From fc2d72afc0516e397dc0d7edb75930efa3697a2c Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Tue, 9 May 2023 14:33:42 -0600 Subject: Add singleThread support to some DAP requests A few DAP requests support a "singleThread" parameter, which is somewhat similar to scheduler-locking. This patch implements support for this. --- gdb/python/lib/gdb/dap/next.py | 45 +++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 12 deletions(-) (limited to 'gdb/python') diff --git a/gdb/python/lib/gdb/dap/next.py b/gdb/python/lib/gdb/dap/next.py index 232b152..290b9b8 100644 --- a/gdb/python/lib/gdb/dap/next.py +++ b/gdb/python/lib/gdb/dap/next.py @@ -13,21 +13,40 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import gdb + from .events import StopKinds, ExecutionInvoker from .server import capability, request -from .startup import send_gdb +from .startup import in_gdb_thread, send_gdb, send_gdb_with_response from .state import set_thread -# Helper function to set the current thread. -def _handle_thread_step(threadId): +# Helper function to set the current thread and the scheduler-locking +# mode. Returns True if scheduler-locking was successfully set to +# 'on', False in all other cases, including error. +@in_gdb_thread +def _handle_thread_step(thread_id, single_thread): # Ensure we're going to step the correct thread. - send_gdb(lambda: set_thread(threadId)) + set_thread(thread_id) + if single_thread: + result = True + arg = "on" + else: + result = False + arg = "off" + try: + # This can fail, depending on the target, so catch the error + # and report to our caller. We can't use exec_and_log because + # that does not propagate exceptions. + gdb.execute("set scheduler-locking " + arg, from_tty=True, to_string=True) + except gdb.error: + result = False + return result @request("next") -def next(*, threadId, granularity="statement", **args): - _handle_thread_step(threadId) +def next(*, threadId, singleThread=False, granularity="statement", **args): + send_gdb(lambda: _handle_thread_step(threadId, singleThread)) cmd = "next" if granularity == "instruction": cmd += "i" @@ -35,9 +54,10 @@ def next(*, threadId, granularity="statement", **args): @capability("supportsSteppingGranularity") +@capability("supportsSingleThreadExecutionRequests") @request("stepIn") -def stepIn(*, threadId, granularity="statement", **args): - _handle_thread_step(threadId) +def stepIn(*, threadId, singleThread=False, granularity="statement", **args): + send_gdb(lambda: _handle_thread_step(threadId, singleThread)) cmd = "step" if granularity == "instruction": cmd += "i" @@ -45,12 +65,13 @@ def stepIn(*, threadId, granularity="statement", **args): @request("stepOut") -def step_out(*, threadId): - _handle_thread_step(threadId) +def step_out(*, threadId, singleThread=False): + send_gdb(lambda: _handle_thread_step(threadId, singleThread)) send_gdb(ExecutionInvoker("finish", StopKinds.STEP)) @request("continue") -def continue_request(**args): +def continue_request(*, threadId, singleThread=False, **args): + locked = send_gdb_with_response(lambda: _handle_thread_step(threadId, singleThread)) send_gdb(ExecutionInvoker("continue", None)) - return {"allThreadsContinued": True} + return {"allThreadsContinued": not locked} -- cgit v1.1