[Lldb-commits] [lldb] r118142 - in /lldb/trunk: include/lldb/Target/ThreadPlanCallFunction.h source/Target/ThreadPlanCallFunction.cpp

Sean Callanan scallanan at apple.com
Tue Nov 2 18:37:53 PDT 2010


Author: spyffe
Date: Tue Nov  2 20:37:52 2010
New Revision: 118142

URL: http://llvm.org/viewvc/llvm-project?rev=118142&view=rev
Log:
Modified the thread plan that calls functions to
set breakpoints at the different locations where
an exception could be thrown, so that exceptions
thrown by expressions are properly caught.

Modified:
    lldb/trunk/include/lldb/Target/ThreadPlanCallFunction.h
    lldb/trunk/source/Target/ThreadPlanCallFunction.cpp

Modified: lldb/trunk/include/lldb/Target/ThreadPlanCallFunction.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanCallFunction.h?rev=118142&r1=118141&r2=118142&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanCallFunction.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlanCallFunction.h Tue Nov  2 20:37:52 2010
@@ -77,6 +77,12 @@
 
 protected:
 private:
+    void
+    SetBreakpoints ();
+    
+    void
+    ClearBreakpoints ();
+    
     bool                                            m_use_abi;
     bool                                            m_valid;
     bool                                            m_stop_other_threads;
@@ -88,6 +94,9 @@
     Thread                                         &m_thread;
     Thread::RegisterCheckpoint                      m_register_backup;
     lldb::ThreadPlanSP                              m_subplan_sp;
+    lldb::BreakpointSP                              m_cxx_exception_bp_sp;
+    lldb::BreakpointSP                              m_cxx_exception_alloc_bp_sp;
+    lldb::BreakpointSP                              m_objc_exception_bp_sp;
 
     DISALLOW_COPY_AND_ASSIGN (ThreadPlanCallFunction);
 };

Modified: lldb/trunk/source/Target/ThreadPlanCallFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanCallFunction.cpp?rev=118142&r1=118141&r2=118142&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanCallFunction.cpp (original)
+++ lldb/trunk/source/Target/ThreadPlanCallFunction.cpp Tue Nov  2 20:37:52 2010
@@ -12,6 +12,7 @@
 // C Includes
 // C++ Includes
 // Other libraries and framework includes
+#include "llvm/Support/MachO.h"
 // Project includes
 #include "lldb/lldb-private-log.h"
 #include "lldb/Breakpoint/Breakpoint.h"
@@ -52,10 +53,12 @@
     Process& process = thread.GetProcess();
     Target& target = process.GetTarget();
     const ABI *abi = process.GetABI();
-
+    
     if (!abi)
         return;
-
+    
+    SetBreakpoints();
+    
     lldb::addr_t spBelowRedZone = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize();
     
     SymbolContextList contexts;
@@ -111,6 +114,8 @@
     if(!abi)
         return;
     
+    SetBreakpoints();
+    
     lldb::addr_t spBelowRedZone = thread.GetRegisterContext()->GetSP() - abi->GetRedZoneSize();
     
     SymbolContextList contexts;
@@ -173,7 +178,7 @@
 
 bool
 ThreadPlanCallFunction::PlanExplainsStop ()
-{
+{    
     // If our subplan knows why we stopped, even if it's done (which would forward the question to us)
     // we answer yes.
     if(m_subplan_sp.get() != NULL && m_subplan_sp->PlanExplainsStop())
@@ -186,6 +191,7 @@
     // Otherwise, check the case where we stopped for an internal breakpoint, in that case, continue on.
     // If it is not an internal breakpoint, consult OkayToDiscard.
     lldb::StopInfoSP stop_info_sp = GetPrivateStopReason();
+    
     if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonBreakpoint)
     {
         uint64_t break_site_id = stop_info_sp->GetValue();
@@ -196,7 +202,24 @@
             bool is_internal = true;
             for (uint32_t i = 0; i < num_owners; i++)
             {
-                if (!bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().IsInternal())
+                Breakpoint &bp = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint();
+                break_id_t bid = bp.GetID();
+                
+                // Check if the breakpoint is one of ours.
+                
+                if (m_cxx_exception_bp_sp.get() &&
+                    bid == m_cxx_exception_bp_sp->GetID())
+                    return true;
+                
+                if (m_cxx_exception_alloc_bp_sp.get() &&
+                    bid == m_cxx_exception_alloc_bp_sp->GetID())
+                    return true;
+                
+                if (m_objc_exception_bp_sp.get() &&
+                    bid == m_objc_exception_bp_sp->GetID())
+                    return true;
+                
+                if (!bp.IsInternal())
                 {
                     is_internal = false;
                     break;
@@ -242,6 +265,8 @@
         m_thread.RestoreSaveFrameZero(m_register_backup);
         m_thread.ClearStackFrames();
         SetPlanComplete();
+        
+        ClearBreakpoints();
         return true;
     }
     else
@@ -309,3 +334,67 @@
         return false;
     }
 }
+
+void
+ThreadPlanCallFunction::SetBreakpoints ()
+{
+    Target& target = m_process.GetTarget();
+    
+    ArchSpec arch_spec = target.GetArchitecture();
+    
+    // A temporary fix to set breakpoints at points where exceptions are being
+    // thrown.  This functionality will migrate into the Target.
+    switch (arch_spec.GetCPUType())
+    {
+    default:
+        break;
+    case llvm::MachO::CPUTypeI386:
+        m_cxx_exception_bp_sp = target.CreateBreakpoint (NULL,
+                                                       "__cxa_throw",
+                                                       eFunctionNameTypeBase, 
+                                                       true);
+        m_cxx_exception_alloc_bp_sp = target.CreateBreakpoint (NULL,
+                                                             "__cxa_allocate",
+                                                             eFunctionNameTypeBase,
+                                                             true);
+        m_objc_exception_bp_sp = target.CreateBreakpoint (NULL,
+                                                        "objc_exception_throw",
+                                                        eFunctionNameTypeBase,
+                                                        true);
+        break;
+    case llvm::MachO::CPUTypeX86_64:
+        m_cxx_exception_bp_sp = target.CreateBreakpoint (NULL,
+                                                       "__cxa_throw",
+                                                       eFunctionNameTypeBase, 
+                                                       true);
+        m_cxx_exception_alloc_bp_sp = target.CreateBreakpoint (NULL,
+                                                             "__cxa_allocate",
+                                                             eFunctionNameTypeBase,
+                                                             true);
+        break;
+    }
+}
+
+void
+ThreadPlanCallFunction::ClearBreakpoints ()
+{
+    Target& target = m_process.GetTarget();
+    
+    if (m_cxx_exception_bp_sp.get())
+    {
+        target.RemoveBreakpointByID(m_cxx_exception_bp_sp->GetID());
+        m_cxx_exception_bp_sp.reset();
+    }
+    
+    if (m_cxx_exception_alloc_bp_sp.get())
+    {
+        target.RemoveBreakpointByID(m_cxx_exception_alloc_bp_sp->GetID());
+        m_cxx_exception_bp_sp.reset();
+    }
+    
+    if (m_objc_exception_bp_sp.get())
+    {
+        target.RemoveBreakpointByID(m_objc_exception_bp_sp->GetID());
+        m_cxx_exception_bp_sp.reset();
+    }
+}





More information about the lldb-commits mailing list