-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[lldb] Print a warning on checksum mismatch #107968
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
[lldb] Print a warning on checksum mismatch #107968
Conversation
Print a warning when the debugger detects a mismatch between the MD5 checksum in the DWARF 5 line table and the file on disk. The warning is printed only once per file.
@llvm/pr-subscribers-lldb Author: Jonas Devlieghere (JDevlieghere) ChangesPrint a warning when the debugger detects a mismatch between the MD5 checksum in the DWARF 5 line table and the file on disk. The warning is printed only once per file. Full diff: https://github.com/llvm/llvm-project/pull/107968.diff 4 Files Affected:
diff --git a/lldb/include/lldb/Core/SourceManager.h b/lldb/include/lldb/Core/SourceManager.h
index 172824dc78a6bc..e38627182a9690 100644
--- a/lldb/include/lldb/Core/SourceManager.h
+++ b/lldb/include/lldb/Core/SourceManager.h
@@ -74,6 +74,10 @@ class SourceManager {
const Checksum &GetChecksum() const { return m_checksum; }
+ llvm::once_flag &GetChecksumWarningOnceFlag() {
+ return m_checksum_warning_once_flag;
+ }
+
protected:
/// Set file and update modification time.
void SetSupportFile(lldb::SupportFileSP support_file_sp);
@@ -87,6 +91,9 @@ class SourceManager {
/// Keep track of the on-disk checksum.
Checksum m_checksum;
+ /// Once flag for emitting a checksum mismatch warning.
+ llvm::once_flag m_checksum_warning_once_flag;
+
// Keep the modification time that this file data is valid for
llvm::sys::TimePoint<> m_mod_time;
diff --git a/lldb/source/Core/SourceManager.cpp b/lldb/source/Core/SourceManager.cpp
index f97d86ad79f6ab..fd5b49946c6a92 100644
--- a/lldb/source/Core/SourceManager.cpp
+++ b/lldb/source/Core/SourceManager.cpp
@@ -61,6 +61,12 @@ static void resolve_tilde(FileSpec &file_spec) {
}
}
+static std::string toString(const Checksum &checksum) {
+ if (!checksum)
+ return "";
+ return std::string(llvm::formatv("{0}", checksum.digest()));
+}
+
// SourceManager constructor
SourceManager::SourceManager(const TargetSP &target_sp)
: m_last_support_file_sp(std::make_shared<SupportFile>()), m_last_line(0),
@@ -302,6 +308,18 @@ size_t SourceManager::DisplaySourceLinesWithLineNumbersUsingLastFile(
break;
}
}
+
+ Checksum line_table_checksum =
+ last_file_sp->GetSupportFile()->GetChecksum();
+ Checksum on_disk_checksum = last_file_sp->GetChecksum();
+ if (line_table_checksum && line_table_checksum != on_disk_checksum)
+ Debugger::ReportWarning(
+ llvm::formatv(
+ "{0}: source file checksum mismatch between line table "
+ "({1}) and file on disk ({2})",
+ last_file_sp->GetSupportFile()->GetSpecOnly().GetFilename(),
+ toString(line_table_checksum), toString(on_disk_checksum)),
+ std::nullopt, &last_file_sp->GetChecksumWarningOnceFlag());
}
return *delta;
}
@@ -837,12 +855,6 @@ SourceManager::FileSP SourceManager::SourceFileCache::FindSourceFile(
return {};
}
-static std::string toString(const Checksum &checksum) {
- if (!checksum)
- return "";
- return std::string(llvm::formatv("{0}", checksum.digest()));
-}
-
void SourceManager::SourceFileCache::Dump(Stream &stream) const {
// clang-format off
stream << "Modification time MD5 Checksum (on-disk) MD5 Checksum (line table) Lines Path\n";
diff --git a/lldb/test/Shell/SymbolFile/Inputs/main.c b/lldb/test/Shell/SymbolFile/Inputs/main.c
new file mode 100644
index 00000000000000..341417f970d7fe
--- /dev/null
+++ b/lldb/test/Shell/SymbolFile/Inputs/main.c
@@ -0,0 +1,4 @@
+int main(int argc, char **argv) {
+ // Break on main.
+ return 1;
+}
diff --git a/lldb/test/Shell/SymbolFile/checksum-mismatch.test b/lldb/test/Shell/SymbolFile/checksum-mismatch.test
new file mode 100644
index 00000000000000..5db97647c9aa02
--- /dev/null
+++ b/lldb/test/Shell/SymbolFile/checksum-mismatch.test
@@ -0,0 +1,7 @@
+RUN: mkdir -p %t
+RUN: cp %S/Inputs/main.c %t/main.c
+RUN: %clang_host %t/main.c -std=c99 -gdwarf-5 -o %t/main.out
+RUN: echo "// Modify source file hash" >> %t/main.c
+RUN: %lldb -b %t/main.out -o 'b main' -o 'r' 2>&1 | FileCheck %s
+
+CHECK: warning: main.c: source file checksum mismatch between line table ({{.*}}) and file on disk ({{.*}})
|
@@ -74,6 +74,10 @@ class SourceManager { | |||
|
|||
const Checksum &GetChecksum() const { return m_checksum; } | |||
|
|||
llvm::once_flag &GetChecksumWarningOnceFlag() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This getter seems rather pointless, isn't the only user in SourceManager itself?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but this isn't SourceManager.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This broke building in mingw configurations, and possibly a few others as well. The LLDB seems to be using a mixture of |
If there are no suggestions on a way to go here, I'll push a fix within a couple hours, that fixes compilation - probably switching the newly added code to |
I pushed a fix in a81a4b2. |
Print a warning when the debugger detects a mismatch between the MD5 checksum in the DWARF 5 line table and the file on disk. The warning is printed only once per file.