Skip to content

Commit cebf86e

Browse files
authored
[lldb][Format] Make function name frame-format variables work without debug-info (#137408)
This patch makes the frame-format variables introduced in #131836 also work when no debug-info is available. Previously, we assumed `sc.function` was available, but without debug-info we might only have `sc.symbol`. We don't really need the `sc.function` apart from when formatting arguments. For the function arguments case I added a fallback that will just print the arguments we get from the demangler (which is what LLDB does for stacktraces with no debug-info anyway). Ideally we'd have a separate `FormatEntity::Entry::Type::FunctionArguments` that will just print the arguments from the demangler and have something like the following in the `plugin.cplusplus.display.function-name-format`: ``` { ${function.formatted-arguments} || ${function.arguments} } ``` I.e., when we can't format the arguments, print the ones from the demangler. But we currently don't have the `||` operator in the frame-format language yet.
1 parent 32059ce commit cebf86e

8 files changed

+73
-10
lines changed

lldb/source/Core/FormatEntity.cpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -1809,11 +1809,12 @@ bool FormatEntity::Format(const Entry &entry, Stream &s,
18091809
case Entry::Type::FunctionReturnRight:
18101810
case Entry::Type::FunctionReturnLeft:
18111811
case Entry::Type::FunctionQualifiers: {
1812-
if (!sc->function)
1813-
return false;
1812+
Language *language_plugin = nullptr;
1813+
if (sc->function)
1814+
language_plugin = Language::FindPlugin(sc->function->GetLanguage());
1815+
else if (sc->symbol)
1816+
language_plugin = Language::FindPlugin(sc->symbol->GetLanguage());
18141817

1815-
Language *language_plugin =
1816-
Language::FindPlugin(sc->function->GetLanguage());
18171818
if (!language_plugin)
18181819
return false;
18191820

lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp

+36-2
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,34 @@ GetDemangledScope(const SymbolContext &sc) {
381381
return demangled_name.slice(info->ScopeRange.first, info->ScopeRange.second);
382382
}
383383

384+
static bool PrintDemangledArgumentList(Stream &s, const SymbolContext &sc) {
385+
assert(sc.symbol);
386+
387+
Mangled mangled = sc.GetPossiblyInlinedFunctionName();
388+
if (!mangled)
389+
return false;
390+
391+
auto demangled_name = mangled.GetDemangledName().GetStringRef();
392+
if (demangled_name.empty())
393+
return false;
394+
395+
const std::optional<DemangledNameInfo> &info = mangled.GetDemangledInfo();
396+
if (!info)
397+
return false;
398+
399+
// Function without a basename is nonsense.
400+
if (!info->hasBasename())
401+
return false;
402+
403+
if (info->ArgumentsRange.second < info->ArgumentsRange.first)
404+
return false;
405+
406+
s << demangled_name.slice(info->ArgumentsRange.first,
407+
info->ArgumentsRange.second);
408+
409+
return true;
410+
}
411+
384412
bool CPlusPlusLanguage::CxxMethodName::TrySimplifiedParse() {
385413
// This method tries to parse simple method definitions which are presumably
386414
// most comman in user programs. Definitions that can be parsed by this
@@ -1890,8 +1918,6 @@ bool CPlusPlusLanguage::GetFunctionDisplayName(
18901918
bool CPlusPlusLanguage::HandleFrameFormatVariable(
18911919
const SymbolContext &sc, const ExecutionContext *exe_ctx,
18921920
FormatEntity::Entry::Type type, Stream &s) {
1893-
assert(sc.function);
1894-
18951921
switch (type) {
18961922
case FormatEntity::Entry::Type::FunctionScope: {
18971923
std::optional<llvm::StringRef> scope = GetDemangledScope(sc);
@@ -1925,6 +1951,14 @@ bool CPlusPlusLanguage::HandleFrameFormatVariable(
19251951
}
19261952

19271953
case FormatEntity::Entry::Type::FunctionFormattedArguments: {
1954+
// This ensures we print the arguments even when no debug-info is available.
1955+
//
1956+
// FIXME: we should have a Entry::Type::FunctionArguments and
1957+
// use it in the plugin.cplusplus.display.function-name-format
1958+
// once we have a "fallback operator" in the frame-format language.
1959+
if (!sc.function && sc.symbol)
1960+
return PrintDemangledArgumentList(s, sc);
1961+
19281962
VariableList args;
19291963
if (auto variable_list_sp = GetFunctionVariableList(sc))
19301964
variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument,

lldb/test/Shell/Settings/TestFrameFormatFunctionBasename.test

+4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
# RUN: %lldb -x -b -s %t/commands.input %t.out -o exit 2>&1 \
88
# RUN: | FileCheck %s
99
#
10+
# RUN: %clang_host -O0 %t/main.cpp -o %t-nodebug.out
11+
# RUN: %lldb -x -b -s %t/commands.input %t-nodebug.out -o exit 2>&1 \
12+
# RUN: | FileCheck %s
13+
1014
#--- main.cpp
1115
namespace ns {
1216
template<typename T>

lldb/test/Shell/Settings/TestFrameFormatFunctionFormattedArguments.test

+9
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
# RUN: %clang_host -g -gdwarf %t/main.cpp -o %t.out
77
# RUN: %lldb -x -b -s %t/commands.input %t.out -o exit 2>&1 \
88
# RUN: | FileCheck %s
9+
#
10+
# RUN: %clang_host -O0 %t/main.cpp -o %t-nodebug.out
11+
# RUN: %lldb -x -b -s %t/commands.input %t-nodebug.out -o exit 2>&1 \
12+
# RUN: | FileCheck %s --check-prefix=CHECK-NODEBUG
913

1014
#--- main.cpp
1115
struct Foo {
@@ -42,3 +46,8 @@ bt
4246
# CHECK: custom-frame '({{.*}}=5, x=10)'
4347
# CHECK: custom-frame '(str="hello", fptr=({{.*}}.out`{{.*}}foo(int,{{.*}}int) at main.cpp:{{[0-9]+}}))'
4448
# CHECK: custom-frame '(argc=1, argv={{.*}})'
49+
50+
# CHECK-NODEBUG: custom-frame '()'
51+
# CHECK-NODEBUG: custom-frame '()'
52+
# CHECK-NODEBUG: custom-frame '(int, int)'
53+
# CHECK-NODEBUG: custom-frame '(char const*, void (*)(int, int))'

lldb/test/Shell/Settings/TestFrameFormatFunctionQualifiers.test

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
# RUN: %clang_host -g -gdwarf %t/main.cpp -o %t.out
77
# RUN: %lldb -x -b -s %t/commands.input %t.out -o exit 2>&1 \
88
# RUN: | FileCheck %s
9+
#
10+
# RUN: %clang_host -O0 %t/main.cpp -o %t-nodebug.out
11+
# RUN: %lldb -x -b -s %t/commands.input %t-nodebug.out -o exit 2>&1 \
12+
# RUN: | FileCheck %s
913

1014
#--- main.cpp
1115
struct Foo {

lldb/test/Shell/Settings/TestFrameFormatFunctionReturn.test

+4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
# RUN: %clang_host -g -gdwarf %t/main.cpp -o %t.out
88
# RUN: %lldb -x -b -s %t/commands.input %t.out -o exit 2>&1 \
99
# RUN: | FileCheck %s
10+
#
11+
# RUN: %clang_host -O0 %t/main.cpp -o %t-nodebug.out
12+
# RUN: %lldb -x -b -s %t/commands.input %t-nodebug.out -o exit 2>&1 \
13+
# RUN: | FileCheck %s
1014

1115
#--- main.cpp
1216
namespace ns::ns2 {

lldb/test/Shell/Settings/TestFrameFormatFunctionScope.test

+5-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44

55
# RUN: split-file %s %t
66
# RUN: %clang_host -g -gdwarf %t/main.cpp -o %t.out
7-
# RUN: %lldb -o "settings set interpreter.stop-command-source-on-error false" \
8-
# RUN: -x -b -s %t/commands.input %t.out -o exit 2>&1 \
7+
# RUN: %lldb -x -b -s %t/commands.input %t.out -o exit 2>&1 \
8+
# RUN: | FileCheck %s
9+
#
10+
# RUN: %clang_host -O0 %t/main.cpp -o %t-nodebug.out
11+
# RUN: %lldb -x -b -s %t/commands.input %t-nodebug.out -o exit 2>&1 \
912
# RUN: | FileCheck %s
1013

1114
#--- main.cpp

lldb/test/Shell/Settings/TestFrameFormatFunctionTemplateArguments.test

+6-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@
33
# Test the ${function.template-arguments} frame-format variable.
44

55
# RUN: split-file %s %t
6-
# RUN: %clang_host -g -gdwarf %t/main.cpp -o %t.cxx.out
7-
# RUN: %lldb -x -b -s %t/commands.input %t.cxx.out -o exit 2>&1 \
6+
# RUN: %clang_host -g -gdwarf %t/main.cpp -o %t.out
7+
# RUN: %lldb -x -b -s %t/commands.input %t.out -o exit 2>&1 \
8+
# RUN: | FileCheck %s
9+
#
10+
# RUN: %clang_host -O0 %t/main.cpp -o %t-nodebug.out
11+
# RUN: %lldb -x -b -s %t/commands.input %t-nodebug.out -o exit 2>&1 \
812
# RUN: | FileCheck %s
913

1014
#--- main.cpp

0 commit comments

Comments
 (0)