diff options
author | Pavel Labath <pavel@labath.sk> | 2025-02-07 12:52:21 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-02-07 12:52:21 +0100 |
commit | 83ba3740bf51347307494d013099e392c310e32b (patch) | |
tree | 873f5d182a07bf8f97eeb9710676d5345a6246d0 /lldb/source | |
parent | ae08969a2068dd327fbf4d0f606550574fbb9e45 (diff) | |
download | llvm-83ba3740bf51347307494d013099e392c310e32b.zip llvm-83ba3740bf51347307494d013099e392c310e32b.tar.gz llvm-83ba3740bf51347307494d013099e392c310e32b.tar.bz2 |
[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
Diffstat (limited to 'lldb/source')
-rw-r--r-- | lldb/source/Commands/CommandObjectTarget.cpp | 22 | ||||
-rw-r--r-- | lldb/source/Commands/Options.td | 2 | ||||
-rw-r--r-- | lldb/source/Symbol/UnwindTable.cpp | 3 |
3 files changed, 23 insertions, 4 deletions
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp index d0092c2..da50fe0 100644 --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -3474,6 +3474,17 @@ public: m_type = eLookupTypeFunctionOrSymbol; break; + case 'c': + bool value, success; + value = OptionArgParser::ToBoolean(option_arg, false, &success); + if (success) { + m_cached = value; + } else { + return Status::FromErrorStringWithFormatv( + "invalid boolean value '%s' passed for -c option", option_arg); + } + break; + default: llvm_unreachable("Unimplemented option"); } @@ -3485,6 +3496,7 @@ public: m_type = eLookupTypeInvalid; m_str.clear(); m_addr = LLDB_INVALID_ADDRESS; + m_cached = false; } llvm::ArrayRef<OptionDefinition> GetDefinitions() override { @@ -3497,6 +3509,7 @@ public: // parsing options std::string m_str; // Holds name lookup lldb::addr_t m_addr = LLDB_INVALID_ADDRESS; // Holds the address to lookup + bool m_cached = true; }; CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter) @@ -3583,9 +3596,12 @@ protected: if (abi) start_addr = abi->FixCodeAddress(start_addr); - FuncUnwindersSP func_unwinders_sp( - sc.module_sp->GetUnwindTable() - .GetUncachedFuncUnwindersContainingAddress(start_addr, sc)); + UnwindTable &uw_table = sc.module_sp->GetUnwindTable(); + FuncUnwindersSP func_unwinders_sp = + m_options.m_cached + ? uw_table.GetFuncUnwindersContainingAddress(start_addr, sc) + : uw_table.GetUncachedFuncUnwindersContainingAddress(start_addr, + sc); if (!func_unwinders_sp) continue; diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 777f8c3..8831fed 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -965,6 +965,8 @@ let Command = "target modules show unwind" in { def target_modules_show_unwind_address : Option<"address", "a">, Group<2>, Arg<"AddressOrExpression">, Desc<"Show unwind instructions for a function " "or symbol containing an address">; + def target_modules_show_unwind_cached : Option<"cached", "c">, + Arg<"Boolean">, Desc<"Show cached unwind information">; } let Command = "target modules lookup" in { diff --git a/lldb/source/Symbol/UnwindTable.cpp b/lldb/source/Symbol/UnwindTable.cpp index da88b0c..61d5119 100644 --- a/lldb/source/Symbol/UnwindTable.cpp +++ b/lldb/source/Symbol/UnwindTable.cpp @@ -86,6 +86,7 @@ void UnwindTable::Initialize() { void UnwindTable::ModuleWasUpdated() { std::lock_guard<std::mutex> guard(m_mutex); m_scanned_all_unwind_sources = false; + m_unwinds.clear(); } UnwindTable::~UnwindTable() = default; @@ -118,7 +119,7 @@ UnwindTable::GetAddressRange(const Address &addr, const SymbolContext &sc) { FuncUnwindersSP UnwindTable::GetFuncUnwindersContainingAddress(const Address &addr, - SymbolContext &sc) { + const SymbolContext &sc) { Initialize(); std::lock_guard<std::mutex> guard(m_mutex); |