[Lldb-commits] [lldb] r201300 - The Platform base class now maintains a list of trap handlers

Jason Molenda jmolenda at apple.com
Wed Feb 12 23:11:08 PST 2014


Author: jmolenda
Date: Thu Feb 13 01:11:08 2014
New Revision: 201300

URL: http://llvm.org/viewvc/llvm-project?rev=201300&view=rev
Log:
The Platform base class now maintains a list of trap handlers
aka asynchronous signal handlers, which subclasses should fill
in as appropriate.  For most Unix user process environments,
the one entry in this list is _sigtramp.  For bare-board and
kernel environments, there will be different sets of trap 
handlers.

The unwinder needs to know when a frame is a trap handler 
because the rules it enforces for the frame "above" the
trap handler is different from most middle-of-the-stack frames.

<rdar://problem/15835846> 

Modified:
    lldb/trunk/include/lldb/Target/Platform.h
    lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
    lldb/trunk/source/Plugins/Platform/Linux/PlatformLinux.cpp
    lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
    lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
    lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
    lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
    lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h
    lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp
    lldb/trunk/source/Target/Platform.cpp

Modified: lldb/trunk/include/lldb/Target/Platform.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Platform.h?rev=201300&r1=201299&r2=201300&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Platform.h (original)
+++ lldb/trunk/include/lldb/Target/Platform.h Thu Feb 13 01:11:08 2014
@@ -835,6 +835,32 @@ namespace lldb_private {
             return LLDB_INVALID_QUEUE_ID;
         }
 
+        //------------------------------------------------------------------
+        /// Provide a list of trap handler function names for this platform
+        ///
+        /// The unwinder needs to treat trap handlers specially -- the stack
+        /// frame may not be aligned correctly for a trap handler (the kernel
+        /// often won't perturb the stack pointer, or won't re-align it properly,
+        /// in the process of calling the handler) and the frame above the handler
+        /// needs to be treated by the unwinder's "frame 0" rules instead of its
+        /// "middle of the stack frame" rules.
+        /// 
+        /// In a user process debugging scenario, the list of trap handlers is
+        /// typically just "_sigtramp".
+        ///
+        /// The Platform base class provides the m_trap_handlers ivar but it does
+        /// not populate it.  Subclasses should add the names of the asynchronous
+        /// signal handler routines as needed.  For most Unix platforms, add _sigtramp.
+        ///
+        /// @return
+        ///     A list of symbol names.  The list may be empty.
+        //------------------------------------------------------------------
+        virtual const std::vector<ConstString> &
+        GetTrapHandlerSymbolNames ()
+        {
+            return m_trap_handlers;
+        }
+
     protected:
         bool m_is_host;
         // Set to true when we are able to actually set the OS version while 
@@ -867,6 +893,7 @@ namespace lldb_private {
         std::string m_ssh_opts;
         bool m_ignores_remote_hostname;
         std::string m_local_cache_directory;
+        std::vector<ConstString> m_trap_handlers;
 
         const char *
         GetCachedUserName (uint32_t uid)
@@ -1115,7 +1142,9 @@ namespace lldb_private {
         
         bool m_ssh;
         std::string m_ssh_opts;
+
     private:
+
         DISALLOW_COPY_AND_ASSIGN(OptionGroupPlatformSSH);
     };
     

Modified: lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp?rev=201300&r1=201299&r2=201300&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp Thu Feb 13 01:11:08 2014
@@ -142,8 +142,10 @@ PlatformFreeBSD::Terminate ()
 /// Default Constructor
 //------------------------------------------------------------------
 PlatformFreeBSD::PlatformFreeBSD (bool is_host) :
-Platform(is_host)
+Platform(is_host),
+m_remote_platform_sp()
 {
+    m_trap_handlers.push_back (ConstString ("_sigtramp"));
 }
 
 //------------------------------------------------------------------

Modified: lldb/trunk/source/Plugins/Platform/Linux/PlatformLinux.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/Linux/PlatformLinux.cpp?rev=201300&r1=201299&r2=201300&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/Linux/PlatformLinux.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/Linux/PlatformLinux.cpp Thu Feb 13 01:11:08 2014
@@ -307,6 +307,7 @@ PlatformLinux::PlatformLinux (bool is_ho
     Platform(is_host),  // This is the local host platform
     m_remote_platform_sp ()
 {
+    m_trap_handlers.push_back (ConstString ("_sigtramp"));
 }
 
 //------------------------------------------------------------------

Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp?rev=201300&r1=201299&r2=201300&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp Thu Feb 13 01:11:08 2014
@@ -40,6 +40,7 @@ PlatformDarwin::PlatformDarwin (bool is_
     PlatformPOSIX(is_host),  // This is the local host platform
     m_developer_directory ()
 {
+    m_trap_handlers.push_back (ConstString ("_sigtramp"));
 }
 
 //------------------------------------------------------------------

Modified: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp?rev=201300&r1=201299&r2=201300&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformDarwinKernel.cpp Thu Feb 13 01:11:08 2014
@@ -257,6 +257,8 @@ PlatformDarwinKernel::PlatformDarwinKern
     {
         SearchForKexts ();
     }
+    m_trap_handlers.push_back(ConstString ("trap_from_kernel"));
+    m_trap_handlers.push_back(ConstString ("hndl_double_fault"));
 }
 
 //------------------------------------------------------------------

Modified: lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp?rev=201300&r1=201299&r2=201300&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp Thu Feb 13 01:11:08 2014
@@ -32,6 +32,7 @@ PlatformPOSIX::PlatformPOSIX (bool is_ho
 Platform(is_host),  // This is the local host platform
 m_remote_platform_sp ()
 {
+    m_trap_handlers.push_back (ConstString ("_sigtramp"));
 }
 
 //------------------------------------------------------------------

Modified: lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp?rev=201300&r1=201299&r2=201300&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp Thu Feb 13 01:11:08 2014
@@ -135,6 +135,7 @@ PlatformRemoteGDBServer::PlatformRemoteG
     Platform(false), // This is a remote platform
     m_gdb_client(true)
 {
+    m_trap_handlers.push_back (ConstString ("_sigtramp"));
 }
 
 //------------------------------------------------------------------

Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp?rev=201300&r1=201299&r2=201300&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp Thu Feb 13 01:11:08 2014
@@ -21,16 +21,17 @@
 #include "lldb/Symbol/FuncUnwinders.h"
 #include "lldb/Symbol/Function.h"
 #include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Symbol/SymbolContext.h"
 #include "lldb/Symbol/Symbol.h"
+#include "lldb/Symbol/SymbolContext.h"
 #include "lldb/Target/ABI.h"
+#include "lldb/Target/DynamicLoader.h"
 #include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Platform.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/SectionLoadList.h"
 #include "lldb/Target/StackFrame.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/Thread.h"
-#include "lldb/Target/DynamicLoader.h"
 
 #include "RegisterContextLLDB.h"
 
@@ -76,7 +77,7 @@ RegisterContextLLDB::RegisterContextLLDB
 
     // This same code exists over in the GetFullUnwindPlanForFrame() but it may not have been executed yet
     if (IsFrameZero()
-        || next_frame->m_frame_type == eSigtrampFrame
+        || next_frame->m_frame_type == eTrapHandlerFrame
         || next_frame->m_frame_type == eDebuggerFrame)
     {
         m_all_registers_available = true;
@@ -171,17 +172,21 @@ RegisterContextLLDB::InitializeZerothFra
     AddressRange addr_range;
     m_sym_ctx.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, addr_range);
 
-    static ConstString g_sigtramp_name ("_sigtramp");
-    if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == g_sigtramp_name) ||
-        (m_sym_ctx.symbol   && m_sym_ctx.symbol->GetName()   == g_sigtramp_name))
+    m_frame_type = eNormalFrame;
+    PlatformSP platform_sp (process->GetTarget().GetPlatform());
+    if (platform_sp)
     {
-        m_frame_type = eSigtrampFrame;
-    }
-    else
-    {
-        // FIXME:  Detect eDebuggerFrame here.
-        m_frame_type = eNormalFrame;
+        const std::vector<ConstString> trap_handler_names (platform_sp->GetTrapHandlerSymbolNames());
+        for (ConstString name : trap_handler_names)
+        {
+            if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == name) ||
+                (m_sym_ctx.symbol   && m_sym_ctx.symbol->GetName()   == name))
+            {
+                m_frame_type = eTrapHandlerFrame;
+            }
+        }
     }
+    // FIXME:  Detect eDebuggerFrame here.
 
     // If we were able to find a symbol/function, set addr_range to the bounds of that symbol/function.
     // else treat the current pc value as the start_pc and record no offset.
@@ -442,7 +447,7 @@ RegisterContextLLDB::InitializeNonZeroth
     // Or if we're in the middle of the stack (and not "above" an asynchronous event like sigtramp),
     // and our "current" pc is the start of a function...
     if (m_sym_ctx_valid
-        && GetNextFrame()->m_frame_type != eSigtrampFrame
+        && GetNextFrame()->m_frame_type != eTrapHandlerFrame
         && GetNextFrame()->m_frame_type != eDebuggerFrame
         && addr_range.GetBaseAddress().IsValid()
         && addr_range.GetBaseAddress().GetSection() == m_current_pc.GetSection()
@@ -492,20 +497,25 @@ RegisterContextLLDB::InitializeNonZeroth
         m_current_offset_backed_up_one = -1;
     }
 
-    static ConstString sigtramp_name ("_sigtramp");
-    if ((m_sym_ctx.function && m_sym_ctx.function->GetMangled().GetMangledName() == sigtramp_name)
-        || (m_sym_ctx.symbol && m_sym_ctx.symbol->GetMangled().GetMangledName() == sigtramp_name))
+    if (m_frame_type != eSkipFrame) // don't override eSkipFrame
     {
-        m_frame_type = eSigtrampFrame;
+        m_frame_type = eNormalFrame;
     }
-    else
+    PlatformSP platform_sp (process->GetTarget().GetPlatform());
+    if (platform_sp)
     {
-        // FIXME:  Detect eDebuggerFrame here.
-        if (m_frame_type != eSkipFrame) // don't override eSkipFrame
+        const std::vector<ConstString> trap_handler_names (platform_sp->GetTrapHandlerSymbolNames());
+        for (ConstString name : trap_handler_names)
         {
-            m_frame_type = eNormalFrame;
+            if ((m_sym_ctx.function && m_sym_ctx.function->GetName() == name) ||
+                (m_sym_ctx.symbol   && m_sym_ctx.symbol->GetName()   == name))
+            {
+                m_frame_type = eTrapHandlerFrame;
+            }
         }
     }
+    // FIXME:  Detect eDebuggerFrame here.
+
 
     // We've set m_frame_type and m_sym_ctx before this call.
     m_fast_unwind_plan_sp = GetFastUnwindPlanForFrame ();
@@ -617,7 +627,7 @@ RegisterContextLLDB::IsFrameZero () cons
 //
 // On entry to this method,
 //
-//   1. m_frame_type should already be set to eSigtrampFrame/eDebuggerFrame if either of those are correct,
+//   1. m_frame_type should already be set to eTrapHandlerFrame/eDebuggerFrame if either of those are correct,
 //   2. m_sym_ctx should already be filled in, and
 //   3. m_current_pc should have the current pc value for this frame
 //   4. m_current_offset_backed_up_one should have the current byte offset into the function, maybe backed up by 1, -1 if unknown
@@ -639,7 +649,7 @@ RegisterContextLLDB::GetFastUnwindPlanFo
         return unwind_plan_sp;
 
     // If we're in _sigtramp(), unwinding past this frame requires special knowledge.
-    if (m_frame_type == eSigtrampFrame || m_frame_type == eDebuggerFrame)
+    if (m_frame_type == eTrapHandlerFrame || m_frame_type == eDebuggerFrame)
         return unwind_plan_sp;
 
     unwind_plan_sp = func_unwinders_sp->GetUnwindPlanFastUnwind (m_thread);
@@ -668,7 +678,7 @@ RegisterContextLLDB::GetFastUnwindPlanFo
 
 // On entry to this method,
 //
