[Lldb-commits] [lldb] r139274 - in /lldb/trunk/tools/debugserver/source/MacOSX: i386/DNBArchImplI386.cpp i386/DNBArchImplI386.h x86_64/DNBArchImplX86_64.cpp x86_64/DNBArchImplX86_64.h

Johnny Chen johnny.chen at apple.com
Wed Sep 7 18:16:50 PDT 2011


Author: johnny
Date: Wed Sep  7 20:16:50 2011
New Revision: 139274

URL: http://llvm.org/viewvc/llvm-project?rev=139274&view=rev
Log:
Add logic to the DNBArchImplX86_64/DNBArchImplI386::NotifyException() callback method
in order to distinguish the real single step exception from a watchpoint exception
which uses the same exc_type of EXC_BREAKPOINT and exc_code of EXC_I386_SGL.

This is done by checking the debug status register to find out whether the watchpoint
data break event has fired, and, if yes, stuff the data break address into the exception's
exc_sub_code field on the debugserver side for lldb to consume on the other end.

Modified:
    lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h
    lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
    lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h

Modified: lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp?rev=139274&r1=139273&r2=139274&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp Wed Sep  7 20:16:50 2011
@@ -625,6 +625,19 @@
                 return true;
             }
         }
+        else if (exc.exc_data.size() >= 2 && exc.exc_data[0] == 1)
+        {
+            // exc_code = EXC_I386_SGL
+            //
+            // Check whether this corresponds to a watchpoint hit event.
+            // If yes, set the exc_sub_code to the data break address.
+            nub_addr_t addr = 0;
+            uint32_t hw_index = GetHardwareWatchpointHit(addr);
+            if (hw_index != INVALID_NUB_HW_INDEX)
+                exc.exc_data[1] = addr;
+
+            return true;
+        }
         break;
     case EXC_SYSCALL:
         break;
@@ -636,29 +649,6 @@
     return false;
 }
 
-// Iterate through the debug status register; return the index of the first hit.
-uint32_t
-DNBArchImplI386::GetHardwareWatchpointHit()
-{
-    // Read the debug state
-    kern_return_t kret = GetDBGState(false);
-    DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::GetHardwareWatchpointHit() GetDBGState() => 0x%8.8x.", kret);
-    if (kret == KERN_SUCCESS)
-    {
-        DBG debug_state = m_state.context.dbg;
-        uint32_t i, num = NumSupportedHardwareWatchpoints();
-        for (i = 0; i < num; ++i)
-        {
-            if (IsWatchpointHit(debug_state, i))
-            {
-                DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::GetHardwareWatchpointHit() found => %u.", i);
-                return i;
-            }
-        }
-    }
-    return INVALID_NUB_HW_INDEX;
-}
-
 uint32_t
 DNBArchImplI386::NumSupportedHardwareWatchpoints()
 {
@@ -790,6 +780,23 @@
     return (debug_state.__dr6 & (1 << hw_index));
 }
 
+nub_addr_t
+DNBArchImplI386::GetWatchAddress(const DBG &debug_state, uint32_t hw_index)
+{
+    switch (hw_index) {
+    case 0:
+        return debug_state.__dr0;
+    case 1:
+        return debug_state.__dr1;
+    case 2:
+        return debug_state.__dr2;
+    case 3:
+        return debug_state.__dr3;
+    default:
+        assert(0 && "invalid hardware register index, must be one of 0, 1, 2, or 3");
+    }
+}
+
 uint32_t
 DNBArchImplI386::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write)
 {
@@ -865,6 +872,32 @@
     return false;
 }
 
+// Iterate through the debug status register; return the index of the first hit.
+uint32_t
+DNBArchImplI386::GetHardwareWatchpointHit(nub_addr_t &addr)
+{
+    // Read the debug state
+    kern_return_t kret = GetDBGState(false);
+    DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::GetHardwareWatchpointHit() GetDBGState() => 0x%8.8x.", kret);
+    if (kret == KERN_SUCCESS)
+    {
+        DBG debug_state = m_state.context.dbg;
+        uint32_t i, num = NumSupportedHardwareWatchpoints();
+        for (i = 0; i < num; ++i)
+        {
+            if (IsWatchpointHit(debug_state, i))
+            {
+                addr = GetWatchAddress(debug_state, i);
+                DNBLogThreadedIf(LOG_WATCHPOINTS,
+                                 "DNBArchImplI386::GetHardwareWatchpointHit() found => %u (addr = %8.8p).",
+                                 i, addr);
+                return i;
+            }
+        }
+    }
+    return INVALID_NUB_HW_INDEX;
+}
+
 // Set the single step bit in the processor status register.
 kern_return_t
 DNBArchImplI386::EnableHardwareSingleStep (bool enable)

