Skip to content

Commit 5746e99

Browse files
committed
[lldb]Make list command work with headers when possible.
1 parent 39beeb8 commit 5746e99

File tree

3 files changed

+94
-3
lines changed

3 files changed

+94
-3
lines changed

lldb/source/Commands/CommandObjectSource.cpp

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,6 +1104,7 @@ class CommandObjectSourceList : public CommandObjectParsed {
11041104
bool check_inlines = false;
11051105
SymbolContextList sc_list;
11061106
size_t num_matches = 0;
1107+
uint32_t start_line = m_options.start_line;
11071108

11081109
if (!m_options.modules.empty()) {
11091110
ModuleList matching_modules;
@@ -1114,15 +1115,15 @@ class CommandObjectSourceList : public CommandObjectParsed {
11141115
matching_modules.Clear();
11151116
target.GetImages().FindModules(module_spec, matching_modules);
11161117
num_matches += matching_modules.ResolveSymbolContextForFilePath(
1117-
filename, 0, check_inlines,
1118+
filename, start_line, check_inlines,
11181119
SymbolContextItem(eSymbolContextModule |
11191120
eSymbolContextCompUnit),
11201121
sc_list);
11211122
}
11221123
}
11231124
} else {
11241125
num_matches = target.GetImages().ResolveSymbolContextForFilePath(
1125-
filename, 0, check_inlines,
1126+
filename, start_line, check_inlines,
11261127
eSymbolContextModule | eSymbolContextCompUnit, sc_list);
11271128
}
11281129

@@ -1170,8 +1171,37 @@ class CommandObjectSourceList : public CommandObjectParsed {
11701171
if (m_options.num_lines == 0)
11711172
m_options.num_lines = 10;
11721173
const uint32_t column = 0;
1174+
1175+
// Headers aren't always in the DWARF but if they have
1176+
// executable code (eg., inlined-functions) then the callsite's file(s)
1177+
// will be found.
1178+
// So if a header was requested and we got a primary file, then look
1179+
// thru its support file(s) for the header.
1180+
lldb::SupportFileSP actual_file_sp =
1181+
sc.comp_unit->GetPrimarySupportFile();
1182+
if (llvm::StringRef(m_options.file_name).ends_with(".h")) {
1183+
int support_matches_count = 0;
1184+
for (auto &file : sc.comp_unit->GetSupportFiles()) {
1185+
if (llvm::StringRef(file->GetSpecOnly().GetPath()).ends_with(filename)) {
1186+
actual_file_sp = file;
1187+
++support_matches_count;
1188+
}
1189+
}
1190+
if (support_matches_count == 0) {
1191+
result.AppendErrorWithFormat(
1192+
"No file found for requested header: \"%s.\"\n",
1193+
m_options.file_name.c_str());
1194+
return;
1195+
} else if (support_matches_count > 1) {
1196+
result.AppendErrorWithFormat(
1197+
"Multiple files found for requested header: \"%s.\"\n",
1198+
m_options.file_name.c_str());
1199+
return;
1200+
}
1201+
}
1202+
11731203
target.GetSourceManager().DisplaySourceLinesWithLineNumbers(
1174-
sc.comp_unit->GetPrimarySupportFile(),
1204+
actual_file_sp,
11751205
m_options.start_line, column, 0, m_options.num_lines, "",
11761206
&result.GetOutputStream(), GetBreakpointLocations());
11771207

lldb/source/Core/ModuleList.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,8 @@ uint32_t ModuleList::ResolveSymbolContextsForFileSpec(
714714
const FileSpec &file_spec, uint32_t line, bool check_inlines,
715715
SymbolContextItem resolve_scope, SymbolContextList &sc_list) const {
716716
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
717+
// If we're looking for a header (not source), then need to check inline.
718+
check_inlines = check_inlines || !file_spec.IsSourceImplementationFile();
717719
for (const ModuleSP &module_sp : m_modules) {
718720
module_sp->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
719721
resolve_scope, sc_list);
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
## Test that `list header.h:<line>` works correctly when header is available.
2+
##
3+
# REQUIRES: x86
4+
# RUN: split-file %s %t
5+
6+
# RUN: %clang_host -g %t/main_with_inlined.cc %t/foo.cc -o %t/main_with_inlined.out
7+
# RUN: %clang_host -g %t/main_no_inlined.cc %t/foo.cc -o %t/main_no_inlined.out
8+
9+
# RUN: %lldb %t/main_with_inlined.out -o "list foo.h:2" -o "exit" 2>&1 \
10+
# RUN: | FileCheck %s --check-prefix=CHECK-INLINED
11+
12+
## Would be nice if this listed the header too - but probably not something
13+
## we want to support right now.
14+
# RUN: echo quit | %lldb %t/main_no_inlined.out -o "list foo.h:2" -o "exit" 2>&1 \
15+
# RUN: | FileCheck %s --check-prefix=CHECK-NO-INLINED
16+
17+
# CHECK-INLINED: 2 extern int* ptr;
18+
# CHECK-INLINED: 3 void f(int x);
19+
# CHECK-INLINED: 4
20+
# CHECK-INLINED: 5 inline void g(int x) {
21+
# CHECK-INLINED: 6 *ptr = x; // should raise a SIGILL
22+
# CHECK-INLINED: 7 }
23+
24+
# CHECK-NO-INLINED: error: Could not find source file "foo.h".
25+
26+
#--- foo.h
27+
// foo.h
28+
extern int* ptr;
29+
void f(int x);
30+
31+
inline void g(int x) {
32+
*ptr = x; // should raise a SIGILL
33+
}
34+
35+
#--- foo.cc
36+
#include "foo.h"
37+
38+
int* ptr;
39+
40+
void f(int x) {
41+
*ptr = x;
42+
}
43+
44+
#--- main_with_inlined.cc
45+
#include "foo.h"
46+
47+
int main() {
48+
f(234);
49+
g(123); // Call the inlined function
50+
return 0;
51+
}
52+
53+
#--- main_no_inlined.cc
54+
#include "foo.h"
55+
56+
int main() {
57+
f(234);
58+
return 0;
59+
}

0 commit comments

Comments
 (0)