Skip to content

Commit 83ba374

Browse files
authored
[lldb] Clear cached unwind plans when adding symbols (#125839)
PR #86603 broke unwinding in for unwind info added via "target symbols add". #86770 attempted to fix this, but the fix was only partial -- it accepted new sources of unwind information, but didn't take into account that the symbol file can alter what lldb percieves as function boundaries. A stripped file will not contain information about private (non-exported) symbols, which will make the public symbols appear very large. If lldb tries to unwind from such a function before symbols are added, then the cached unwind plan will prevent new (correct) unwind plans from being created. target-symbols-add-unwind.test might have caught this, were it not for the fact that the "image show-unwind" command does *not* use cached unwind information (it recomputes it from scratch). The changes in this patch come in three pieces: - Clear cached unwind plans when adding symbols. Since the symbol boundaries can change, we cannot trust anything we've computed previously. - Add a flag to "image show-unwind" to display the cached unwind information (mainly for the use in the test, but I think it's also generally useful). - Rewrite the test to better and more reliably simulate the real-world scenario: I've swapped the running process for a core (minidump) file so it can run anywhere; used the caching version of the show-unwind command; and swapped C for assembly to better control the placement of symbols
1 parent ae08969 commit 83ba374

File tree

6 files changed

+125
-26
lines changed

6 files changed

+125
-26
lines changed

lldb/include/lldb/Symbol/UnwindTable.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@ class UnwindTable {
3838
ArmUnwindInfo *GetArmUnwindInfo();
3939
SymbolFile *GetSymbolFile();
4040

41-
lldb::FuncUnwindersSP GetFuncUnwindersContainingAddress(const Address &addr,
42-
SymbolContext &sc);
41+
lldb::FuncUnwindersSP
42+
GetFuncUnwindersContainingAddress(const Address &addr,
43+
const SymbolContext &sc);
4344

4445
bool GetAllowAssemblyEmulationUnwindPlans();
4546

lldb/source/Commands/CommandObjectTarget.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3474,6 +3474,17 @@ class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
34743474
m_type = eLookupTypeFunctionOrSymbol;
34753475
break;
34763476

3477+
case 'c':
3478+
bool value, success;
3479+
value = OptionArgParser::ToBoolean(option_arg, false, &success);
3480+
if (success) {
3481+
m_cached = value;
3482+
} else {
3483+
return Status::FromErrorStringWithFormatv(
3484+
"invalid boolean value '%s' passed for -c option", option_arg);
3485+
}
3486+
break;
3487+
34773488
default:
34783489
llvm_unreachable("Unimplemented option");
34793490
}
@@ -3485,6 +3496,7 @@ class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
34853496
m_type = eLookupTypeInvalid;
34863497
m_str.clear();
34873498
m_addr = LLDB_INVALID_ADDRESS;
3499+
m_cached = false;
34883500
}
34893501

34903502
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
@@ -3497,6 +3509,7 @@ class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
34973509
// parsing options
34983510
std::string m_str; // Holds name lookup
34993511
lldb::addr_t m_addr = LLDB_INVALID_ADDRESS; // Holds the address to lookup
3512+
bool m_cached = true;
35003513
};
35013514

35023515
CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter)
@@ -3583,9 +3596,12 @@ class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
35833596
if (abi)
35843597
start_addr = abi->FixCodeAddress(start_addr);
35853598

