[Lldb-commits] [lldb] r157858 - in /lldb/trunk/tools/debugserver/source: DNBArch.h MacOSX/MachThread.cpp MacOSX/MachThread.h MacOSX/MachThreadList.cpp MacOSX/i386/DNBArchImplI386.cpp MacOSX/i386/DNBArchImplI386.h MacOSX/x86_64/DNBArchImplX86_64.cpp MacOSX/x86_64/DNBArchImplX86_64.h
Johnny Chen
johnny.chen at apple.com
Fri Jun 1 16:43:06 PDT 2012
Author: johnny
Date: Fri Jun 1 18:43:05 2012
New Revision: 157858
URL: http://llvm.org/viewvc/llvm-project?rev=157858&view=rev
Log:
rdar://problem/11320188
Designate MachThreadList as a transaction coordinator when doing Enable/DisableHardwareWatchpoint on the list of threads.
In case the operation (iterating on the threads and doing enable/disable) fails in the middle, we rollback the already
enabled/disabled threads to their checkpointed states. When all the threads succeed in enable/disable, we ask each thread
to finsih the transaction and commit the change of the debug state.
Modified:
lldb/trunk/tools/debugserver/source/DNBArch.h
lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp
lldb/trunk/tools/debugserver/source/MacOSX/MachThread.h
lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp
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/DNBArch.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNBArch.h?rev=157858&r1=157857&r2=157858&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/DNBArch.h (original)
+++ lldb/trunk/tools/debugserver/source/DNBArch.h Fri Jun 1 18:43:05 2012
@@ -82,6 +82,19 @@
virtual bool DisableHardwareWatchpoint (uint32_t hw_index) { return false; }
virtual uint32_t GetHardwareWatchpointHit() { return INVALID_NUB_HW_INDEX; }
virtual bool StepNotComplete () { return false; }
+
+protected:
+ friend class MachThread;
+
+ enum
+ {
+ Trans_Pending = 0, // Transaction is pending, and checkpoint state has been snapshotted.
+ Trans_Done = 1, // Transaction is done, the current state is committed, and checkpoint state is irrelevant.
+ Trans_Rolled_Back = 2 // Transaction is done, the current state has been rolled back to the checkpoint state.
+ };
+ virtual bool StartTransForHWP() { return true; }
+ virtual bool RollbackTransForHWP() { return true; }
+ virtual bool FinishTransForHWP() { return true; }
};
Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp?rev=157858&r1=157857&r2=157858&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachThread.cpp Fri Jun 1 18:43:05 2012
@@ -700,6 +700,18 @@
}
bool
+MachThread::RollbackTransForHWP()
+{
+ return m_arch_ap->RollbackTransForHWP();
+}
+
+bool
+MachThread::FinishTransForHWP()
+{
+ return m_arch_ap->FinishTransForHWP();
+}
+
+bool
MachThread::DisableHardwareBreakpoint (const DNBBreakpoint *bp)
{
if (bp != NULL && bp->IsHardware())
Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachThread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachThread.h?rev=157858&r1=157857&r2=157858&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachThread.h (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachThread.h Fri Jun 1 18:43:05 2012
@@ -66,6 +66,8 @@
bool DisableHardwareBreakpoint (const DNBBreakpoint *breakpoint);
bool DisableHardwareWatchpoint (const DNBBreakpoint *watchpoint);
uint32_t NumSupportedHardwareWatchpoints () const;
+ bool RollbackTransForHWP();
+ bool FinishTransForHWP();
nub_state_t GetState();
void SetState(nub_state_t state);
Modified: lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp?rev=157858&r1=157857&r2=157858&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/MachThreadList.cpp Fri Jun 1 18:43:05 2012
@@ -478,8 +478,17 @@
for (uint32_t idx = 0; idx < num_threads; ++idx)
{
if ((hw_index = m_threads[idx]->EnableHardwareWatchpoint(wp)) == INVALID_NUB_HW_INDEX)
+ {
+ // We know that idx failed for some reason. Let's rollback the transaction for [0, idx).
+ for (uint32_t i = 0; i < idx; ++i)
+ m_threads[i]->RollbackTransForHWP();
return INVALID_NUB_HW_INDEX;
+ }
}
+ // Notify each thread to commit the pending transaction.
+ for (uint32_t idx = 0; idx < num_threads; ++idx)
+ m_threads[idx]->FinishTransForHWP();
+
// Use an arbitrary thread to signal the completion of our transaction.
if (num_threads)
m_threads[0]->HardwareWatchpointStateChanged();
@@ -498,8 +507,17 @@
for (uint32_t idx = 0; idx < num_threads; ++idx)
{
if (!m_threads[idx]->DisableHardwareWatchpoint(wp))
+ {
+ // We know that idx failed for some reason. Let's rollback the transaction for [0, idx).
+ for (uint32_t i = 0; i < idx; ++i)
+ m_threads[i]->RollbackTransForHWP();
return false;
+ }
}
+ // Notify each thread to commit the pending transaction.
+ for (uint32_t idx = 0; idx < num_threads; ++idx)
+ m_threads[idx]->FinishTransForHWP();
+
// Use an arbitrary thread to signal the completion of our transaction.
if (num_threads)
m_threads[0]->HardwareWatchpointStateChanged();
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=157858&r1=157857&r2=157858&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp Fri Jun 1 18:43:05 2012
@@ -818,6 +818,42 @@
}
}
+bool
+DNBArchImplI386::StartTransForHWP()
+{
+ if (m_2pc_trans_state != Trans_Done || m_2pc_trans_state != Trans_Rolled_Back)
+ DNBLogError ("%s inconsistent state detected, expected %d or %d, got: %d", __FUNCTION__, Trans_Done, Trans_Rolled_Back, m_2pc_trans_state);
+ m_2pc_dbg_checkpoint = m_state.context.dbg;
+ m_2pc_trans_state = Trans_Pending;
+ return true;
+}
+bool
+DNBArchImplI386::RollbackTransForHWP()
+{
+ m_state.context.dbg = m_2pc_dbg_checkpoint;
+ if (m_2pc_trans_state != Trans_Pending)
+ DNBLogError ("%s inconsistent state detected, expected %d, got: %d", __FUNCTION__, Trans_Pending, m_2pc_trans_state);
+ m_2pc_trans_state = Trans_Rolled_Back;
+ kern_return_t kret = SetDBGState();
+ DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::RollbackTransForHWP() SetDBGState() => 0x%8.8x.", kret);
+
+ if (kret == KERN_SUCCESS)
+ return true;
+ else
+ return false;
+}
+bool
+DNBArchImplI386::FinishTransForHWP()
+{
+ m_2pc_trans_state = Trans_Done;
+ return true;
+}
+DNBArchImplI386::DBG
+DNBArchImplI386::GetDBGCheckpoint()
+{
+ return m_2pc_dbg_checkpoint;
+}
+
uint32_t
DNBArchImplI386::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write)
{
@@ -842,7 +878,6 @@
uint32_t i = 0;
DBG &debug_state = m_state.context.dbg;
- DBG dsCheckPoint = m_state.context.dbg;
for (i = 0; i < num_hw_watchpoints; ++i)
{
if (IsWatchpointVacant(debug_state, i))
@@ -852,6 +887,8 @@
// See if we found an available hw breakpoint slot above
if (i < num_hw_watchpoints)
{
+ StartTransForHWP();
+
// Modify our local copy of the debug state, first.
SetWatchpoint(debug_state, i, addr, size, read, write);
// Now set the watch point in the inferior.
@@ -860,8 +897,8 @@
if (kret == KERN_SUCCESS)
return i;
- else // Recovery block.
- m_state.context.dbg = dsCheckPoint;
+ else // Revert to the previous debug state voluntarily. The transaction coordinator knows that we have failed.
+ m_state.context.dbg = GetDBGCheckpoint();
}
else
{
@@ -880,9 +917,10 @@
if (kret == KERN_SUCCESS)
{
DBG &debug_state = m_state.context.dbg;
- DBG dsCheckPoint = m_state.context.dbg;
if (hw_index < num_hw_points && !IsWatchpointVacant(debug_state, hw_index))
{
+ StartTransForHWP();
+
// Modify our local copy of the debug state, first.
ClearWatchpoint(debug_state, hw_index);
// Now disable the watch point in the inferior.
@@ -892,8 +930,8 @@
if (kret == KERN_SUCCESS)
return true;
- else // Recovery block.
- m_state.context.dbg = dsCheckPoint;
+ else // Revert to the previous debug state voluntarily. The transaction coordinator knows that we have failed.
+ m_state.context.dbg = GetDBGCheckpoint();
}
}
return false;
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=157858&r1=157857&r2=157858&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h (original)
+++ lldb/trunk/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h Fri Jun 1 18:43:05 2012
@@ -231,8 +231,15 @@
static bool IsWatchpointHit(const DBG &debug_state, uint32_t hw_index);
static nub_addr_t GetWatchAddress(const DBG &debug_state, uint32_t hw_index);
+ virtual bool StartTransForHWP();
+ virtual bool RollbackTransForHWP();
+ virtual bool FinishTransForHWP();
+ DBG GetDBGCheckpoint();
+
MachThread *m_thread;
State m_state;
+ DBG m_2pc_dbg_checkpoint;
+ uint32_t m_2pc_trans_state; // Is transaction of DBG state change: Pedning (0), Done (1), or Rolled Back (2)?
};
#endif // #if defined (__i386__) || defined (__x86_64__)
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=157858&r1=157857&r2=157858&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 Fri Jun 1 18:43:05 2012
@@ -795,6 +795,42 @@
}
}
+bool
+DNBArchImplX86_64::StartTransForHWP()
+{
+ if (m_2pc_trans_state != Trans_Done || m_2pc_trans_state != Trans_Rolled_Back)
+ DNBLogError ("%s inconsistent state detected, expected %d or %d, got: %d", __FUNCTION__, Trans_Done, Trans_Rolled_Back, m_2pc_trans_state);
+ m_2pc_dbg_checkpoint = m_state.context.dbg;
+ m_2pc_trans_state = Trans_Pending;
+ return true;
+}
+bool
+DNBArchImplX86_64::RollbackTransForHWP()
+{
+ m_state.context.dbg = m_2pc_dbg_checkpoint;
+ if (m_2pc_trans_state != Trans_Pending)
+ DNBLogError ("%s inconsistent state detected, expected %d, got: %d", __FUNCTION__, Trans_Pending, m_2pc_trans_state);
+ m_2pc_trans_state = Trans_Rolled_Back;
+ kern_return_t kret = SetDBGState();
+ DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::RollbackTransForHWP() SetDBGState() => 0x%8.8x.", kret);
+
+ if (kret == KERN_SUCCESS)
+ return true;
+ else
+ return false;
+}
+bool
+DNBArchImplX86_64::FinishTransForHWP()
+{
+ m_2pc_trans_state = Trans_Done;
+ return true;
+}
+DNBArchImplX86_64::DBG
+DNBArchImplX86_64::GetDBGCheckpoint()
+{
+ return m_2pc_dbg_checkpoint;
+}
+
uint32_t
DNBArchImplX86_64::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write)
{
@@ -819,7 +855,6 @@
uint32_t i = 0;
DBG &debug_state = m_state.context.dbg;
- DBG dsCheckPoint = m_state.context.dbg;
for (i = 0; i < num_hw_watchpoints; ++i)
{
if (IsWatchpointVacant(debug_state, i))
@@ -829,6 +864,8 @@
// See if we found an available hw breakpoint slot above
if (i < num_hw_watchpoints)
{
+ StartTransForHWP();
+
// Modify our local copy of the debug state, first.
SetWatchpoint(debug_state, i, addr, size, read, write);
// Now set the watch point in the inferior.
@@ -837,8 +874,8 @@
if (kret == KERN_SUCCESS)
return i;
- else // Recovery block.
- m_state.context.dbg = dsCheckPoint;
+ else // Revert to the previous debug state voluntarily. The transaction coordinator knows that we have failed.
+ m_state.context.dbg = GetDBGCheckpoint();
}
else
{
@@ -857,9 +894,10 @@
if (kret == KERN_SUCCESS)
{
DBG &debug_state = m_state.context.dbg;
- DBG dsCheckPoint = m_state.context.dbg;
if (hw_index < num_hw_points && !IsWatchpointVacant(debug_state, hw_index))
{
+ StartTransForHWP();
+
// Modify our local copy of the debug state, first.
ClearWatchpoint(debug_state, hw_index);
// Now disable the watch point in the inferior.
@@ -869,8 +907,8 @@
if (kret == KERN_SUCCESS)
return true;
- else // Recovery block.
- m_state.context.dbg = dsCheckPoint;
+ else // Revert to the previous debug state voluntarily. The transaction coordinator knows that we have failed.
+ m_state.context.dbg = GetDBGCheckpoint();
}
}
return false;
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=157858&r1=157857&r2=157858&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 Fri Jun 1 18:43:05 2012
@@ -238,8 +238,15 @@
static bool IsWatchpointHit(const DBG &debug_state, uint32_t hw_index);
static nub_addr_t GetWatchAddress(const DBG &debug_state, uint32_t hw_index);
+ virtual bool StartTransForHWP();
+ virtual bool RollbackTransForHWP();
+ virtual bool FinishTransForHWP();
+ DBG GetDBGCheckpoint();
+
MachThread *m_thread;
- State m_state;
+ State m_state;
+ DBG m_2pc_dbg_checkpoint;
+ uint32_t m_2pc_trans_state; // Is transaction of DBG state change: Pedning (0), Done (1), or Rolled Back (2)?
};
#endif // #if defined (__i386__) || defined (__x86_64__)
More information about the lldb-commits
mailing list