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 <v...@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 <v...@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 <v...@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 <v...@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()); _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits