Skip to content

More aggressively deduplicate global warnings based on contents. #112801

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions lldb/include/lldb/Core/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/ADT/StableHashing.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Chrono.h"

Expand Down Expand Up @@ -1057,8 +1058,11 @@ class Module : public std::enable_shared_from_this<Module>,
/// time for the symbol tables can be aggregated here.
StatsDuration m_symtab_index_time;

std::once_flag m_optimization_warning;
std::once_flag m_language_warning;
/// A set of hashes of all warnings and errors, to avoid reporting them
/// multiple times to the same Debugger.
llvm::DenseMap<llvm::stable_hash, std::unique_ptr<std::once_flag>>
m_shown_diagnostics;
std::recursive_mutex m_diagnostic_mutex;

void SymbolIndicesToSymbolContextList(Symtab *symtab,
std::vector<uint32_t> &symbol_indexes,
Expand Down Expand Up @@ -1086,6 +1090,7 @@ class Module : public std::enable_shared_from_this<Module>,
void ReportWarning(const llvm::formatv_object_base &payload);
void ReportError(const llvm::formatv_object_base &payload);
void ReportErrorIfModifyDetected(const llvm::formatv_object_base &payload);
std::once_flag *GetDiagnosticOnceFlag(llvm::StringRef msg);
};

} // namespace lldb_private
Expand Down
29 changes: 19 additions & 10 deletions lldb/source/Core/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1093,8 +1093,8 @@ void Module::ReportWarningOptimization(
ss << file_name
<< " was compiled with optimization - stepping may behave "
"oddly; variables may not be available.";
Debugger::ReportWarning(std::string(ss.GetString()), debugger_id,
&m_optimization_warning);
llvm::StringRef msg = ss.GetString();
Debugger::ReportWarning(msg.str(), debugger_id, GetDiagnosticOnceFlag(msg));
}

void Module::ReportWarningUnsupportedLanguage(
Expand All @@ -1104,8 +1104,8 @@ void Module::ReportWarningUnsupportedLanguage(
<< Language::GetNameForLanguageType(language)
<< "\". "
"Inspection of frame variables will be limited.";
Debugger::ReportWarning(std::string(ss.GetString()), debugger_id,
&m_language_warning);
llvm::StringRef msg = ss.GetString();
Debugger::ReportWarning(msg.str(), debugger_id, GetDiagnosticOnceFlag(msg));
}

void Module::ReportErrorIfModifyDetected(
Expand All @@ -1125,20 +1125,29 @@ void Module::ReportErrorIfModifyDetected(
}
}

std::once_flag *Module::GetDiagnosticOnceFlag(llvm::StringRef msg) {
std::lock_guard<std::recursive_mutex> guard(m_diagnostic_mutex);
auto &once_ptr = m_shown_diagnostics[llvm::stable_hash_name(msg)];
if (!once_ptr)
once_ptr = std::make_unique<std::once_flag>();
return once_ptr.get();
}

void Module::ReportError(const llvm::formatv_object_base &payload) {
StreamString strm;
GetDescription(strm.AsRawOstream(), lldb::eDescriptionLevelBrief);
strm.PutChar(' ');
strm.PutCString(payload.str());
Debugger::ReportError(strm.GetString().str());
std::string msg = payload.str();
strm << ' ' << msg;
Debugger::ReportError(strm.GetString().str(), {}, GetDiagnosticOnceFlag(msg));
}

void Module::ReportWarning(const llvm::formatv_object_base &payload) {
StreamString strm;
GetDescription(strm.AsRawOstream(), lldb::eDescriptionLevelFull);
strm.PutChar(' ');
strm.PutCString(payload.str());
Debugger::ReportWarning(std::string(strm.GetString()));
std::string msg = payload.str();
strm << ' ' << msg;
Debugger::ReportWarning(strm.GetString().str(), {},
GetDiagnosticOnceFlag(msg));
}

void Module::LogMessage(Log *log, const llvm::formatv_object_base &payload) {
Expand Down
25 changes: 13 additions & 12 deletions lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2069,13 +2069,15 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
Status error = ModuleList::GetSharedModule(dwo_module_spec, module_sp,
nullptr, nullptr, nullptr);
if (!module_sp) {
// ReportWarning also rate-limits based on the warning string,
// but in a -gmodules build, each object file has a similar DAG
// of module dependencies that would all be listed here.
GetObjectFile()->GetModule()->ReportWarning(
"{0:x16}: unable to locate module needed for external types: "
"{1}\nerror: {2}\nDebugging will be degraded due to missing "
"types. Rebuilding the project will regenerate the needed "
"module files.",
die.GetOffset(), dwo_module_spec.GetFileSpec().GetPath().c_str(),
error.AsCString("unknown error"));
"{0}", error.AsCString("unknown error"));
GetObjectFile()->GetModule()->ReportWarning(
"Unable to locate module needed for external types.\n"
"Debugging will be degraded due to missing types. Rebuilding the "
"project will regenerate the needed module files.");
continue;
}

Expand All @@ -2095,12 +2097,11 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {

if (dwo_id != dwo_dwo_id) {
GetObjectFile()->GetModule()->ReportWarning(
"{0:x16}: Module {1} is out-of-date (hash mismatch). Type "
"information "
"from this module may be incomplete or inconsistent with the rest of "
"the program. Rebuilding the project will regenerate the needed "
"module files.",
die.GetOffset(), dwo_module_spec.GetFileSpec().GetPath().c_str());
"Module {0} is out-of-date (hash mismatch).\n"
"Type information from this module may be incomplete or inconsistent "
"with the rest of the program. Rebuilding the project will "
"regenerate the needed module files.",
dwo_module_spec.GetFileSpec().GetPath());
}
}
}
Expand Down
22 changes: 22 additions & 0 deletions lldb/test/Shell/SymbolFile/DWARF/TestDedupWarnings.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# REQUIRES: system-darwin
# Test the rate-limiting of module not found warnings.
# RUN: rm -rf %t
# RUN: mkdir -p %t

# RUN: echo 'module "C" { header "c.h" }' >%t/module.modulemap
# RUN: echo 'struct c {};' >>%t/c.h
# RUN: echo '@import C;' >%t/a.m
# RUN: echo 'struct a { struct c c; } a;' >>%t/a.m
# RUN: echo '@import C;' >%t/b.m
# RUN: echo 'struct b { struct c c; } b;' >>%t/b.m
# RUN: echo 'int main() {}' >>%t/b.m

# RUN: %clang_host -fmodules -Xclang -fmodules-cache-path=%t/cache -I%t -g -gmodules %t/a.m -o %t/a.o -c
# RUN: %clang_host -fmodules -Xclang -fmodules-cache-path=%t/cache -I%t -g -gmodules %t/b.m -o %t/b.o -c
# RUN: %clang_host %t/a.o %t/b.o -o %t/a.out
# RUN: rm -rf %t/cache
# RUN: %lldb %t/a.out -o "b main" -o run -o "p a" -o "p b" -o q 2>&1 | FileCheck %s
# CHECK: {{[ab]}}.o{{.*}}/cache/{{.*}}/C-{{.*}}.pcm' does not exist
# CHECK-NOT: /cache/{{.*}}/C-{.*}.pcm' does not exist
# CHECK: {{[ab]}}.o{{.*}}/cache/{{.*}}/C-{{.*}}.pcm' does not exist
# CHECK-NOT: /cache/{{.*}}/C-{.*}.pcm' does not exist
Loading