[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