diff options
author | Vy Nguyen <vyng@google.com> | 2025-05-19 11:04:01 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-05-19 11:04:01 -0400 |
commit | dc25ab389c2d441ba378d4db56a4a61e3eedb889 (patch) | |
tree | 0ccc3c556e612bce81b95e0c926da25e549605d8 /lldb/source/Commands/CommandObjectSource.cpp | |
parent | 59f8af35b6bb15c0794873786cb34c7867be357b (diff) | |
download | llvm-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.cpp | 39 |
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 { |