Cope with the case where the user-supplied callbacks want the watchpoint itself to be disabled!
Previously we put a WatchpointSentry object within StopInfo.cpp to disable-and-then-enable the watchpoint itself
while we are performing the actions associated with the triggered watchpoint, which can cause the user-initiated
watchpoint disabling action to be negated.
Add a test case to verify that a watchpoint can be disabled during the callbacks.
git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@162483 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Breakpoint/Watchpoint.cpp b/source/Breakpoint/Watchpoint.cpp
index 3736adb..ca5503f 100644
--- a/source/Breakpoint/Watchpoint.cpp
+++ b/source/Breakpoint/Watchpoint.cpp
@@ -30,6 +30,7 @@
m_is_hardware(hardware),
m_is_watch_variable(false),
m_is_ephemeral(false),
+ m_disabled_count(0),
m_watch_read(0),
m_watch_write(0),
m_watch_was_read(0),
@@ -322,6 +323,14 @@
Watchpoint::TurnOffEphemeralMode()
{
m_is_ephemeral = false;
+ // Leaving ephemeral mode, reset the m_disabled_count!
+ m_disabled_count = 0;
+}
+
+bool
+Watchpoint::IsDisabledDuringEphemeralMode()
+{
+ return m_disabled_count > 1;
}
void
@@ -331,6 +340,9 @@
{
if (!m_is_ephemeral)
SetHardwareIndex(LLDB_INVALID_INDEX32);
+ else
+ ++m_disabled_count;
+
// Don't clear the snapshots for now.
// Within StopInfo.cpp, we purposely do disable/enable watchpoint while performing watchpoint actions.
//ClearSnapshots();
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 07536c7..6089b83 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -2281,6 +2281,10 @@
{
if (log)
log->Printf ("ProcessGDBRemote::DisableWatchpoint (watchID = %llu) addr = 0x%8.8llx -- SUCCESS (already disabled)", watchID, (uint64_t)addr);
+ // See also 'class WatchpointSentry' within StopInfo.cpp.
+ // This disabling attempt might come from the user-supplied actions, we'll route it in order for
+ // the watchpoint object to intelligently process this action.
+ wp->SetEnabled(false);
return error;
}
diff --git a/source/Target/StopInfo.cpp b/source/Target/StopInfo.cpp
index 400829f..01d8ba9 100644
--- a/source/Target/StopInfo.cpp
+++ b/source/Target/StopInfo.cpp
@@ -463,7 +463,8 @@
{
if (process && watchpoint)
{
- process->EnableWatchpoint(watchpoint);
+ if (!watchpoint->IsDisabledDuringEphemeralMode())
+ process->EnableWatchpoint(watchpoint);
watchpoint->TurnOffEphemeralMode();
}
}