aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Commands/CommandObjectSource.cpp
diff options
context:
space:
mode:
authorVy Nguyen <vyng@google.com>2025-05-19 11:04:01 -0400
committerGitHub <noreply@github.com>2025-05-19 11:04:01 -0400
commitdc25ab389c2d441ba378d4db56a4a61e3eedb889 (patch)
tree0ccc3c556e612bce81b95e0c926da25e549605d8 /lldb/source/Commands/CommandObjectSource.cpp
parent59f8af35b6bb15c0794873786cb34c7867be357b (diff)
downloadllvm-dc25ab389c2d441ba378d4db56a4a61e3eedb889.zip
llvm-dc25ab389c2d441ba378d4db56a4a61e3eedb889.tar.gz
llvm-dc25ab389c2d441ba378d4db56a4a61e3eedb889.tar.bz2
[lldb]Make `list` command work with headers when possible. (#139002)
Given this simple test case: ``` // foo.h extern int* ptr; inline void g(int x) { *ptr = x; // should raise a SIGILL } //-------------- // foo.cc #include "foo.h" int* ptr; //-------------- // main.cc #include "foo.h" int main() { g(123); // Call the inlined function and crash return 0; } $ clang -g main.cc foo.cc -o main.out $ lldb main.out ``` When you run `main.out` under lldb, it'd stop inside `void g(int)` because of the crash. The stack trace would show that it had crashed in `foo.h`, but if you do `list foo.h:2`, lldb would complain that it could not find the source file, which is confusing. This patch make `list` work with headers.
Diffstat (limited to 'lldb/source/Commands/CommandObjectSource.cpp')
-rw-r--r--lldb/source/Commands/CommandObjectSource.cpp39
1 files changed, 28 insertions, 11 deletions
diff --git a/lldb/source/Commands/CommandObjectSource.cpp b/lldb/source/Commands/CommandObjectSource.cpp
index 8c87af5..7e7d3f0 100644
--- a/lldb/source/Commands/CommandObjectSource.cpp
+++ b/lldb/source/Commands/CommandObjectSource.cpp
@@ -1108,9 +1108,15 @@ protected:
}
}
} else {
- const char *filename = m_options.file_name.c_str();
-
+ // const char *filename = m_options.file_name.c_str();
+ FileSpec file_spec(m_options.file_name);
bool check_inlines = false;
+ const InlineStrategy inline_strategy = target.GetInlineStrategy();
+ if (inline_strategy == eInlineBreakpointsAlways ||
+ (inline_strategy == eInlineBreakpointsHeaders &&
+ !file_spec.IsSourceImplementationFile()))
+ check_inlines = true;
+
SymbolContextList sc_list;
size_t num_matches = 0;
@@ -1122,17 +1128,20 @@ protected:
ModuleSpec module_spec(module_file_spec);
matching_modules.Clear();
target.GetImages().FindModules(module_spec, matching_modules);
- num_matches += matching_modules.ResolveSymbolContextForFilePath(
- filename, 0, check_inlines,
+ num_matches += matching_modules.ResolveSymbolContextsForFileSpec(
+ file_spec, 1, check_inlines,
SymbolContextItem(eSymbolContextModule |
- eSymbolContextCompUnit),
+ eSymbolContextCompUnit |
+ eSymbolContextLineEntry),
sc_list);
}
}
} else {
- num_matches = target.GetImages().ResolveSymbolContextForFilePath(
- filename, 0, check_inlines,
- eSymbolContextModule | eSymbolContextCompUnit, sc_list);
+ num_matches = target.GetImages().ResolveSymbolContextsForFileSpec(
+ file_spec, 1, check_inlines,
+ eSymbolContextModule | eSymbolContextCompUnit |
+ eSymbolContextLineEntry,
+ sc_list);
}
if (num_matches == 0) {
@@ -1179,10 +1188,18 @@ protected:
if (m_options.num_lines == 0)
m_options.num_lines = 10;
const uint32_t column = 0;
+
+ // Headers aren't always in the DWARF but if they have
+ // executable code (eg., inlined-functions) then the callsite's
+ // file(s) will be found and assigned to
+ // sc.comp_unit->GetPrimarySupportFile, which is NOT what we want to
+ // print. Instead, we want to print the one from the line entry.
+ lldb::SupportFileSP found_file_sp = sc.line_entry.file_sp;
+
target.GetSourceManager().DisplaySourceLinesWithLineNumbers(
- sc.comp_unit->GetPrimarySupportFile(),
- m_options.start_line, column, 0, m_options.num_lines, "",
- &result.GetOutputStream(), GetBreakpointLocations());
+ found_file_sp, m_options.start_line, column, 0,
+ m_options.num_lines, "", &result.GetOutputStream(),
+ GetBreakpointLocations());
result.SetStatus(eReturnStatusSuccessFinishResult);
} else {