From f12e0380be3bd6084ae860090dc027e0281e388e Mon Sep 17 00:00:00 2001 From: Felipe de Azevedo Piovezan Date: Mon, 11 Aug 2025 10:26:57 -0700 Subject: [lldb] Guard SBFrame/SBThread methods against running processes (#152020) Prior to this patch, SBFrame/SBThread methods exhibit racy behavior if called while the process is running, because they do not lock the `Process::RetRunLock` mutex. If they did, they would fail, correctly identifying that the process is not running. Some methods _attempt_ to protect against this with the pattern: ``` ExecutionContext exe_ctx(m_opaque_sp.get(), lock); // this is a different lock Process *process = exe_ctx.GetProcessPtr(); if (process) { Process::StopLocker stop_locker; if (stop_locker.TryLock(&process->GetRunLock())) .... do work ... ``` However, this is also racy: the constructor of `ExecutionContext` will access the frame list, which is something that can only be done once the process is stopped. With this patch: 1. The constructor of `ExecutionContext` now expects a `ProcessRunLock` as an argument. It attempts to lock the run lock, and only fills in information about frames and threads if the lock can be acquired. Callers of the constructor are expected to check the lock. 2. All uses of ExecutionContext are adjusted to conform to the above. 3. The SBThread.cpp-defined helper function ResumeNewPlan now expects a locked ProcessRunLock as _proof_ that the execution is stopped. It will unlock the mutex prior to resuming the process. This commit exposes many opportunities for early-returns, but these would increase the diff of this patch and distract from the important changes, so we opt not to do it here. --- lldb/test/API/python_api/run_locker/TestRunLocker.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lldb/test/API/python_api') diff --git a/lldb/test/API/python_api/run_locker/TestRunLocker.py b/lldb/test/API/python_api/run_locker/TestRunLocker.py index b7b4941214e8..d525bbf6b406 100644 --- a/lldb/test/API/python_api/run_locker/TestRunLocker.py +++ b/lldb/test/API/python_api/run_locker/TestRunLocker.py @@ -107,4 +107,6 @@ class TestRunLocker(TestBase): "script var = lldb.frame.EvaluateExpression('SomethingToCall()'); var.GetError().GetCString()", result, ) - self.assertIn("sbframe object is not valid", result.GetOutput()) + self.assertIn( + "can't evaluate expressions when the process is running", result.GetOutput() + ) -- cgit v1.2.3