[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