Skip to content

Commit ffa2f53

Browse files
authored
[lldb] Print a warning on checksum mismatch (#107968)
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.
1 parent 3786568 commit ffa2f53

File tree

4 files changed

+36
-6
lines changed

4 files changed

+36
-6
lines changed

lldb/include/lldb/Core/SourceManager.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ class SourceManager {
7474

7575
const Checksum &GetChecksum() const { return m_checksum; }
7676

77+
llvm::once_flag &GetChecksumWarningOnceFlag() {
78+
return m_checksum_warning_once_flag;
79+
}
80+
7781
protected:
7882
/// Set file and update modification time.
7983
void SetSupportFile(lldb::SupportFileSP support_file_sp);
@@ -87,6 +91,9 @@ class SourceManager {
8791
/// Keep track of the on-disk checksum.
8892
Checksum m_checksum;
8993

94+
/// Once flag for emitting a checksum mismatch warning.
95+
llvm::once_flag m_checksum_warning_once_flag;
96+
9097
// Keep the modification time that this file data is valid for
9198
llvm::sys::TimePoint<> m_mod_time;
9299

lldb/source/Core/SourceManager.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ static void resolve_tilde(FileSpec &file_spec) {
6161
}
6262
}
6363

64+
static std::string toString(const Checksum &checksum) {
65+
if (!checksum)
66+
return "";
67+
return std::string(llvm::formatv("{0}", checksum.digest()));
68+
}
69+
6470
// SourceManager constructor
6571
SourceManager::SourceManager(const TargetSP &target_sp)
6672
: m_last_support_file_sp(std::make_shared<SupportFile>()), m_last_line(0),
@@ -302,6 +308,18 @@ size_t SourceManager::DisplaySourceLinesWithLineNumbersUsingLastFile(
302308
break;
303309
}
304310
}
311+
312+
Checksum line_table_checksum =
313+
last_file_sp->GetSupportFile()->GetChecksum();
314+
Checksum on_disk_checksum = last_file_sp->GetChecksum();
315+
if (line_table_checksum && line_table_checksum != on_disk_checksum)
316+
Debugger::ReportWarning(
317+
llvm::formatv(
318+
"{0}: source file checksum mismatch between line table "
319+
"({1}) and file on disk ({2})",
320+
last_file_sp->GetSupportFile()->GetSpecOnly().GetFilename(),
321+
toString(line_table_checksum), toString(on_disk_checksum)),
322+
std::nullopt, &last_file_sp->GetChecksumWarningOnceFlag());
305323
}
306324
return *delta;
307325
}
@@ -837,12 +855,6 @@ SourceManager::FileSP SourceManager::SourceFileCache::FindSourceFile(
837855
return {};
838856
}
839857

840-
static std::string toString(const Checksum &checksum) {
841-
if (!checksum)
842-
return "";
843-
return std::string(llvm::formatv("{0}", checksum.digest()));
844-
}
845-
846858
void SourceManager::SourceFileCache::Dump(Stream &stream) const {
847859
// clang-format off
848860
stream << "Modification time MD5 Checksum (on-disk) MD5 Checksum (line table) Lines Path\n";
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
int main(int argc, char **argv) {
2+
// Break on main.
3+
return 1;
4+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
RUN: mkdir -p %t
2+
RUN: cp %S/Inputs/main.c %t/main.c
3+
RUN: %clang_host %t/main.c -std=c99 -gdwarf-5 -o %t/main.out
4+
RUN: echo "// Modify source file hash" >> %t/main.c
5+
RUN: %lldb -b %t/main.out -o 'b main' -o 'r' 2>&1 | FileCheck %s
6+
7+
CHECK: warning: main.c: source file checksum mismatch between line table ({{.*}}) and file on disk ({{.*}})

0 commit comments

Comments
 (0)