This revision was automatically updated to reflect the committed changes.
Closed by commit rG8d024a79ea78: Fix a problem with "watchpoint triggers
before" watchpoint handling. (authored by jingham).
Changed prior to commit:
https://reviews.llvm.org/D146337?vs=506219&id=506750#toc
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D146337/new/
https://reviews.llvm.org/D146337
Files:
lldb/include/lldb/Target/Process.h
lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
lldb/source/Target/StopInfo.cpp
lldb/source/Target/Thread.cpp
lldb/test/API/commands/watchpoints/step_over_watchpoint/TestStepOverWatchpoint.py
lldb/test/API/commands/watchpoints/step_over_watchpoint/main.c
Index: lldb/test/API/commands/watchpoints/step_over_watchpoint/main.c
===================================================================
--- lldb/test/API/commands/watchpoints/step_over_watchpoint/main.c
+++ lldb/test/API/commands/watchpoints/step_over_watchpoint/main.c
@@ -11,8 +11,8 @@
}
int main() {
- watch_read();
- g_temp = g_watch_me_read;
+ watch_read(); // Set a breakpoint here
+ g_temp = g_watch_me_read; // Set breakpoint after call
watch_write();
g_watch_me_write = g_temp;
return 0;
Index: lldb/test/API/commands/watchpoints/step_over_watchpoint/TestStepOverWatchpoint.py
===================================================================
--- lldb/test/API/commands/watchpoints/step_over_watchpoint/TestStepOverWatchpoint.py
+++ lldb/test/API/commands/watchpoints/step_over_watchpoint/TestStepOverWatchpoint.py
@@ -11,36 +11,11 @@
class TestStepOverWatchpoint(TestBase):
NO_DEBUG_INFO_TESTCASE = True
- @expectedFailureAll(
- oslist=["freebsd", "linux"],
- archs=[
- 'aarch64',
- 'arm'],
- bugnumber="llvm.org/pr26031")
- # Read-write watchpoints not supported on SystemZ
- @expectedFailureAll(archs=['s390x'])
- @expectedFailureAll(
- oslist=["ios", "watchos", "tvos", "bridgeos", "macosx"],
- archs=['aarch64', 'arm'],
- bugnumber="<rdar://problem/34027183>")
- @add_test_categories(["basic_process"])
- def test(self):
+ def get_to_start(self, bkpt_text):
"""Test stepping over watchpoints."""
self.build()
- target = self.createTestTarget()
-
- lldbutil.run_break_set_by_symbol(self, 'main')
-
- process = target.LaunchSimple(None, None,
- self.get_process_working_directory())
- self.assertTrue(process.IsValid(), PROCESS_IS_VALID)
- self.assertState(process.GetState(), lldb.eStateStopped,
- PROCESS_STOPPED)
-
- thread = lldbutil.get_stopped_thread(process,
- lldb.eStopReasonBreakpoint)
- self.assertTrue(thread.IsValid(), "Failed to get thread.")
-
+ target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(self, bkpt_text,
+ lldb.SBFileSpec("main.c"))
frame = thread.GetFrameAtIndex(0)
self.assertTrue(frame.IsValid(), "Failed to get frame.")
@@ -55,14 +30,45 @@
self.assertSuccess(error, "Error while setting watchpoint")
self.assertTrue(read_watchpoint, "Failed to set read watchpoint.")
+ # Disable the breakpoint we hit so we don't muddy the waters with
+ # stepping off from the breakpoint:
+ bkpt.SetEnabled(False)
+
+ return (target, process, thread, read_watchpoint)
+
+ @expectedFailureAll(
+ oslist=["freebsd", "linux"],
+ archs=[
+ 'aarch64',
+ 'arm'],
+ bugnumber="llvm.org/pr26031")
+ # Read-write watchpoints not supported on SystemZ
+ @expectedFailureAll(archs=['s390x'])
+ @add_test_categories(["basic_process"])
+ def test_step_over(self):
+ target, process, thread, wp = self.get_to_start("Set a breakpoint here")
+
thread.StepOver()
self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonWatchpoint,
STOPPED_DUE_TO_WATCHPOINT)
self.assertEquals(thread.GetStopDescription(20), 'watchpoint 1')
- process.Continue()
- self.assertState(process.GetState(), lldb.eStateStopped,
- PROCESS_STOPPED)
+ @expectedFailureAll(
+ oslist=["freebsd", "linux"],
+ archs=[
+ 'aarch64',
+ 'arm'],
+ bugnumber="llvm.org/pr26031")
+ # Read-write watchpoints not supported on SystemZ
+ @expectedFailureAll(archs=['s390x'])
+ @expectedFailureAll(
+ oslist=["ios", "watchos", "tvos", "bridgeos", "macosx"],
+ archs=['aarch64', 'arm'],
+ bugnumber="<rdar://problem/34027183>")
+ @add_test_categories(["basic_process"])
+ def test_step_instruction(self):
+ target, process, thread, wp = self.get_to_start("Set breakpoint after call")
+
self.assertEquals(thread.GetStopDescription(20), 'step over')
self.step_inst_for_watchpoint(1)
Index: lldb/source/Target/Thread.cpp
===================================================================
--- lldb/source/Target/Thread.cpp
+++ lldb/source/Target/Thread.cpp
@@ -1664,6 +1664,9 @@
bool Thread::SafeToCallFunctions() {
Process *process = GetProcess().get();
if (process) {
+ if (!process->SafeToCallFunctions())
+ return false;
+
DynamicLoader *loader = GetProcess()->GetDynamicLoader();
if (loader && loader->IsFullyInitialized() == false)
return false;
Index: lldb/source/Target/StopInfo.cpp
===================================================================
--- lldb/source/Target/StopInfo.cpp
+++ lldb/source/Target/StopInfo.cpp
@@ -831,6 +831,11 @@
= std::static_pointer_cast<StopInfoWatchpoint>(shared_from_this());
ThreadPlanSP step_over_wp_sp(new ThreadPlanStepOverWatchpoint(
*(thread_sp.get()), me_as_siwp_sp, wp_sp));
+ // When this plan is done we want to stop, so set this as a Controlling
+ // plan.
+ step_over_wp_sp->SetIsControllingPlan(true);
+ step_over_wp_sp->SetOkayToDiscard(false);
+
Status error;
error = thread_sp->QueueThreadPlan(step_over_wp_sp, false);
// If we couldn't push the thread plan, just stop here:
Index: lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
===================================================================
--- lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
+++ lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp
@@ -795,6 +795,19 @@
case 9: // EXC_RPC_ALERT
case 10: // EXC_CRASH
break;
+ case 12: // EXC_GUARD
+ {
+ // Some EXC_GUARD exceptions are fatal, and the process will go away
+ // the next time you allow it to run. When we get one of those
+ // exceptions we have to make sure SafeToCallFunctions returns false to
+ // prevent us or other agents running the process. This has to be set
+ // on the process because even the threads that didn't get the exception
+ // can't run.
+ ProcessSP process_sp(thread.GetProcess());
+ if (process_sp)
+ process_sp->SetSafeToCallFunctions(false);
+
+ }
}
return StopInfoSP(new StopInfoMachException(thread, exc_type, exc_data_count,
Index: lldb/include/lldb/Target/Process.h
===================================================================
--- lldb/include/lldb/Target/Process.h
+++ lldb/include/lldb/Target/Process.h
@@ -311,6 +311,14 @@
return m_last_natural_stop_event;
return lldb::EventSP();
}
+
+ void SetSafeToCallFunctions(bool safe) {
+ m_safe = safe;
+ }
+
+ bool GetSafeToCallFunctions() {
+ return m_safe;
+ }
private:
uint32_t m_stop_id = 0;
@@ -321,6 +329,7 @@
uint32_t m_running_user_expression = false;
uint32_t m_running_utility_function = 0;
lldb::EventSP m_last_natural_stop_event;
+ std::atomic<bool> m_safe = true;
};
inline bool operator==(const ProcessModID &lhs, const ProcessModID &rhs) {
@@ -459,7 +468,7 @@
void SetRestarted(bool new_value) { m_restarted = new_value; }
void SetInterrupted(bool new_value) { m_interrupted = new_value; }
-
+
void AddRestartedReason(const char *reason) {
m_restarted_reasons.push_back(reason);
}
@@ -1250,6 +1259,14 @@
DiagnosticManager &diagnostic_manager);
static const char *ExecutionResultAsCString(lldb::ExpressionResults result);
+
+ void SetSafeToCallFunctions(bool safe) {
+ GetModID().SetSafeToCallFunctions(safe);
+ }
+
+ bool GetSafeToCallFunctions() {
+ return GetModID().GetSafeToCallFunctions();
+ }
void GetStatus(Stream &ostrm);
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits