[Lldb-commits] [lldb] [lldb][Format] Display only the inlined frame name in backtraces if available (PR #135343)
Michael Buch via lldb-commits
lldb-commits at lists.llvm.org
Fri Apr 11 07:54:42 PDT 2025
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/135343
>From 7d8455bd0b30ee5cd49788243646e75ae8938159 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 11 Apr 2025 11:02:19 +0100
Subject: [PATCH 1/5] [lldb][Format] Only display inlined frame name in
backtraces if available
---
lldb/include/lldb/Symbol/SymbolContext.h | 7 ++
lldb/source/Core/FormatEntity.cpp | 95 +++++--------------
.../Language/CPlusPlus/CPlusPlusLanguage.cpp | 25 +----
lldb/source/Symbol/SymbolContext.cpp | 26 +++++
.../Shell/Settings/TestFrameFormatName.test | 8 +-
5 files changed, 63 insertions(+), 98 deletions(-)
diff --git a/lldb/include/lldb/Symbol/SymbolContext.h b/lldb/include/lldb/Symbol/SymbolContext.h
index 8b6317c6f33c2..4f8405f1f0db5 100644
--- a/lldb/include/lldb/Symbol/SymbolContext.h
+++ b/lldb/include/lldb/Symbol/SymbolContext.h
@@ -307,6 +307,13 @@ class SymbolContext {
SymbolContext &next_frame_sc,
Address &inlined_frame_addr) const;
+ /// If available, will return the function name according to the specified
+ /// mangling preference. If this object represents an inlined function,
+ /// returns the name of the inlined function. Returns nullptr if no function
+ /// name could be determined.
+ const char *GetPossiblyInlinedFunctionName(
+ Mangled::NamePreference mangling_preference) const;
+
// Member variables
lldb::TargetSP target_sp; ///< The Target for a given query
lldb::ModuleSP module_sp; ///< The Module for a given query
diff --git a/lldb/source/Core/FormatEntity.cpp b/lldb/source/Core/FormatEntity.cpp
index a9370595c11e7..c3068a9cfaeab 100644
--- a/lldb/source/Core/FormatEntity.cpp
+++ b/lldb/source/Core/FormatEntity.cpp
@@ -1147,19 +1147,6 @@ static void PrettyPrintFunctionNameWithArgs(Stream &out_stream,
out_stream.PutChar(')');
}
-static void FormatInlinedBlock(Stream &out_stream, Block *block) {
- if (!block)
- return;
- Block *inline_block = block->GetContainingInlinedBlock();
- if (inline_block) {
- if (const InlineFunctionInfo *inline_info =
- inline_block->GetInlinedFunctionInfo()) {
- out_stream.PutCString(" [inlined] ");
- inline_info->GetName().Dump(&out_stream);
- }
- }
-}
-
static VariableListSP GetFunctionVariableList(const SymbolContext &sc) {
assert(sc.function);
@@ -1170,22 +1157,6 @@ static VariableListSP GetFunctionVariableList(const SymbolContext &sc) {
return sc.function->GetBlock(true).GetBlockVariableList(true);
}
-static char const *GetInlinedFunctionName(const SymbolContext &sc) {
- if (!sc.block)
- return nullptr;
-
- const Block *inline_block = sc.block->GetContainingInlinedBlock();
- if (!inline_block)
- return nullptr;
-
- const InlineFunctionInfo *inline_info =
- inline_block->GetInlinedFunctionInfo();
- if (!inline_info)
- return nullptr;
-
- return inline_info->GetName().AsCString(nullptr);
-}
-
static bool PrintFunctionNameWithArgs(Stream &s,
const ExecutionContext *exe_ctx,
const SymbolContext &sc) {
@@ -1194,16 +1165,11 @@ static bool PrintFunctionNameWithArgs(Stream &s,
ExecutionContextScope *exe_scope =
exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;
- const char *cstr = sc.function->GetName().AsCString(nullptr);
+ const char *cstr =
+ sc.GetPossiblyInlinedFunctionName(Mangled::ePreferDemangled);
if (!cstr)
return false;
- if (const char *inlined_name = GetInlinedFunctionName(sc)) {
- s.PutCString(cstr);
- s.PutCString(" [inlined] ");
- cstr = inlined_name;
- }
-
VariableList args;
if (auto variable_list_sp = GetFunctionVariableList(sc))
variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument,
@@ -1724,21 +1690,17 @@ bool FormatEntity::Format(const Entry &entry, Stream &s,
if (language_plugin_handled) {
s << ss.GetString();
return true;
- } else {
- const char *name = nullptr;
- if (sc->function)
- name = sc->function->GetName().AsCString(nullptr);
- else if (sc->symbol)
- name = sc->symbol->GetName().AsCString(nullptr);
-
- if (name) {
- s.PutCString(name);
- FormatInlinedBlock(s, sc->block);
- return true;
- }
}
+
+ const char *name = GetPossiblyInlinedFunctionName(
+ *sc, Mangled::NamePreference::ePreferDemangled);
+ if (!name)
+ return false;
+
+ s.PutCString(name);
+
+ return true;
}
- return false;
case Entry::Type::FunctionNameNoArgs: {
if (!sc)
@@ -1760,20 +1722,17 @@ bool FormatEntity::Format(const Entry &entry, Stream &s,
if (language_plugin_handled) {
s << ss.GetString();
return true;
- } else {
- ConstString name;
- if (sc->function)
- name = sc->function->GetNameNoArguments();
- else if (sc->symbol)
- name = sc->symbol->GetNameNoArguments();
- if (name) {
- s.PutCString(name.GetCString());
- FormatInlinedBlock(s, sc->block);
- return true;
- }
}
+
+ const char *name = GetPossiblyInlinedFunctionName(
+ *sc, Mangled::NamePreference::ePreferDemangledWithoutArguments);
+ if (!name)
+ return false;
+
+ s.PutCString(name);
+
+ return true;
}
- return false;
case Entry::Type::FunctionNameWithArgs: {
if (!sc)
@@ -1814,19 +1773,13 @@ bool FormatEntity::Format(const Entry &entry, Stream &s,
if (!sc)
return false;
- const char *name = nullptr;
- if (sc->symbol)
- name =
- sc->symbol->GetMangled().GetName(Mangled::ePreferMangled).AsCString();
- else if (sc->function)
- name = sc->function->GetMangled()
- .GetName(Mangled::ePreferMangled)
- .AsCString();
-
+ const char *name = GetPossiblyInlinedFunctionName(
+ *sc, Mangled::NamePreference::ePreferMangled);
if (!name)
return false;
+
s.PutCString(name);
- FormatInlinedBlock(s, sc->block);
+
return true;
}
case Entry::Type::FunctionAddrOffset:
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index a6fdf66f13e4d..e985c11f66e86 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -1707,22 +1707,6 @@ static VariableListSP GetFunctionVariableList(const SymbolContext &sc) {
return sc.function->GetBlock(true).GetBlockVariableList(true);
}
-static char const *GetInlinedFunctionName(const SymbolContext &sc) {
- if (!sc.block)
- return nullptr;
-
- const Block *inline_block = sc.block->GetContainingInlinedBlock();
- if (!inline_block)
- return nullptr;
-
- const InlineFunctionInfo *inline_info =
- inline_block->GetInlinedFunctionInfo();
- if (!inline_info)
- return nullptr;
-
- return inline_info->GetName().AsCString(nullptr);
-}
-
static bool PrintFunctionNameWithArgs(Stream &s,
const ExecutionContext *exe_ctx,
const SymbolContext &sc) {
@@ -1731,16 +1715,11 @@ static bool PrintFunctionNameWithArgs(Stream &s,
ExecutionContextScope *exe_scope =
exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;
- const char *cstr = sc.function->GetName().AsCString(nullptr);
+ const char *cstr = sc.GetPossiblyInlinedFunctionName(
+ Mangled::NamePreference::ePreferDemangled);
if (!cstr)
return false;
- if (const char *inlined_name = GetInlinedFunctionName(sc)) {
- s.PutCString(cstr);
- s.PutCString(" [inlined] ");
- cstr = inlined_name;
- }
-
VariableList args;
if (auto variable_list_sp = GetFunctionVariableList(sc))
variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument,
diff --git a/lldb/source/Symbol/SymbolContext.cpp b/lldb/source/Symbol/SymbolContext.cpp
index 183947a694363..b8c7ab66c8845 100644
--- a/lldb/source/Symbol/SymbolContext.cpp
+++ b/lldb/source/Symbol/SymbolContext.cpp
@@ -872,6 +872,32 @@ const Symbol *SymbolContext::FindBestGlobalDataSymbol(ConstString name,
return nullptr; // no error; we just didn't find anything
}
+char const *SymbolContext::GetPossiblyInlinedFunctionName(
+ Mangled::NamePreference mangling_preference) const {
+ const char *name = nullptr;
+ if (function)
+ name = function->GetMangled().GetName(mangling_preference).AsCString();
+ else if (symbol)
+ name = symbol->GetMangled().GetName(mangling_preference).AsCString();
+
+ if (!block)
+ return name;
+
+ const Block *inline_block = block->GetContainingInlinedBlock();
+ if (!inline_block)
+ return name;
+
+ const InlineFunctionInfo *inline_info =
+ inline_block->GetInlinedFunctionInfo();
+ if (!inline_info)
+ return name;
+
+ // If we do have an inlined frame name, return that.
+ return inline_info->GetMangled()
+ .GetName(mangling_preference)
+ .AsCString(nullptr);
+}
+
//
// SymbolContextSpecifier
//
diff --git a/lldb/test/Shell/Settings/TestFrameFormatName.test b/lldb/test/Shell/Settings/TestFrameFormatName.test
index caa3242527c6e..110daceb47b40 100644
--- a/lldb/test/Shell/Settings/TestFrameFormatName.test
+++ b/lldb/test/Shell/Settings/TestFrameFormatName.test
@@ -30,7 +30,7 @@ c
c
# NAME_WITH_ARGS: frame Foo::returns_func_ptr<int>(this={{.*}}, (null)={{.*}})
c
-# NAME_WITH_ARGS: frame main [inlined] inlined_foo(str="bar")
+# NAME_WITH_ARGS: frame inlined_foo(str="bar")
q
#--- name.input
@@ -38,18 +38,18 @@ q
settings set -f frame-format "frame ${function.name}\n"
break set -n inlined_foo
run
-# NAME: frame main [inlined] inlined_foo(char const*)
+# NAME: frame inlined_foo(char const*)
#--- name_without_args.input
# RUN: %lldb -b -s %t/name_without_args.input %t.out | FileCheck %s --check-prefix=NAME_WITHOUT_ARGS
settings set -f frame-format "frame ${function.name-without-args}\n"
break set -n inlined_foo
run
-# NAME_WITHOUT_ARGS: frame main [inlined] inlined_foo(char const*)
+# NAME_WITHOUT_ARGS: frame inlined_foo
#--- mangled_name.input
# RUN: %lldb -b -s %t/mangled_name.input %t.out | FileCheck %s --check-prefix=MANGLED_NAME
settings set -f frame-format "frame ${function.mangled-name}\n"
break set -n inlined_foo
run
-# MANGLED_NAME: frame main [inlined] inlined_foo(char const*)
+# MANGLED_NAME: frame _Z11inlined_fooPKc
>From 5f6ad22f9c24546c22813760b403006e280d3196 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 11 Apr 2025 12:50:47 +0100
Subject: [PATCH 2/5] fixup! fix build failure
---
lldb/source/Core/FormatEntity.cpp | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/lldb/source/Core/FormatEntity.cpp b/lldb/source/Core/FormatEntity.cpp
index c3068a9cfaeab..33cf7794866b2 100644
--- a/lldb/source/Core/FormatEntity.cpp
+++ b/lldb/source/Core/FormatEntity.cpp
@@ -1692,8 +1692,8 @@ bool FormatEntity::Format(const Entry &entry, Stream &s,
return true;
}
- const char *name = GetPossiblyInlinedFunctionName(
- *sc, Mangled::NamePreference::ePreferDemangled);
+ const char *name = sc->GetPossiblyInlinedFunctionName(
+ Mangled::NamePreference::ePreferDemangled);
if (!name)
return false;
@@ -1724,8 +1724,8 @@ bool FormatEntity::Format(const Entry &entry, Stream &s,
return true;
}
- const char *name = GetPossiblyInlinedFunctionName(
- *sc, Mangled::NamePreference::ePreferDemangledWithoutArguments);
+ const char *name = sc->GetPossiblyInlinedFunctionName(
+ Mangled::NamePreference::ePreferDemangledWithoutArguments);
if (!name)
return false;
@@ -1773,8 +1773,8 @@ bool FormatEntity::Format(const Entry &entry, Stream &s,
if (!sc)
return false;
- const char *name = GetPossiblyInlinedFunctionName(
- *sc, Mangled::NamePreference::ePreferMangled);
+ const char *name = sc->GetPossiblyInlinedFunctionName(
+ Mangled::NamePreference::ePreferMangled);
if (!name)
return false;
>From 30eb129faa35c1c05b7d846dd498b1140a91c90e Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 11 Apr 2025 13:33:41 +0100
Subject: [PATCH 3/5] fixup! update more tests
---
.../param_entry_vals/basic_entry_values/main.cpp | 4 ++--
.../tail_call_frames/inlining_and_tail_calls/main.cpp | 6 ++----
2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/lldb/test/API/functionalities/param_entry_vals/basic_entry_values/main.cpp b/lldb/test/API/functionalities/param_entry_vals/basic_entry_values/main.cpp
index 7ad72b4880d79..64e2a5b479675 100644
--- a/lldb/test/API/functionalities/param_entry_vals/basic_entry_values/main.cpp
+++ b/lldb/test/API/functionalities/param_entry_vals/basic_entry_values/main.cpp
@@ -70,8 +70,8 @@ __attribute__((noinline)) void func6(int &sink, int x) {
__attribute__((noinline)) void func7(int &sink, int x) {
//% self.filecheck("bt", "main.cpp", "-check-prefix=FUNC7-BT")
// FUNC7-BT: func7
- // FUNC7-BT-NEXT: [inlined] func8_inlined
- // FUNC7-BT-NEXT: [inlined] func9_inlined
+ // FUNC7-BT-NEXT: func8_inlined
+ // FUNC7-BT-NEXT: func9_inlined
// FUNC7-BT-NEXT: func10
use<int &, int>(sink, x);
use<int &, int>(dummy, 0);
diff --git a/lldb/test/API/functionalities/tail_call_frames/inlining_and_tail_calls/main.cpp b/lldb/test/API/functionalities/tail_call_frames/inlining_and_tail_calls/main.cpp
index 9829e0246fc2b..5e5c0aa1d5fc4 100644
--- a/lldb/test/API/functionalities/tail_call_frames/inlining_and_tail_calls/main.cpp
+++ b/lldb/test/API/functionalities/tail_call_frames/inlining_and_tail_calls/main.cpp
@@ -3,10 +3,8 @@ volatile int x;
void __attribute__((noinline)) tail_call_sink() {
x++; //% self.filecheck("bt", "main.cpp", "-check-prefix=TAIL-CALL-SINK")
// TAIL-CALL-SINK: frame #0: 0x{{[0-9a-f]+}} a.out`tail_call_sink() at main.cpp:[[@LINE-1]]:4
- // TAIL-CALL-SINK-NEXT: func3{{.*}} [artificial]
+ // TAIL-CALL-SINK-NEXT: inlinable_function_which_tail_calls() at main.cpp{{.*}} [artificial]
// TAIL-CALL-SINK-NEXT: main{{.*}}
-
- // TODO: The backtrace should include inlinable_function_which_tail_calls.
}
void __attribute__((always_inline)) inlinable_function_which_tail_calls() {
@@ -19,7 +17,7 @@ void __attribute__((noinline)) func3() {
void __attribute__((always_inline)) inline_sink() {
x++; //% self.filecheck("bt", "main.cpp", "-check-prefix=INLINE-SINK")
- // INLINE-SINK: frame #0: 0x{{[0-9a-f]+}} a.out`func2() [inlined] inline_sink() at main.cpp:[[@LINE-1]]:4
+ // INLINE-SINK: frame #0: 0x{{[0-9a-f]+}} a.out`inline_sink() at main.cpp:[[@LINE-1]]:4
// INLINE-SINK-NEXT: func2{{.*}}
// INLINE-SINK-NEXT: func1{{.*}} [artificial]
// INLINE-SINK-NEXT: main{{.*}}
>From fc3443187b35dec1ce99ca16dc57a8702bfdb75f Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 11 Apr 2025 15:44:40 +0100
Subject: [PATCH 4/5] fixup! inline-name fallback
---
lldb/source/Symbol/SymbolContext.cpp | 11 ++++++++---
.../Recognizer/verbose_trap-in-stl-max-depth.test | 2 +-
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/lldb/source/Symbol/SymbolContext.cpp b/lldb/source/Symbol/SymbolContext.cpp
index b8c7ab66c8845..dfb3203dbc180 100644
--- a/lldb/source/Symbol/SymbolContext.cpp
+++ b/lldb/source/Symbol/SymbolContext.cpp
@@ -893,9 +893,14 @@ char const *SymbolContext::GetPossiblyInlinedFunctionName(
return name;
// If we do have an inlined frame name, return that.
- return inline_info->GetMangled()
- .GetName(mangling_preference)
- .AsCString(nullptr);
+ if (char const *inline_name = inline_info->GetMangled()
+ .GetName(mangling_preference)
+ .AsCString(nullptr))
+ return inline_name;
+
+ // Sometimes an inline frame may not have mangling information,
+ // but does have a valid name.
+ return inline_info->GetName().AsCString(nullptr);
}
//
diff --git a/lldb/test/Shell/Recognizer/verbose_trap-in-stl-max-depth.test b/lldb/test/Shell/Recognizer/verbose_trap-in-stl-max-depth.test
index 0c3275c571b3d..2ea6594643c9c 100644
--- a/lldb/test/Shell/Recognizer/verbose_trap-in-stl-max-depth.test
+++ b/lldb/test/Shell/Recognizer/verbose_trap-in-stl-max-depth.test
@@ -12,5 +12,5 @@ run
frame recognizer info 0
# CHECK: frame 0 is recognized by Verbose Trap StackFrame Recognizer
frame info
-# CHECK: frame #0: {{.*}}`std::recursively_aborts(int) {{.*}} at verbose_trap-in-stl-max-depth.cpp
+# CHECK: frame #0: {{.*}}`__clang_trap_msg$Error$max depth at verbose_trap-in-stl-max-depth.cpp
q
>From 2bcfbf8401dbbc4708100b626ff43eb80674cd65 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 11 Apr 2025 15:48:32 +0100
Subject: [PATCH 5/5] fixup! remove redundant parameter
---
lldb/source/Symbol/SymbolContext.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lldb/source/Symbol/SymbolContext.cpp b/lldb/source/Symbol/SymbolContext.cpp
index dfb3203dbc180..45f30e186191a 100644
--- a/lldb/source/Symbol/SymbolContext.cpp
+++ b/lldb/source/Symbol/SymbolContext.cpp
@@ -895,12 +895,12 @@ char const *SymbolContext::GetPossiblyInlinedFunctionName(
// If we do have an inlined frame name, return that.
if (char const *inline_name = inline_info->GetMangled()
.GetName(mangling_preference)
- .AsCString(nullptr))
+ .AsCString())
return inline_name;
// Sometimes an inline frame may not have mangling information,
// but does have a valid name.
- return inline_info->GetName().AsCString(nullptr);
+ return inline_info->GetName().AsCString();
}
//
More information about the lldb-commits
mailing list