[Lldb-commits] [lldb] [lldb]Make `list` command work with headers when possible. (PR #139002)
Vy Nguyen via lldb-commits
lldb-commits at lists.llvm.org
Thu May 8 10:30:44 PDT 2025
https://github.com/oontvoo updated https://github.com/llvm/llvm-project/pull/139002
>From 5746e997eea55c05cbbb63ad6f78ca225c9ac855 Mon Sep 17 00:00:00 2001
From: Vy Nguyen <vyng at google.com>
Date: Wed, 7 May 2025 21:37:31 -0400
Subject: [PATCH 1/4] [lldb]Make `list` command work with headers when
possible.
---
lldb/source/Commands/CommandObjectSource.cpp | 36 +++++++++++-
lldb/source/Core/ModuleList.cpp | 2 +
lldb/test/Shell/Commands/list-header.test | 59 ++++++++++++++++++++
3 files changed, 94 insertions(+), 3 deletions(-)
create mode 100644 lldb/test/Shell/Commands/list-header.test
diff --git a/lldb/source/Commands/CommandObjectSource.cpp b/lldb/source/Commands/CommandObjectSource.cpp
index c205813565d52..475317021255c 100644
--- a/lldb/source/Commands/CommandObjectSource.cpp
+++ b/lldb/source/Commands/CommandObjectSource.cpp
@@ -1104,6 +1104,7 @@ class CommandObjectSourceList : public CommandObjectParsed {
bool check_inlines = false;
SymbolContextList sc_list;
size_t num_matches = 0;
+ uint32_t start_line = m_options.start_line;
if (!m_options.modules.empty()) {
ModuleList matching_modules;
@@ -1114,7 +1115,7 @@ class CommandObjectSourceList : public CommandObjectParsed {
matching_modules.Clear();
target.GetImages().FindModules(module_spec, matching_modules);
num_matches += matching_modules.ResolveSymbolContextForFilePath(
- filename, 0, check_inlines,
+ filename, start_line, check_inlines,
SymbolContextItem(eSymbolContextModule |
eSymbolContextCompUnit),
sc_list);
@@ -1122,7 +1123,7 @@ class CommandObjectSourceList : public CommandObjectParsed {
}
} else {
num_matches = target.GetImages().ResolveSymbolContextForFilePath(
- filename, 0, check_inlines,
+ filename, start_line, check_inlines,
eSymbolContextModule | eSymbolContextCompUnit, sc_list);
}
@@ -1170,8 +1171,37 @@ class CommandObjectSourceList : public CommandObjectParsed {
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.
+ // So if a header was requested and we got a primary file, then look
+ // thru its support file(s) for the header.
+ lldb::SupportFileSP actual_file_sp =
+ sc.comp_unit->GetPrimarySupportFile();
+ if (llvm::StringRef(m_options.file_name).ends_with(".h")) {
+ int support_matches_count = 0;
+ for (auto &file : sc.comp_unit->GetSupportFiles()) {
+ if (llvm::StringRef(file->GetSpecOnly().GetPath()).ends_with(filename)) {
+ actual_file_sp = file;
+ ++support_matches_count;
+ }
+ }
+ if (support_matches_count == 0) {
+ result.AppendErrorWithFormat(
+ "No file found for requested header: \"%s.\"\n",
+ m_options.file_name.c_str());
+ return;
+ } else if (support_matches_count > 1) {
+ result.AppendErrorWithFormat(
+ "Multiple files found for requested header: \"%s.\"\n",
+ m_options.file_name.c_str());
+ return;
+ }
+ }
+
target.GetSourceManager().DisplaySourceLinesWithLineNumbers(
- sc.comp_unit->GetPrimarySupportFile(),
+ actual_file_sp,
m_options.start_line, column, 0, m_options.num_lines, "",
&result.GetOutputStream(), GetBreakpointLocations());
diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp
index d5ddf6e846112..90c6a62727734 100644
--- a/lldb/source/Core/ModuleList.cpp
+++ b/lldb/source/Core/ModuleList.cpp
@@ -714,6 +714,8 @@ uint32_t ModuleList::ResolveSymbolContextsForFileSpec(
const FileSpec &file_spec, uint32_t line, bool check_inlines,
SymbolContextItem resolve_scope, SymbolContextList &sc_list) const {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
+ // If we're looking for a header (not source), then need to check inline.
+ check_inlines = check_inlines || !file_spec.IsSourceImplementationFile();
for (const ModuleSP &module_sp : m_modules) {
module_sp->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
resolve_scope, sc_list);
diff --git a/lldb/test/Shell/Commands/list-header.test b/lldb/test/Shell/Commands/list-header.test
new file mode 100644
index 0000000000000..ca700cd2b2fb1
--- /dev/null
+++ b/lldb/test/Shell/Commands/list-header.test
@@ -0,0 +1,59 @@
+## Test that `list header.h:<line>` works correctly when header is available.
+##
+# REQUIRES: x86
+# RUN: split-file %s %t
+
+# RUN: %clang_host -g %t/main_with_inlined.cc %t/foo.cc -o %t/main_with_inlined.out
+# RUN: %clang_host -g %t/main_no_inlined.cc %t/foo.cc -o %t/main_no_inlined.out
+
+# RUN: %lldb %t/main_with_inlined.out -o "list foo.h:2" -o "exit" 2>&1 \
+# RUN: | FileCheck %s --check-prefix=CHECK-INLINED
+
+## Would be nice if this listed the header too - but probably not something
+## we want to support right now.
+# RUN: echo quit | %lldb %t/main_no_inlined.out -o "list foo.h:2" -o "exit" 2>&1 \
+# RUN: | FileCheck %s --check-prefix=CHECK-NO-INLINED
+
+# CHECK-INLINED: 2 extern int* ptr;
+# CHECK-INLINED: 3 void f(int x);
+# CHECK-INLINED: 4
+# CHECK-INLINED: 5 inline void g(int x) {
+# CHECK-INLINED: 6 *ptr = x; // should raise a SIGILL
+# CHECK-INLINED: 7 }
+
+# CHECK-NO-INLINED: error: Could not find source file "foo.h".
+
+#--- foo.h
+// foo.h
+extern int* ptr;
+void f(int x);
+
+inline void g(int x) {
+ *ptr = x; // should raise a SIGILL
+}
+
+#--- foo.cc
+#include "foo.h"
+
+int* ptr;
+
+void f(int x) {
+ *ptr = x;
+}
+
+#--- main_with_inlined.cc
+#include "foo.h"
+
+int main() {
+ f(234);
+ g(123); // Call the inlined function
+ return 0;
+}
+
+#--- main_no_inlined.cc
+#include "foo.h"
+
+int main() {
+ f(234);
+ return 0;
+}
>From b0af06e7ea2f408691c25aab25dc3951f3ddd403 Mon Sep 17 00:00:00 2001
From: Vy Nguyen <vyng at google.com>
Date: Wed, 7 May 2025 21:42:26 -0400
Subject: [PATCH 2/4] formatting
---
lldb/source/Commands/CommandObjectSource.cpp | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/lldb/source/Commands/CommandObjectSource.cpp b/lldb/source/Commands/CommandObjectSource.cpp
index 475317021255c..4b0e47f4cc83f 100644
--- a/lldb/source/Commands/CommandObjectSource.cpp
+++ b/lldb/source/Commands/CommandObjectSource.cpp
@@ -1173,16 +1173,16 @@ class CommandObjectSourceList : public CommandObjectParsed {
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.
- // So if a header was requested and we got a primary file, then look
- // thru its support file(s) for the header.
+ // executable code (eg., inlined-functions) then the callsite's
+ // file(s) will be found. So if a header was requested and we got a
+ // primary file, then look thru its support file(s) for the header.
lldb::SupportFileSP actual_file_sp =
sc.comp_unit->GetPrimarySupportFile();
if (llvm::StringRef(m_options.file_name).ends_with(".h")) {
int support_matches_count = 0;
for (auto &file : sc.comp_unit->GetSupportFiles()) {
- if (llvm::StringRef(file->GetSpecOnly().GetPath()).ends_with(filename)) {
+ if (llvm::StringRef(file->GetSpecOnly().GetPath())
+ .ends_with(filename)) {
actual_file_sp = file;
++support_matches_count;
}
@@ -1201,9 +1201,9 @@ class CommandObjectSourceList : public CommandObjectParsed {
}
target.GetSourceManager().DisplaySourceLinesWithLineNumbers(
- actual_file_sp,
- m_options.start_line, column, 0, m_options.num_lines, "",
- &result.GetOutputStream(), GetBreakpointLocations());
+ actual_file_sp, m_options.start_line, column, 0,
+ m_options.num_lines, "", &result.GetOutputStream(),
+ GetBreakpointLocations());
result.SetStatus(eReturnStatusSuccessFinishResult);
} else {
>From 0e823400669138776ed55f441ca8cb03e262f6e3 Mon Sep 17 00:00:00 2001
From: Vy Nguyen <vyng at google.com>
Date: Thu, 8 May 2025 10:10:58 -0400
Subject: [PATCH 3/4] update test
---
lldb/test/Shell/Commands/list-header.test | 1 -
1 file changed, 1 deletion(-)
diff --git a/lldb/test/Shell/Commands/list-header.test b/lldb/test/Shell/Commands/list-header.test
index ca700cd2b2fb1..204b704ebe2a2 100644
--- a/lldb/test/Shell/Commands/list-header.test
+++ b/lldb/test/Shell/Commands/list-header.test
@@ -45,7 +45,6 @@ void f(int x) {
#include "foo.h"
int main() {
- f(234);
g(123); // Call the inlined function
return 0;
}
>From 692a387f56715e99fe33f6b5a840b2fa9f92d8c7 Mon Sep 17 00:00:00 2001
From: Vy Nguyen <vyng at google.com>
Date: Thu, 8 May 2025 13:30:31 -0400
Subject: [PATCH 4/4] rework the logic to be more general
---
lldb/source/Commands/CommandObjectSource.cpp | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/lldb/source/Commands/CommandObjectSource.cpp b/lldb/source/Commands/CommandObjectSource.cpp
index 4b0e47f4cc83f..c4c46bb33d0fc 100644
--- a/lldb/source/Commands/CommandObjectSource.cpp
+++ b/lldb/source/Commands/CommandObjectSource.cpp
@@ -1175,33 +1175,35 @@ class CommandObjectSourceList : public CommandObjectParsed {
// 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. So if a header was requested and we got a
- // primary file, then look thru its support file(s) for the header.
- lldb::SupportFileSP actual_file_sp =
+ // primary file (ie., something with a different name), then look thru
+ // its support file(s) for the header.
+ lldb::SupportFileSP found_file_sp =
sc.comp_unit->GetPrimarySupportFile();
- if (llvm::StringRef(m_options.file_name).ends_with(".h")) {
+
+ if (!llvm::StringRef(found_file_sp->GetSpecOnly().GetPath())
+ .ends_with(filename)) {
int support_matches_count = 0;
for (auto &file : sc.comp_unit->GetSupportFiles()) {
if (llvm::StringRef(file->GetSpecOnly().GetPath())
.ends_with(filename)) {
- actual_file_sp = file;
+ found_file_sp = file;
++support_matches_count;
}
}
if (support_matches_count == 0) {
result.AppendErrorWithFormat(
- "No file found for requested header: \"%s.\"\n",
- m_options.file_name.c_str());
+ "No file found for requested header: \"%s.\"\n", filename);
return;
} else if (support_matches_count > 1) {
result.AppendErrorWithFormat(
"Multiple files found for requested header: \"%s.\"\n",
- m_options.file_name.c_str());
+ filename);
return;
}
}
target.GetSourceManager().DisplaySourceLinesWithLineNumbers(
- actual_file_sp, m_options.start_line, column, 0,
+ found_file_sp, m_options.start_line, column, 0,
m_options.num_lines, "", &result.GetOutputStream(),
GetBreakpointLocations());
More information about the lldb-commits
mailing list