3586-
FuncUnwindersSP func_unwinders_sp(
3587-
sc.module_sp->GetUnwindTable()
3588-
.GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
3599+
UnwindTable &uw_table = sc.module_sp->GetUnwindTable();
3600+
FuncUnwindersSP func_unwinders_sp =
3601+
m_options.m_cached
3602+
? uw_table.GetFuncUnwindersContainingAddress(start_addr, sc)
3603+
: uw_table.GetUncachedFuncUnwindersContainingAddress(start_addr,
3604+
sc);
35893605
if (!func_unwinders_sp)
35903606
continue;
35913607

lldb/source/Commands/Options.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -965,6 +965,8 @@ let Command = "target modules show unwind" in {
965965
def target_modules_show_unwind_address : Option<"address", "a">, Group<2>,
966966
Arg<"AddressOrExpression">, Desc<"Show unwind instructions for a function "
967967
"or symbol containing an address">;
968+
def target_modules_show_unwind_cached : Option<"cached", "c">,
969+
Arg<"Boolean">, Desc<"Show cached unwind information">;
968970
}
969971

970972
let Command = "target modules lookup" in {

lldb/source/Symbol/UnwindTable.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ void UnwindTable::Initialize() {
8686
void UnwindTable::ModuleWasUpdated() {
8787
std::lock_guard<std::mutex> guard(m_mutex);
8888
m_scanned_all_unwind_sources = false;
89+
m_unwinds.clear();
8990
}
9091

9192
UnwindTable::~UnwindTable() = default;
@@ -118,7 +119,7 @@ UnwindTable::GetAddressRange(const Address &addr, const SymbolContext &sc) {
118119

119120
FuncUnwindersSP
120121
UnwindTable::GetFuncUnwindersContainingAddress(const Address &addr,
121-
SymbolContext &sc) {
122+
const SymbolContext &sc) {
122123
Initialize();
123124

124125
std::lock_guard<std::mutex> guard(m_mutex);

lldb/test/Shell/SymbolFile/Inputs/target-symbols-add-unwind.c

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 99 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,107 @@
1-
# TODO: When it's possible to run "image show-unwind" without a running
2-
# process, we can remove the unsupported line below, and hard-code an ELF
3-
# triple in the test.
4-
# UNSUPPORTED: system-windows, system-darwin
5-
6-
# RUN: cd %T
7-
# RUN: %clang_host %S/Inputs/target-symbols-add-unwind.c -g \
8-
# RUN: -fno-unwind-tables -fno-asynchronous-unwind-tables \
9-
# RUN: -o target-symbols-add-unwind.debug
10-
# RUN: llvm-objcopy --strip-debug target-symbols-add-unwind.debug \
11-
# RUN: target-symbols-add-unwind.stripped
12-
# RUN: %lldb target-symbols-add-unwind.stripped -s %s -o quit | FileCheck %s
13-
14-
process launch --stop-at-entry
15-
image show-unwind -n main
16-
# CHECK-LABEL: image show-unwind -n main
1+
# NB: The minidump core file exists only because "image show-unwind" currently
2+
# requires a process to exist. If that changes, it can be removed.
3+
4+
# REQUIRES: x86, lld
5+
6+
# RUN: split-file %s %t
7+
# RUN: yaml2obj %t/a.core.yaml -o %t/a.core
8+
# RUN: %clang -c --target=x86_64-pc-linux %t/a.s -o %t/a.o
9+
# RUN: ld.lld --shared %t/a.o -o %t/a.debug --build-id=0xdeadbeef \
10+
# RUN: --image-base=0x10000
11+
# RUN: llvm-objcopy --strip-all %t/a.debug %t/a.stripped
12+
# RUN: cd %t
13+
# RUN: %lldb -c %t/a.core \
14+
# RUN: -o "settings set interpreter.stop-command-source-on-error false" \
15+
# RUN: -s %t/commands -o quit | FileCheck %s
16+
17+
#--- commands
18+
19+
image add a.stripped
20+
image load --file a.stripped --slide 0
21+
image list
22+
# CHECK-LABEL: image list
23+
# CHECK: [ 0] DEADBEEF 0x0000000000010000 a.stripped
24+
25+
## Due to missing symbol information this (incorrectly) prints the unwind
26+
## information for public_fn1
27+
image show-unwind -n public_fn1 --cached true
28+
# CHECK-LABEL: image show-unwind -n public_fn1
29+
# CHECK-NEXT: UNWIND PLANS for a.stripped`public_fn1 (start addr 0x12000)
1730
# CHECK-NOT: debug_frame UnwindPlan:
1831

19-
target symbols add -s target-symbols-add-unwind.stripped target-symbols-add-unwind.debug
32+
target symbols add -s a.stripped a.debug
2033
# CHECK-LABEL: target symbols add
2134
# CHECK: symbol file {{.*}} has been added to {{.*}}
2235

23-
image show-unwind -n main
24-
# CHECK-LABEL: image show-unwind -n main
36+
image show-unwind -n private_fn --cached true
37+
# CHECK-LABEL: image show-unwind -n private_fn
38+
# CHECK-NEXT: UNWIND PLANS for a.stripped`private_fn (start addr 0x12010)
2539
# CHECK: debug_frame UnwindPlan:
2640
# CHECK-NEXT: This UnwindPlan originally sourced from DWARF CFI
2741
# CHECK-NEXT: This UnwindPlan is sourced from the compiler: yes.
42+
# CHECK-NEXT: This UnwindPlan is valid at all instruction locations: no.
43+
# CHECK-NEXT: This UnwindPlan is for a trap handler function: no.
44+
# CHECK-NEXT: Address range of this UnwindPlan: [a.stripped.PT_LOAD[1]..text + 16-0x0000000000000013)
45+
46+
47+
#--- a.s
48+
49+
.text
50+
.cfi_sections .debug_frame
51+
.globl public_fn1, public_fn2
52+
53+
.p2align 12
54+
public_fn1:
55+
.cfi_startproc
56+
pushq %rbp
57+
.cfi_def_cfa_offset 16
58+
.cfi_offset %rbp, -16
59+
popq %rbp
60+
.cfi_def_cfa %rsp, 8
61+
retq
62+
.cfi_endproc
63+
64+
.p2align 4
65+
private_fn:
66+
.cfi_startproc
67+
pushq %rbp
68+
.cfi_def_cfa_offset 16
69+
.cfi_offset %rbp, -16
70+
popq %rbp
71+
.cfi_def_cfa %rsp, 8
72+
retq
73+
.cfi_endproc
74+
75+
.p2align 4
76+
public_fn2:
77+
.cfi_startproc
78+
pushq %rbp
79+
.cfi_def_cfa_offset 16
80+
.cfi_offset %rbp, -16
81+
popq %rbp
82+
.cfi_def_cfa %rsp, 8
83+
retq
84+
.cfi_endproc
85+
86+
#--- a.core.yaml
87+
--- !minidump
88+
Streams:
89+
- Type: SystemInfo
90+
Processor Arch: AMD64
91+
Platform ID: Linux
92+
CPU:
93+
Vendor ID: GenuineIntel
94+
Version Info: 0x00000000
95+
Feature Info: 0x00000000
96+
- Type: ThreadList
97+
Threads:
98+
- Thread Id: 0x000074F3
99+
Context: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B001000000000006CAE000000006B7FC05A0000C81D415A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A2BF9E5A6B7F0000000000000000000000000000000000008850C14BFD7F00009850C14BFD7F00000100000000000000B04AC14BFD7F0000000000000000000060812D01000000000800000000000000B065E05A6B7F00008004400000000000E050C14BFD7F00000000000000000000000000000000000004400000000000007F03FFFF0000FFFFFFFFFFFF000000000000000000000000801F00006B7F00000400000000000000B84CC14BFD7F0000304D405A6B7F0000C84DC14BFD7F0000C0AA405A6B7F00004F033D0000000000B84DC14BFD7F0000E84DC14BFD7F0000000000000000000000000000000000000070E05A6B7F000078629E5A6B7F0000C81D415A6B7F0000804F9E5A6B7F00000000000001000000E603000001000000E093115A6B7F0000804EC14BFD7F0000584EC14BFD7F000099ADC05A6B7F00000100000000000000AAAAD77D0000000002000000000000000800000000000000B065E05A6B7F0000E6B7C05A6B7F0000010000006B7F0000884DC14BFD7F0000106F7C5A6B7F0000984EC14BFD7F0000488B7C5A6B7F0000C4A71CB90000000001000000000000000800000000000000B065E05A6B7F000048B6C05A6B7F0000702AE25A6B7F0000D84DC14BFD7F000030489E5A6B7F0000E84EC14BFD7F0000E05E9E5A6B7F00000991F0460000000001000000000000000800000000000000B065E05A6B7F000048B6C05A6B7F00000100000000000000284EC14BFD7F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
100+
Stack:
101+
Start of Memory Range: 0x00007FFD4BC15080
102+
Content: 30044000000000000000000000000000
103+
- Type: MemoryList
104+
Memory Ranges:
105+
- Start of Memory Range: 0x00007FFD4BC15080
106+
Content: 30044000000000000000000000000000
107+
...

0 commit comments

Comments
 (0)