Modified: lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h?rev=139274&r1=139273&r2=139274&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h Wed Sep  7 20:16:50 2011
@@ -54,7 +54,7 @@
     virtual uint32_t        NumSupportedHardwareWatchpoints();
     virtual uint32_t        EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write);
     virtual bool            DisableHardwareWatchpoint (uint32_t hw_break_index);
-    virtual uint32_t        GetHardwareWatchpointHit();
+    virtual uint32_t        GetHardwareWatchpointHit(nub_addr_t &addr);
 
 protected:
     kern_return_t           EnableHardwareSingleStep (bool enable);
@@ -233,6 +233,7 @@
     static bool IsWatchpointVacant(const DBG &debug_state, uint32_t hw_index);
     static void ClearWatchpointHits(DBG &debug_state);
     static bool IsWatchpointHit(const DBG &debug_state, uint32_t hw_index);
+    static nub_addr_t GetWatchAddress(const DBG &debug_state, uint32_t hw_index);
 
     MachThread *m_thread;
     State       m_state;

Modified: lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp?rev=139274&r1=139273&r2=139274&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp Wed Sep  7 20:16:50 2011
@@ -554,6 +554,19 @@
                     return true;
                 }
             }
+            else if (exc.exc_data.size() >= 2 && exc.exc_data[0] == 1)
+            {
+                // exc_code = EXC_I386_SGL
+                //
+                // Check whether this corresponds to a watchpoint hit event.
+                // If yes, set the exc_sub_code to the data break address.
+                nub_addr_t addr = 0;
+                uint32_t hw_index = GetHardwareWatchpointHit(addr);
+                if (hw_index != INVALID_NUB_HW_INDEX)
+                    exc.exc_data[1] = addr;
+
+                return true;
+            }
             break;
         case EXC_SYSCALL:
             break;
@@ -695,6 +708,23 @@
     return (debug_state.__dr6 & (1 << hw_index));
 }
 
+nub_addr_t
+DNBArchImplX86_64::GetWatchAddress(const DBG &debug_state, uint32_t hw_index)
+{
+    switch (hw_index) {
+    case 0:
+        return debug_state.__dr0;
+    case 1:
+        return debug_state.__dr1;
+    case 2:
+        return debug_state.__dr2;
+    case 3:
+        return debug_state.__dr3;
+    default:
+        assert(0 && "invalid hardware register index, must be one of 0, 1, 2, or 3");
+    }
+}
+
 uint32_t
 DNBArchImplX86_64::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write)
 {
@@ -772,7 +802,7 @@
 
 // Iterate through the debug status register; return the index of the first hit.
 uint32_t
-DNBArchImplX86_64::GetHardwareWatchpointHit()
+DNBArchImplX86_64::GetHardwareWatchpointHit(nub_addr_t &addr)
 {
     // Read the debug state
     kern_return_t kret = GetDBGState(false);
@@ -785,7 +815,10 @@
         {
             if (IsWatchpointHit(debug_state, i))
             {
-                DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::GetHardwareWatchpointHit() found => %u.", i);
+                addr = GetWatchAddress(debug_state, i);
+                DNBLogThreadedIf(LOG_WATCHPOINTS,
+                                 "DNBArchImplX86_64::GetHardwareWatchpointHit() found => %u (addr = %8.8p).",
+                                 i, addr);
                 return i;
             }
         }

Modified: lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h?rev=139274&r1=139273&r2=139274&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h Wed Sep  7 20:16:50 2011
@@ -53,7 +53,7 @@
     virtual uint32_t        NumSupportedHardwareWatchpoints();
     virtual uint32_t        EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write);
     virtual bool            DisableHardwareWatchpoint (uint32_t hw_break_index);
-    virtual uint32_t        GetHardwareWatchpointHit();
+    virtual uint32_t        GetHardwareWatchpointHit(nub_addr_t &addr);
 
 protected:
     kern_return_t           EnableHardwareSingleStep (bool enable);
@@ -240,6 +240,7 @@
     static bool IsWatchpointVacant(const DBG &debug_state, uint32_t hw_index);
     static void ClearWatchpointHits(DBG &debug_state);
     static bool IsWatchpointHit(const DBG &debug_state, uint32_t hw_index);
+    static nub_addr_t GetWatchAddress(const DBG &debug_state, uint32_t hw_index);
 
     MachThread *m_thread;
     State        m_state;





More information about the lldb-commits mailing list