aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Labath <pavel@labath.sk>2024-11-13 09:56:00 +0100
committerGitHub <noreply@github.com>2024-11-13 09:56:00 +0100
commit39b2979a434e70a4ce76d4adf91572dcfc9662ff (patch)
treef46f999c984e0bea1e21bb2c1a77ba22573a7944
parent12dcaa2e1e6c46d8a1b440d8a836d6b81ab92efb (diff)
downloadllvm-39b2979a434e70a4ce76d4adf91572dcfc9662ff.zip
llvm-39b2979a434e70a4ce76d4adf91572dcfc9662ff.tar.gz
llvm-39b2979a434e70a4ce76d4adf91572dcfc9662ff.tar.bz2
[lldb] Fix source display for artificial locations (#115876)
When retrieving the location of the function declaration, we were dropping the file component on the floor, which resulted in an amusingly confusing situation were we displayed the file containing the implementation of the function, but used the line number of the declaration. This patch fixes that. It required a small refactor Function::GetStartLineSourceLineInfo to return a SupportFile (instead of just the file spec), which in turn necessitated changes in a couple of other places as well.
-rw-r--r--lldb/include/lldb/Symbol/Function.h3
-rw-r--r--lldb/source/Breakpoint/BreakpointResolverFileLine.cpp13
-rw-r--r--lldb/source/Commands/CommandObjectSource.cpp4
-rw-r--r--lldb/source/Core/Disassembler.cpp30
-rw-r--r--lldb/source/Symbol/Function.cpp9
-rw-r--r--lldb/source/Target/StackFrame.cpp6
-rw-r--r--lldb/test/API/source-manager/TestSourceManager.py19
-rw-r--r--lldb/test/API/source-manager/artificial_location.c6
-rw-r--r--lldb/test/API/source-manager/artificial_location.cpp8
-rw-r--r--lldb/test/API/source-manager/artificial_location.h3
10 files changed, 63 insertions, 38 deletions
diff --git a/lldb/include/lldb/Symbol/Function.h b/lldb/include/lldb/Symbol/Function.h
index bbfc25f..70f51a8 100644
--- a/lldb/include/lldb/Symbol/Function.h
+++ b/lldb/include/lldb/Symbol/Function.h
@@ -457,7 +457,8 @@ public:
///
/// \param[out] line_no
/// The line number.
- void GetStartLineSourceInfo(FileSpec &source_file, uint32_t &line_no);
+ void GetStartLineSourceInfo(lldb::SupportFileSP &source_file_sp,
+ uint32_t &line_no);
/// Find the file and line number of the source location of the end of the
/// function.
diff --git a/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp b/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp
index 8e7386d..a94e9e2 100644
--- a/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp
+++ b/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp
@@ -139,21 +139,23 @@ void BreakpointResolverFileLine::FilterContexts(SymbolContextList &sc_list) {
if (!sc.block)
continue;
- FileSpec file;
+ SupportFileSP file_sp;
uint32_t line;
const Block *inline_block = sc.block->GetContainingInlinedBlock();
if (inline_block) {
const Declaration &inline_declaration = inline_block->GetInlinedFunctionInfo()->GetDeclaration();
if (!inline_declaration.IsValid())
continue;
- file = inline_declaration.GetFile();
+ file_sp = std::make_shared<SupportFile>(inline_declaration.GetFile());
line = inline_declaration.GetLine();
} else if (sc.function)
- sc.function->GetStartLineSourceInfo(file, line);
+ sc.function->GetStartLineSourceInfo(file_sp, line);
else
continue;
- if (file != sc.line_entry.GetFile()) {
+ if (!file_sp ||
+ !file_sp->Equal(*sc.line_entry.file_sp,
+ SupportFile::eEqualFileSpecAndChecksumIfSet)) {
LLDB_LOG(log, "unexpected symbol context file {0}",
sc.line_entry.GetFile());
continue;
@@ -190,7 +192,8 @@ void BreakpointResolverFileLine::FilterContexts(SymbolContextList &sc_list) {
const int decl_line_is_too_late_fudge = 1;
if (line &&
m_location_spec.GetLine() < line - decl_line_is_too_late_fudge) {
- LLDB_LOG(log, "removing symbol context at {0}:{1}", file, line);
+ LLDB_LOG(log, "removing symbol context at {0}:{1}",
+ file_sp->GetSpecOnly(), line);
sc_list.RemoveContextAtIndex(i);
--i;
}
diff --git a/lldb/source/Commands/CommandObjectSource.cpp b/lldb/source/Commands/CommandObjectSource.cpp
index 86c090f..c8295fd 100644
--- a/lldb/source/Commands/CommandObjectSource.cpp
+++ b/lldb/source/Commands/CommandObjectSource.cpp
@@ -784,9 +784,7 @@ protected:
if (sc.block == nullptr) {
// Not an inlined function
- FileSpec function_file_spec;
- sc.function->GetStartLineSourceInfo(function_file_spec, start_line);
- start_file = std::make_shared<SupportFile>(function_file_spec);
+ sc.function->GetStartLineSourceInfo(start_file, start_line);
if (start_line == 0) {
result.AppendErrorWithFormat("Could not find line information for "
"start of function: \"%s\".\n",
diff --git a/lldb/source/Core/Disassembler.cpp b/lldb/source/Core/Disassembler.cpp
index 522a3ef..68e5214 100644
--- a/lldb/source/Core/Disassembler.cpp
+++ b/lldb/source/Core/Disassembler.cpp
@@ -205,16 +205,20 @@ Disassembler::GetFunctionDeclLineEntry(const SymbolContext &sc) {
return {};
LineEntry prologue_end_line = sc.line_entry;
- FileSpec func_decl_file;
+ SupportFileSP func_decl_file_sp;
uint32_t func_decl_line;
- sc.function->GetStartLineSourceInfo(func_decl_file, func_decl_line);
+ sc.function->GetStartLineSourceInfo(func_decl_file_sp, func_decl_line);
- if (func_decl_file != prologue_end_line.GetFile() &&
- func_decl_file != prologue_end_line.original_file_sp->GetSpecOnly())
+ if (!func_decl_file_sp)
+ return {};
+ if (!func_decl_file_sp->Equal(*prologue_end_line.file_sp,
+ SupportFile::eEqualFileSpecAndChecksumIfSet) &&
+ !func_decl_file_sp->Equal(*prologue_end_line.original_file_sp,
+ SupportFile::eEqualFileSpecAndChecksumIfSet))
return {};
SourceLine decl_line;
- decl_line.file = func_decl_file;
+ decl_line.file = func_decl_file_sp->GetSpecOnly();
decl_line.line = func_decl_line;
// TODO: Do we care about column on these entries? If so, we need to plumb
// that through GetStartLineSourceInfo.
@@ -410,20 +414,24 @@ void Disassembler::PrintInstructions(Debugger &debugger, const ArchSpec &arch,
LineEntry prologue_end_line = sc.line_entry;
if (!ElideMixedSourceAndDisassemblyLine(exe_ctx, sc,
prologue_end_line)) {
- FileSpec func_decl_file;
+ SupportFileSP func_decl_file_sp;
uint32_t func_decl_line;
- sc.function->GetStartLineSourceInfo(func_decl_file,
+ sc.function->GetStartLineSourceInfo(func_decl_file_sp,
func_decl_line);
- if (func_decl_file == prologue_end_line.GetFile() ||
- func_decl_file ==
- prologue_end_line.original_file_sp->GetSpecOnly()) {
+ if (func_decl_file_sp &&
+ (func_decl_file_sp->Equal(
+ *prologue_end_line.file_sp,
+ SupportFile::eEqualFileSpecAndChecksumIfSet) ||
+ func_decl_file_sp->Equal(
+ *prologue_end_line.original_file_sp,
+ SupportFile::eEqualFileSpecAndChecksumIfSet))) {
// Add all the lines between the function declaration and
// the first non-prologue source line to the list of lines
// to print.
for (uint32_t lineno = func_decl_line;
lineno <= prologue_end_line.line; lineno++) {
SourceLine this_line;
- this_line.file = func_decl_file;
+ this_line.file = func_decl_file_sp->GetSpecOnly();
this_line.line = lineno;
source_lines_to_display.lines.push_back(this_line);
}
diff --git a/lldb/source/Symbol/Function.cpp b/lldb/source/Symbol/Function.cpp
index f590cf4..0186d63 100644
--- a/lldb/source/Symbol/Function.cpp
+++ b/lldb/source/Symbol/Function.cpp
@@ -287,10 +287,10 @@ Function::Function(CompileUnit *comp_unit, lldb::user_id_t func_uid,
Function::~Function() = default;
-void Function::GetStartLineSourceInfo(FileSpec &source_file,
+void Function::GetStartLineSourceInfo(SupportFileSP &source_file_sp,
uint32_t &line_no) {
line_no = 0;
- source_file.Clear();
+ source_file_sp.reset();
if (m_comp_unit == nullptr)
return;
@@ -299,7 +299,8 @@ void Function::GetStartLineSourceInfo(FileSpec &source_file,
GetType();
if (m_type != nullptr && m_type->GetDeclaration().GetLine() != 0) {
- source_file = m_type->GetDeclaration().GetFile();
+ source_file_sp =
+ std::make_shared<SupportFile>(m_type->GetDeclaration().GetFile());
line_no = m_type->GetDeclaration().GetLine();
} else {
LineTable *line_table = m_comp_unit->GetLineTable();
@@ -310,7 +311,7 @@ void Function::GetStartLineSourceInfo(FileSpec &source_file,
if (line_table->FindLineEntryByAddress(GetAddressRange().GetBaseAddress(),
line_entry, nullptr)) {
line_no = line_entry.line;
- source_file = line_entry.GetFile();
+ source_file_sp = line_entry.file_sp;
}
}
}
diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp
index ef71fc6..dbb3127 100644
--- a/lldb/source/Target/StackFrame.cpp
+++ b/lldb/source/Target/StackFrame.cpp
@@ -1918,15 +1918,15 @@ bool StackFrame::GetStatus(Stream &strm, bool show_frame_info, bool show_source,
if (m_sc.comp_unit && m_sc.line_entry.IsValid()) {
have_debuginfo = true;
if (source_lines_before > 0 || source_lines_after > 0) {
+ SupportFileSP source_file_sp = m_sc.line_entry.file_sp;
uint32_t start_line = m_sc.line_entry.line;
if (!start_line && m_sc.function) {
- FileSpec source_file;
- m_sc.function->GetStartLineSourceInfo(source_file, start_line);
+ m_sc.function->GetStartLineSourceInfo(source_file_sp, start_line);
}
size_t num_lines =
target->GetSourceManager().DisplaySourceLinesWithLineNumbers(
- m_sc.line_entry.file_sp, start_line, m_sc.line_entry.column,
+ source_file_sp, start_line, m_sc.line_entry.column,
source_lines_before, source_lines_after, "->", &strm);
if (num_lines != 0)
have_source = true;
diff --git a/lldb/test/API/source-manager/TestSourceManager.py b/lldb/test/API/source-manager/TestSourceManager.py
index ad7c85a..7071f09 100644
--- a/lldb/test/API/source-manager/TestSourceManager.py
+++ b/lldb/test/API/source-manager/TestSourceManager.py
@@ -314,19 +314,28 @@ class SourceManagerTestCase(TestBase):
)
def test_artificial_source_location(self):
- src_file = "artificial_location.c"
- d = {"C_SOURCES": src_file}
+ src_file = "artificial_location.cpp"
+ d = {"C_SOURCES": "", "CXX_SOURCES": src_file}
self.build(dictionary=d)
- lldbutil.run_to_source_breakpoint(
- self, "main", lldb.SBFileSpec(src_file, False)
- )
+ target = lldbutil.run_to_breakpoint_make_target(self)
+
+ # Find the instruction with line=0 and put a breakpoint there.
+ sc_list = target.FindFunctions("A::foo")
+ self.assertEqual(len(sc_list), 1)
+ insns = sc_list[0].function.GetInstructions(target)
+ insn0 = next(filter(lambda insn: insn.addr.line_entry.line == 0, insns))
+ bkpt = target.BreakpointCreateBySBAddress(insn0.addr)
+ self.assertGreater(bkpt.GetNumLocations(), 0)
+
+ lldbutil.run_to_breakpoint_do_run(self, target, bkpt)
self.expect(
"process status",
substrs=[
"stop reason = breakpoint",
f"{src_file}:0",
+ "static int foo();",
"Note: this address is compiler-generated code in function",
"that has no source code associated with it.",
],
diff --git a/lldb/test/API/source-manager/artificial_location.c b/lldb/test/API/source-manager/artificial_location.c
deleted file mode 100644
index e1edd8d..0000000
--- a/lldb/test/API/source-manager/artificial_location.c
+++ /dev/null
@@ -1,6 +0,0 @@
-int foo() { return 42; }
-
-int main() {
-#line 0
- return foo();
-}
diff --git a/lldb/test/API/source-manager/artificial_location.cpp b/lldb/test/API/source-manager/artificial_location.cpp
new file mode 100644
index 0000000..776f68a
--- /dev/null
+++ b/lldb/test/API/source-manager/artificial_location.cpp
@@ -0,0 +1,8 @@
+#include "artificial_location.h"
+
+int A::foo() {
+#line 0
+ return 42;
+}
+
+int main() { return A::foo(); }
diff --git a/lldb/test/API/source-manager/artificial_location.h b/lldb/test/API/source-manager/artificial_location.h
new file mode 100644
index 0000000..1e40359
--- /dev/null
+++ b/lldb/test/API/source-manager/artificial_location.h
@@ -0,0 +1,3 @@
+struct A {
+ static int foo();
+};