-//   1. m_frame_type should already be set to eSigtrampFrame/eDebuggerFrame if either of those are correct,
+//   1. m_frame_type should already be set to eTrapHandlerFrame/eDebuggerFrame if either of those are correct,
 //   2. m_sym_ctx should already be filled in, and
 //   3. m_current_pc should have the current pc value for this frame
 //   4. m_current_offset_backed_up_one should have the current byte offset into the function, maybe backed up by 1, -1 if unknown
@@ -693,7 +703,7 @@ RegisterContextLLDB::GetFullUnwindPlanFo
 
     bool behaves_like_zeroth_frame = false;
     if (IsFrameZero ()
-        || GetNextFrame()->m_frame_type == eSigtrampFrame
+        || GetNextFrame()->m_frame_type == eTrapHandlerFrame
         || GetNextFrame()->m_frame_type == eDebuggerFrame)
     {
         behaves_like_zeroth_frame = true;
@@ -763,7 +773,7 @@ RegisterContextLLDB::GetFullUnwindPlanFo
     // is properly encoded in the eh_frame section, so prefer that if available.
     // On other platforms we may need to provide a platform-specific UnwindPlan which encodes the details of
     // how to unwind out of sigtramp.
-    if (m_frame_type == eSigtrampFrame)
+    if (m_frame_type == eTrapHandlerFrame)
     {
         m_fast_unwind_plan_sp.reset();
         unwind_plan_sp = func_unwinders_sp->GetUnwindPlanAtCallSite (m_current_offset_backed_up_one);
@@ -983,9 +993,9 @@ RegisterContextLLDB::IsValid () const
 }
 
 bool
-RegisterContextLLDB::IsSigtrampFrame () const
+RegisterContextLLDB::IsTrapHandlerFrame () const
 {
-    return m_frame_type == eSigtrampFrame;
+    return m_frame_type == eTrapHandlerFrame;
 }
 
 // A skip frame is a bogus frame on the stack -- but one where we're likely to find a real frame farther

Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h?rev=201300&r1=201299&r2=201300&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.h Thu Feb 13 01:11:08 2014
@@ -73,7 +73,7 @@ public:
     IsValid () const;
 
     bool
-    IsSigtrampFrame () const;
+    IsTrapHandlerFrame () const;
 
     bool
     GetCFA (lldb::addr_t& cfa);
@@ -89,7 +89,7 @@ private:
     enum FrameType
     {
         eNormalFrame,
-        eSigtrampFrame,
+        eTrapHandlerFrame,
         eDebuggerFrame,  // a debugger inferior function call frame; we get caller's registers from debugger
         eSkipFrame,      // The unwind resulted in a bogus frame but may get back on track so we don't want to give up yet
         eNotAValidFrame  // this frame is invalid for some reason - most likely it is past the top (end) of the stack

Modified: lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp?rev=201300&r1=201299&r2=201300&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/UnwindLLDB.cpp Thu Feb 13 01:11:08 2014
@@ -174,7 +174,7 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi)
         // On Mac OS X, the _sigtramp asynchronous signal trampoline frame may not have
         // its (constructed) CFA aligned correctly -- don't do the abi alignment check for
         // these.
-        if (reg_ctx_sp->IsSigtrampFrame() == false)
+        if (reg_ctx_sp->IsTrapHandlerFrame() == false)
         {
             if (log)
             {

Modified: lldb/trunk/source/Target/Platform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Platform.cpp?rev=201300&r1=201299&r2=201300&view=diff
==============================================================================
--- lldb/trunk/source/Target/Platform.cpp (original)
+++ lldb/trunk/source/Target/Platform.cpp Thu Feb 13 01:11:08 2014
@@ -255,7 +255,8 @@ Platform::Platform (bool is_host) :
     m_rsync_prefix (),
     m_supports_ssh (false),
     m_ssh_opts (),
-    m_ignores_remote_hostname (false)
+    m_ignores_remote_hostname (false),
+    m_trap_handlers()
 {
     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
     if (log)





More information about the lldb-commits mailing list