This revision was not accepted when it landed; it landed in state "Needs
Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rGa92f7832f35c: Fix the run locker setting for async launches
that don't stop at the (authored by jingham).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D144665/new/
https://reviews.llvm.org/D144665
Files:
lldb/source/API/SBFrame.cpp
lldb/source/API/SBTarget.cpp
lldb/source/Target/Target.cpp
lldb/test/API/python_api/run_locker/Makefile
lldb/test/API/python_api/run_locker/TestRunLocker.py
lldb/test/API/python_api/run_locker/main.c
Index: lldb/test/API/python_api/run_locker/main.c
===================================================================
--- /dev/null
+++ lldb/test/API/python_api/run_locker/main.c
@@ -0,0 +1,15 @@
+#include <unistd.h>
+
+int
+SomethingToCall() {
+ return 100;
+}
+
+int
+main()
+{
+ while (1) {
+ sleep(1);
+ }
+ return SomethingToCall();
+}
Index: lldb/test/API/python_api/run_locker/TestRunLocker.py
===================================================================
--- /dev/null
+++ lldb/test/API/python_api/run_locker/TestRunLocker.py
@@ -0,0 +1,89 @@
+"""
+Test that the run locker really does work to keep
+us from running SB API that should only be run
+while stopped. This test is mostly concerned with
+what happens between launch and first stop.
+"""
+
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+
+
+class TestRunLocker(TestBase):
+
+ NO_DEBUG_INFO_TESTCASE = True
+
+ def test_run_locker(self):
+ """Test that the run locker is set correctly when we launch"""
+ self.build()
+ self.runlocker_test(False)
+
+ def test_run_locker_stop_at_entry(self):
+ """Test that the run locker is set correctly when we launch"""
+ self.build()
+ self.runlocker_test(False)
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ self.main_source_file = lldb.SBFileSpec("main.c")
+
+ def runlocker_test(self, stop_at_entry):
+ """The code to stop at entry handles events slightly differently, so
+ we test both versions of process launch."""
+
+ target = lldbutil.run_to_breakpoint_make_target(self)
+
+ launch_info = target.GetLaunchInfo()
+ if stop_at_entry:
+ flags = launch_info.GetFlags()
+ launch_info.SetFlags(flags | lldb.eLaunchFlagStopAtEntry)
+
+ error = lldb.SBError()
+ # We are trying to do things when the process is running, so
+ # we have to run the debugger asynchronously.
+ self.dbg.SetAsync(True)
+
+ listener = lldb.SBListener("test-run-lock-listener")
+ launch_info.SetListener(listener)
+ process = target.Launch(launch_info, error)
+ self.assertSuccess(error, "Launched the process")
+
+ event = lldb.SBEvent()
+
+ event_result = listener.WaitForEvent(10, event)
+ self.assertTrue(event_result, "timed out waiting for launch")
+ state_type = lldb.SBProcess.GetStateFromEvent(event)
+ # We don't always see a launching...
+ if state_type == lldb.eStateLaunching:
+ event_result = listener.WaitForEvent(10, event)
+ self.assertTrue(event_result, "Timed out waiting for running after launching")
+ state_type = lldb.SBProcess.GetStateFromEvent(event)
+
+ self.assertState(state_type, lldb.eStateRunning, "Didn't get a running event")
+
+ # We aren't checking the entry state, but just making sure
+ # the running state is set properly if we continue in this state.
+
+ if stop_at_entry:
+ event_result = listener.WaitForEvent(10, event)
+ self.assertTrue(event_result, "Timed out waiting for stop at entry stop")
+ state_type = lldb.SBProcess.GetStateFromEvent(event)
+ self.assertState(state_type, eStateStopped, "Stop at entry stopped")
+ process.Continue()
+
+ # Okay, now the process is running, make sure we can't do things
+ # you aren't supposed to do while running, and that we get some
+ # actual error:
+ val = target.EvaluateExpression("SomethingToCall()")
+ error = val.GetError()
+ self.assertTrue(error.Fail(), "Failed to run expression")
+ print(f"Got Error: {error.GetCString()}")
+ self.assertIn("can't evaluate expressions when the process is running", error.GetCString(), "Stopped by stop locker")
+
+ # This should also fail if we try to use the script interpreter directly:
+ interp = self.dbg.GetCommandInterpreter()
+ result = lldb.SBCommandReturnObject()
+ ret = interp.HandleCommand("script var = lldb.frame.EvaluateExpression('SomethingToCall()'); var.GetError().GetCString()", result)
+ self.assertIn("can't evaluate expressions when the process is running", result.GetOutput())
Index: lldb/test/API/python_api/run_locker/Makefile
===================================================================
--- /dev/null
+++ lldb/test/API/python_api/run_locker/Makefile
@@ -0,0 +1,4 @@
+C_SOURCES := main.c
+CFLAGS_EXTRAS := -std=c99
+
+include Makefile.rules
Index: lldb/source/Target/Target.cpp
===================================================================
--- lldb/source/Target/Target.cpp
+++ lldb/source/Target/Target.cpp
@@ -3223,7 +3223,7 @@
// SyncResume hijacker.
m_process_sp->ResumeSynchronous(stream);
else
- error = m_process_sp->PrivateResume();
+ error = m_process_sp->Resume();
if (!error.Success()) {
Status error2;
error2.SetErrorStringWithFormat(
Index: lldb/source/API/SBTarget.cpp
===================================================================
--- lldb/source/API/SBTarget.cpp
+++ lldb/source/API/SBTarget.cpp
@@ -2219,12 +2219,25 @@
std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
ExecutionContext exe_ctx(m_opaque_sp.get());
-
frame = exe_ctx.GetFramePtr();
Target *target = exe_ctx.GetTargetPtr();
+ Process *process = exe_ctx.GetProcessPtr();
if (target) {
- target->EvaluateExpression(expr, frame, expr_value_sp, options.ref());
+ // If we have a process, make sure to lock the runlock:
+ if (process) {
+ Process::StopLocker stop_locker;
+ if (stop_locker.TryLock(&process->GetRunLock())) {
+ target->EvaluateExpression(expr, frame, expr_value_sp, options.ref());
+ } else {
+ Status error;
+ error.SetErrorString("can't evaluate expressions when the "
+ "process is running.");
+ expr_value_sp = ValueObjectConstResult::Create(nullptr, error);
+ }
+ } else {
+ target->EvaluateExpression(expr, frame, expr_value_sp, options.ref());
+ }
expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue());
}
Index: lldb/source/API/SBFrame.cpp
===================================================================
--- lldb/source/API/SBFrame.cpp
+++ lldb/source/API/SBFrame.cpp
@@ -19,6 +19,7 @@
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ValueObjectRegister.h"
#include "lldb/Core/ValueObjectVariable.h"
+#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Expression/ExpressionVariable.h"
#include "lldb/Expression/UserExpression.h"
#include "lldb/Host/Host.h"
@@ -988,6 +989,12 @@
else
options.SetLanguage(frame->GetLanguage());
return EvaluateExpression(expr, options);
+ } else {
+ Status error;
+ error.SetErrorString("can't evaluate expressions when the "
+ "process is running.");
+ ValueObjectSP error_val_sp = ValueObjectConstResult::Create(nullptr, error);
+ result.SetSP(error_val_sp, false);
}
return result;
}
@@ -1051,7 +1058,6 @@
std::unique_lock<std::recursive_mutex> lock;
ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
-
StackFrame *frame = nullptr;
Target *target = exe_ctx.GetTargetPtr();
Process *process = exe_ctx.GetProcessPtr();
@@ -1075,13 +1081,30 @@
target->EvaluateExpression(expr, frame, expr_value_sp, options.ref());
expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue());
}
+ } else {
+ Status error;
+ error.SetErrorString("can't evaluate expressions when the "
+ "process is running.");
+ expr_value_sp = ValueObjectConstResult::Create(nullptr, error);
+ expr_result.SetSP(expr_value_sp, false);
}
+ } else {
+ Status error;
+ error.SetErrorString("sbframe object is not valid.");
+ expr_value_sp = ValueObjectConstResult::Create(nullptr, error);
+ expr_result.SetSP(expr_value_sp, false);
}
- LLDB_LOGF(expr_log,
- "** [SBFrame::EvaluateExpression] Expression result is "
- "%s, summary %s **",
- expr_result.GetValue(), expr_result.GetSummary());
+ if (expr_result.GetError().Success())
+ LLDB_LOGF(expr_log,
+ "** [SBFrame::EvaluateExpression] Expression result is "
+ "%s, summary %s **",
+ expr_result.GetValue(), expr_result.GetSummary());
+ else
+ LLDB_LOGF(expr_log,
+ "** [SBFrame::EvaluateExpression] Expression evaluation failed: "
+ "%s **",
+ expr_result.GetError().GetCString());
return expr_result;
}
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits