[Lldb-commits] [PATCH] D86417: [lldb] do not propagate eTrapHandlerFrame repeatedly
Luboš Luňák via Phabricator via lldb-commits
lldb-commits at lists.llvm.org
Tue Aug 25 08:49:33 PDT 2020
llunak added a comment.
In D86417#2236337 <https://reviews.llvm.org/D86417#2236337>, @JosephTremoulet wrote:
>> And its parent 'raise' is set so as well because of 'GetNextFrame()->m_frame_type == eTrapHandlerFrame '.
>
> Sorry, can you clarify what code path you're referring to here? I see two occurrences of `GetNextFrame()->m_frame_type == eTrapHandlerFrame` in the code, and three occurrences of `m_frame_type = eTrapHandlerFrame`, but it's not clear how one of the former leads to one of the latter, or if I'm misunderstanding what you're saying.
The one in RegisterContextUnwind::GetFullUnwindPlanForFrame(). It sets behaves_like_zeroth_frame, which in turn leads to executing the if() block later down in the function.
After applying the following patch
diff --git a/lldb/source/Target/RegisterContextUnwind.cpp b/lldb/source/Target/RegisterContextUnwind.cpp
index cf9336857ba..1de27ca764e 100644
--- a/lldb/source/Target/RegisterContextUnwind.cpp
+++ b/lldb/source/Target/RegisterContextUnwind.cpp
@@ -1,3 +1,4 @@
+#include <iostream>
//===-- RegisterContextUnwind.cpp -----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -263,6 +264,7 @@ void RegisterContextUnwind::InitializeZerothFrame() {
// RegisterContextUnwind "below" it to provide things like its current pc value.
void RegisterContextUnwind::InitializeNonZerothFrame() {
+ std::cerr << __PRETTY_FUNCTION__ << ":" << GetSymbolOrFunctionName(m_sym_ctx).AsCString("") << std::endl;
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
if (IsFrameZero()) {
m_frame_type = eNotAValidFrame;
@@ -637,6 +639,7 @@ bool RegisterContextUnwind::IsFrameZero() const { return m_frame_number == 0; }
// the function, maybe backed up by 1, -1 if unknown
UnwindPlanSP RegisterContextUnwind::GetFastUnwindPlanForFrame() {
+ std::cerr << __PRETTY_FUNCTION__ << ":" << GetSymbolOrFunctionName(m_sym_ctx).AsCString("") << std::endl;
UnwindPlanSP unwind_plan_sp;
ModuleSP pc_module_sp(m_current_pc.GetModule());
@@ -689,6 +692,7 @@ UnwindPlanSP RegisterContextUnwind::GetFastUnwindPlanForFrame() {
// the function, maybe backed up by 1, -1 if unknown
UnwindPlanSP RegisterContextUnwind::GetFullUnwindPlanForFrame() {
+ std::cerr << __PRETTY_FUNCTION__ << ":" << GetSymbolOrFunctionName(m_sym_ctx).AsCString("") << std::endl;
UnwindPlanSP unwind_plan_sp;
UnwindPlanSP arch_default_unwind_plan_sp;
ExecutionContext exe_ctx(m_thread.shared_from_this());
@@ -1763,6 +1767,7 @@ bool RegisterContextUnwind::ForceSwitchToFallbackUnwindPlan() {
void RegisterContextUnwind::PropagateTrapHandlerFlagFromUnwindPlan(
lldb::UnwindPlanSP unwind_plan) {
+ std::cerr << __PRETTY_FUNCTION__ << ":" << GetSymbolOrFunctionName(m_sym_ctx).AsCString("") << std::endl;
if (unwind_plan->GetUnwindPlanForSignalTrap() != eLazyBoolYes) {
// Unwind plan does not indicate trap handler. Do nothing. We may
// already be flagged as trap handler flag due to the symbol being
@@ -1775,6 +1780,7 @@ void RegisterContextUnwind::PropagateTrapHandlerFlagFromUnwindPlan(
}
m_frame_type = eTrapHandlerFrame;
+ std::cerr << "SET:" << GetSymbolOrFunctionName(m_sym_ctx).AsCString("") << std::endl;
if (m_current_offset_backed_up_one != m_current_offset) {
// We backed up the pc by 1 to compute the symbol context, but
and then executing manually what TestHandleAbort.py does directly in lldb, then doing the 'bt' command when the breakpoint at "Set a breakpoint here" results in this output:
(lldb) bt
void lldb_private::RegisterContextUnwind::InitializeNonZerothFrame():
lldb::UnwindPlanSP lldb_private::RegisterContextUnwind::GetFastUnwindPlanForFrame():__restore_rt
lldb::UnwindPlanSP lldb_private::RegisterContextUnwind::GetFullUnwindPlanForFrame():__restore_rt
void lldb_private::RegisterContextUnwind::PropagateTrapHandlerFlagFromUnwindPlan(lldb::UnwindPlanSP):__restore_rt
void lldb_private::RegisterContextUnwind::InitializeNonZerothFrame():
lldb::UnwindPlanSP lldb_private::RegisterContextUnwind::GetFastUnwindPlanForFrame():raise
lldb::UnwindPlanSP lldb_private::RegisterContextUnwind::GetFullUnwindPlanForFrame():raise
void lldb_private::RegisterContextUnwind::PropagateTrapHandlerFlagFromUnwindPlan(lldb::UnwindPlanSP):raise
SET:raise
void lldb_private::RegisterContextUnwind::InitializeNonZerothFrame():
lldb::UnwindPlanSP lldb_private::RegisterContextUnwind::GetFastUnwindPlanForFrame():abort
lldb::UnwindPlanSP lldb_private::RegisterContextUnwind::GetFullUnwindPlanForFrame():abort
void lldb_private::RegisterContextUnwind::PropagateTrapHandlerFlagFromUnwindPlan(lldb::UnwindPlanSP):abort
SET:abort
void lldb_private::RegisterContextUnwind::InitializeNonZerothFrame():
lldb::UnwindPlanSP lldb_private::RegisterContextUnwind::GetFastUnwindPlanForFrame():abort_caller
void lldb_private::RegisterContextUnwind::PropagateTrapHandlerFlagFromUnwindPlan(lldb::UnwindPlanSP):abort_caller
void lldb_private::RegisterContextUnwind::InitializeNonZerothFrame():
lldb::UnwindPlanSP lldb_private::RegisterContextUnwind::GetFastUnwindPlanForFrame():main
void lldb_private::RegisterContextUnwind::PropagateTrapHandlerFlagFromUnwindPlan(lldb::UnwindPlanSP):main
void lldb_private::RegisterContextUnwind::InitializeNonZerothFrame():
lldb::UnwindPlanSP lldb_private::RegisterContextUnwind::GetFastUnwindPlanForFrame():__libc_start_main
lldb::UnwindPlanSP lldb_private::RegisterContextUnwind::GetFullUnwindPlanForFrame():__libc_start_main
void lldb_private::RegisterContextUnwind::PropagateTrapHandlerFlagFromUnwindPlan(lldb::UnwindPlanSP):__libc_start_main
void lldb_private::RegisterContextUnwind::InitializeNonZerothFrame():
lldb::UnwindPlanSP lldb_private::RegisterContextUnwind::GetFastUnwindPlanForFrame():_start
lldb::UnwindPlanSP lldb_private::RegisterContextUnwind::GetFullUnwindPlanForFrame():_start
void lldb_private::RegisterContextUnwind::PropagateTrapHandlerFlagFromUnwindPlan(lldb::UnwindPlanSP):_start
void lldb_private::RegisterContextUnwind::InitializeNonZerothFrame():
void lldb_private::RegisterContextUnwind::InitializeNonZerothFrame():
* thread #1, name = 'a.out', stop reason = breakpoint 1.1
* frame #0: 0x00000000004006bb a.out`handler(sig=6) at main.c:7:5
frame #1: 0x00007ffff7a555a0 libc.so.6`__restore_rt
frame #2: 0x00007ffff7a55520 libc.so.6`raise + 272
frame #3: 0x00007ffff7a56b01 libc.so.6`abort + 337
frame #4: 0x00000000004006e9 a.out at main.c:12:5
frame #5: 0x0000000000400743 a.out`main at main.c:23:5
frame #6: 0x00007ffff7a4034a libc.so.6`__libc_start_main + 234
frame #7: 0x00000000004005fa a.out`_start at start.S:120
For raise and abort, GetFastUnwindPlanForFrame() returns nullptr, which leads to calling GetFullUnwindPlanForFrame(), which triggers the behaves_like_zeroth_frame path, which leads to returning an unwind plan with GetUnwindPlanForSignalTrap() set to yes, which leads to propagating eTrapHandlerFrame in PropagateTrapHandlerFlagFromUnwindPlan(). Which leads to getting the symbol for abort_handler() wrong. At least that's my understanding. I have no idea why it's broken for me and (apparently) it works for everybody else.
Repository:
rLLDB LLDB
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D86417/new/
https://reviews.llvm.org/D86417
More information about the lldb-commits
mailing list