Skip to content

Commit

Permalink
[lldb] Revive shell test after updating UnwindTable (#86770)
Browse files Browse the repository at this point in the history
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
(#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.
  • Loading branch information
jasonmolenda committed Mar 27, 2024
1 parent 7711853 commit 6a0ec8e
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 0 deletions.
4 changes: 4 additions & 0 deletions lldb/include/lldb/Symbol/UnwindTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ class UnwindTable {

ArchSpec GetArchitecture();

/// Called after a SymbolFile has been added to a Module to add any new
/// unwind sections that may now be available.
void Update();

private:
void Dump(Stream &s);

Expand Down
2 changes: 2 additions & 0 deletions lldb/source/Core/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1009,6 +1009,8 @@ SymbolFile *Module::GetSymbolFile(bool can_create, Stream *feedback_strm) {
m_symfile_up.reset(
SymbolVendor::FindPlugin(shared_from_this(), feedback_strm));
m_did_load_symfile = true;
if (m_unwind_table)
m_unwind_table->Update();
}
}
}
Expand Down
45 changes: 45 additions & 0 deletions lldb/source/Symbol/UnwindTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,51 @@ void UnwindTable::Initialize() {
}
}

void UnwindTable::Update() {
if (!m_initialized)
return Initialize();

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

ObjectFile *object_file = m_module.GetObjectFile();
if (!object_file)
return;

if (!m_object_file_unwind_up)
m_object_file_unwind_up = object_file->CreateCallFrameInfo();

SectionList *sl = m_module.GetSectionList();
if (!sl)
return;

SectionSP sect = sl->FindSectionByType(eSectionTypeEHFrame, true);
if (!m_eh_frame_up && sect) {
m_eh_frame_up = std::make_unique<DWARFCallFrameInfo>(
*object_file, sect, DWARFCallFrameInfo::EH);
}

sect = sl->FindSectionByType(eSectionTypeDWARFDebugFrame, true);
if (!m_debug_frame_up && sect) {
m_debug_frame_up = std::make_unique<DWARFCallFrameInfo>(
*object_file, sect, DWARFCallFrameInfo::DWARF);
}

sect = sl->FindSectionByType(eSectionTypeCompactUnwind, true);
if (!m_compact_unwind_up && sect) {
m_compact_unwind_up =
std::make_unique<CompactUnwindInfo>(*object_file, sect);
}

sect = sl->FindSectionByType(eSectionTypeARMexidx, true);
if (!m_arm_unwind_up && sect) {
SectionSP sect_extab = sl->FindSectionByType(eSectionTypeARMextab, true);
if (sect_extab.get()) {
m_arm_unwind_up =
std::make_unique<ArmUnwindInfo>(*object_file, sect, sect_extab);
}
}
}

UnwindTable::~UnwindTable() = default;

std::optional<AddressRange>
Expand Down
27 changes: 27 additions & 0 deletions lldb/test/Shell/SymbolFile/target-symbols-add-unwind.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# TODO: When it's possible to run "image show-unwind" without a running
# process, we can remove the unsupported line below, and hard-code an ELF
# triple in the test.
# UNSUPPORTED: system-windows, system-darwin

# RUN: cd %T
# RUN: %clang_host %S/Inputs/target-symbols-add-unwind.c -g \
# RUN: -fno-unwind-tables -fno-asynchronous-unwind-tables \
# RUN: -o target-symbols-add-unwind.debug
# RUN: llvm-objcopy --strip-debug target-symbols-add-unwind.debug \
# RUN: target-symbols-add-unwind.stripped
# RUN: %lldb target-symbols-add-unwind.stripped -s %s -o quit | FileCheck %s

process launch --stop-at-entry
image show-unwind -n main
# CHECK-LABEL: image show-unwind -n main
# CHECK-NOT: debug_frame UnwindPlan:

target symbols add -s target-symbols-add-unwind.stripped target-symbols-add-unwind.debug
# CHECK-LABEL: target symbols add
# CHECK: symbol file {{.*}} has been added to {{.*}}

image show-unwind -n main
# CHECK-LABEL: image show-unwind -n main
# CHECK: debug_frame UnwindPlan:
# CHECK-NEXT: This UnwindPlan originally sourced from DWARF CFI
# CHECK-NEXT: This UnwindPlan is sourced from the compiler: yes.

0 comments on commit 6a0ec8e

Please sign in to comment.