<rdar://problem/11782789> Changes to the watchpoint implementation on ARM so that we single-step before stopping at the WP. This is necessary because on ARM the WP triggers before the opcode is actually executed, so we would be unable to continue since we would keep hitting the WP. We work around this by disabling the WP, single stepping and then putting the WP back in place.
git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@160199 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Target/StopInfo.cpp b/source/Target/StopInfo.cpp
index 113aa57..5b782be 100644
--- a/source/Target/StopInfo.cpp
+++ b/source/Target/StopInfo.cpp
@@ -461,6 +461,36 @@
if (wp_sp)
{
ExecutionContext exe_ctx (m_thread.GetStackFrameAtIndex(0));
+ {
+ // check if this process is running on an architecture where watchpoints trigger
+ // before the associated instruction runs. if so, disable the WP, single-step and then
+ // re-enable the watchpoint
+ Process* process = exe_ctx.GetProcessPtr();
+ if (process)
+ {
+ uint32_t num; bool wp_triggers_after;
+ if (process->GetWatchpointSupportInfo(num, wp_triggers_after).Success())
+ {
+ if (!wp_triggers_after)
+ {
+ process->DisableWatchpoint(wp_sp.get());
+
+ ThreadPlan *new_plan = m_thread.QueueThreadPlanForStepSingleInstruction(false, // step-over
+ false, // abort_other_plans
+ true); // stop_other_threads
+ new_plan->SetIsMasterPlan (true);
+ new_plan->SetOkayToDiscard (false);
+ process->GetThreadList().SetSelectedThreadByID (m_thread.GetID());
+ process->Resume ();
+ process->WaitForProcessToStop (NULL);
+ process->GetThreadList().SetSelectedThreadByID (m_thread.GetID());
+ MakeStopInfoValid(); // make sure we do not fail to stop because of the single-step taken above
+
+ process->EnableWatchpoint(wp_sp.get());
+ }
+ }
+ }
+ }
StoppointCallbackContext context (event_ptr, exe_ctx, false);
bool stop_requested = wp_sp->InvokeCallback (&context);
// Also make sure that the callback hasn't continued the target.