Skip to content

Commit 3fea3a1

Browse files
committed
[lldb] Revive shell test after updating UnwindTable (llvm#86770)
In commit 2f63718 Author: Jason Molenda <jmolenda@apple.com> Date: Tue Mar 26 09:07:15 2024 -0700 [lldb] Don't clear a Module's UnwindTable when adding a SymbolFile (llvm#86603) I stopped clearing a Module's UnwindTable when we add a SymbolFile to avoid the memory management problems with adding a symbol file asynchronously while the UnwindTable is being accessed on another thread. This broke the target-symbols-add-unwind.test shell test on Linux which removes the DWARF debub_frame section from a binary, loads it, then loads the unstripped binary with the DWARF debug_frame section and checks that the UnwindPlans for a function include debug_frame. I originally decided that I was willing to sacrifice the possiblity of additional unwind sources from a symbol file because we rely on assembly emulation so heavily, they're rarely critical. But there are targets where we we don't have emluation and rely on things like DWARF debug_frame a lot more, so this probably wasn't a good choice. This patch adds a new UnwindTable::Update method which looks for any new sources of unwind information and adds it to the UnwindTable, and calls that after a new SymbolFile has been added to a Module. (cherry picked from commit 6a0ec8e)
1 parent ed27e54 commit 3fea3a1

File tree

4 files changed

+78
-0
lines changed

4 files changed

+78
-0
lines changed

lldb/include/lldb/Symbol/UnwindTable.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ class UnwindTable {
5757

5858
ArchSpec GetArchitecture();
5959

60+
/// Called after a SymbolFile has been added to a Module to add any new
61+
/// unwind sections that may now be available.
62+
void Update();
63+
6064
private:
6165
void Dump(Stream &s);
6266

lldb/source/Core/Module.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,6 +1046,8 @@ SymbolFile *Module::GetSymbolFile(bool can_create, Stream *feedback_strm) {
10461046
m_symfile_up.reset(
10471047
SymbolVendor::FindPlugin(shared_from_this(), feedback_strm));
10481048
m_did_load_symfile = true;
1049+
if (m_unwind_table)
1050+
m_unwind_table->Update();
10491051
}
10501052
}
10511053
}

lldb/source/Symbol/UnwindTable.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,51 @@ void UnwindTable::Initialize() {
8484
}
8585
}
8686

87+
void UnwindTable::Update() {
88+
if (!m_initialized)
89+
return Initialize();
90+
91+
std::lock_guard<std::mutex> guard(m_mutex);
92+
93+
ObjectFile *object_file = m_module.GetObjectFile();
94+
if (!object_file)
95+
return;
96+
97+
if (!m_object_file_unwind_up)
98+
m_object_file_unwind_up = object_file->CreateCallFrameInfo();
99+
100+
SectionList *sl = m_module.GetSectionList();
101+
if (!sl)
102+
return;
103+
104+
SectionSP sect = sl->FindSectionByType(eSectionTypeEHFrame, true);
105+
if (!m_eh_frame_up && sect) {
106+
m_eh_frame_up = std::make_unique<DWARFCallFrameInfo>(
107+
*object_file, sect, DWARFCallFrameInfo::EH);
108+
}
109+
110+
sect = sl->FindSectionByType(eSectionTypeDWARFDebugFrame, true);
111+
if (!m_debug_frame_up && sect) {
112+
m_debug_frame_up = std::make_unique<DWARFCallFrameInfo>(
113+
*object_file, sect, DWARFCallFrameInfo::DWARF);
114+
}
115+
116+
sect = sl->FindSectionByType(eSectionTypeCompactUnwind, true);
117+
if (!m_compact_unwind_up && sect) {
118+
m_compact_unwind_up =
119+
std::make_unique<CompactUnwindInfo>(*object_file, sect);
120+
}
121+
122+
sect = sl->FindSectionByType(eSectionTypeARMexidx, true);
123+
if (!m_arm_unwind_up && sect) {
124+
SectionSP sect_extab = sl->FindSectionByType(eSectionTypeARMextab, true);
125+
if (sect_extab.get()) {
126+
m_arm_unwind_up =
127+
std::make_unique<ArmUnwindInfo>(*object_file, sect, sect_extab);
128+
}
129+
}
130+
}
131+
87132
UnwindTable::~UnwindTable() = default;
88133

89134
std::optional<AddressRange>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
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
17+
# CHECK-NOT: debug_frame UnwindPlan:
18+
19+
target symbols add -s target-symbols-add-unwind.stripped target-symbols-add-unwind.debug
20+
# CHECK-LABEL: target symbols add
21+
# CHECK: symbol file {{.*}} has been added to {{.*}}
22+
23+
image show-unwind -n main
24+
# CHECK-LABEL: image show-unwind -n main
25+
# CHECK: debug_frame UnwindPlan:
26+
# CHECK-NEXT: This UnwindPlan originally sourced from DWARF CFI
27+
# CHECK-NEXT: This UnwindPlan is sourced from the compiler: yes.

0 commit comments

Comments
 (0)