From f131a5790812c3ca69a4fcd9cd2b9ac15b29d181 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Mon, 24 Jul 2023 09:14:20 -0600 Subject: [PATCH] Add "cwd" parameter to DAP launch request This adds the "cwd" parameter to the DAP launch request. This came up here: https://github.com/eclipse-cdt-cloud/cdt-gdb-adapter/issues/90 ... and seemed like a good idea. Reviewed-By: Eli Zaretskii --- gdb/doc/gdb.texinfo | 8 +++++++ gdb/python/lib/gdb/dap/launch.py | 34 +++++++++++++------------- gdb/testsuite/gdb.dap/cwd.exp | 40 +++++++++++++++++++++++++++++++ gdb/testsuite/lib/dap-support.exp | 5 ++++ 4 files changed, 70 insertions(+), 17 deletions(-) create mode 100644 gdb/testsuite/gdb.dap/cwd.exp diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 1463f501768..bd11f0a4475 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -39069,6 +39069,14 @@ If provided, this should be an array of strings. These strings are provided as command-line arguments to the inferior, as if by @code{set args}. @xref{Arguments}. +@item cwd +If provided, this should be a string. @value{GDBN} will change its +working directory to this directory, as if by the @code{cd} command +(@pxref{Working Directory}). The launched program will inherit this +as its working directory. Note that change of directory happens +before the @code{program} parameter is processed. This will affect +the result if @code{program} is a relative filename. + @item env If provided, this should be an object. Each key of the object will be used as the name of an environment variable; each value must be a diff --git a/gdb/python/lib/gdb/dap/launch.py b/gdb/python/lib/gdb/dap/launch.py index c3c09bc3dd0..d13037fa476 100644 --- a/gdb/python/lib/gdb/dap/launch.py +++ b/gdb/python/lib/gdb/dap/launch.py @@ -23,12 +23,22 @@ from .server import request, capability from .startup import send_gdb, send_gdb_with_response, in_gdb_thread, exec_and_log +# The program being launched, or None. This should only be access +# from the DAP thread. _program = None @in_gdb_thread -def _set_args_env(args, env): +def _launch_setup(program, cwd, args, env, stopAtBeginningOfMainSubprogram): + if cwd is not None: + exec_and_log("cd " + cwd) + if program is not None: + exec_and_log("file " + program) inf = gdb.selected_inferior() + if stopAtBeginningOfMainSubprogram: + main = inf.main_name + if main is not None: + exec_and_log("tbreak " + main) inf.arguments = args if env is not None: inf.clear_env() @@ -36,14 +46,6 @@ def _set_args_env(args, env): inf.set_env(name, value) -@in_gdb_thread -def _break_at_main(): - inf = gdb.selected_inferior() - main = inf.main_name - if main is not None: - exec_and_log("tbreak " + main) - - # Any parameters here are necessarily extensions -- DAP requires this # from implementations. Any additions or changes here should be # documented in the gdb manual. @@ -51,19 +53,17 @@ def _break_at_main(): def launch( *, program: Optional[str] = None, + cwd: Optional[str] = None, args: Sequence[str] = (), env: Optional[Mapping[str, str]] = None, stopAtBeginningOfMainSubprogram: bool = False, **extra, ): - if program is not None: - global _program - _program = program - send_gdb("file " + _program) - if stopAtBeginningOfMainSubprogram: - send_gdb(_break_at_main) - if len(args) > 0 or env is not None: - send_gdb(lambda: _set_args_env(args, env)) + global _program + _program = program + send_gdb( + lambda: _launch_setup(program, cwd, args, env, stopAtBeginningOfMainSubprogram) + ) @request("attach") diff --git a/gdb/testsuite/gdb.dap/cwd.exp b/gdb/testsuite/gdb.dap/cwd.exp new file mode 100644 index 00000000000..394fe5ada83 --- /dev/null +++ b/gdb/testsuite/gdb.dap/cwd.exp @@ -0,0 +1,40 @@ +# Copyright 2023 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Test the cwd extension. + +require allow_dap_tests {!is_remote host} + +load_lib dap-support.exp + +standard_testfile attach.c + +if {[build_executable ${testfile}.exp $testfile $srcfile] == -1} { + return +} + +# Starting the inferior will fail if the change of cwd does not work. +set the_dir [file dirname $testfile] +set the_file [file tail $testfile] +if {[dap_launch $the_file cwd $the_dir stop_at_main 1] == ""} { + return +} + +dap_check_request_and_response "start inferior" configurationDone +# We didn't explicitly set a breakpoint, so if we hit one, it worked. +dap_wait_for_event_and_check "stopped at function breakpoint" stopped \ + "body reason" breakpoint + +dap_shutdown diff --git a/gdb/testsuite/lib/dap-support.exp b/gdb/testsuite/lib/dap-support.exp index 4a1a288e7ae..657ad7b29bc 100644 --- a/gdb/testsuite/lib/dap-support.exp +++ b/gdb/testsuite/lib/dap-support.exp @@ -248,6 +248,7 @@ proc _dap_initialize {name} { # * stop_at_main - value is ignored, the presence of this means that # "stopAtBeginningOfMainSubprogram" will be passed to the launch # request. +# * cwd - value is the working directory to use. # # After this proc is called, gdb will be ready to accept breakpoint # requests. @@ -284,6 +285,10 @@ proc dap_launch {file {args {}}} { append params { stopAtBeginningOfMainSubprogram [l true]} } + cwd { + append envlist " cwd [format {[%s]} [list s $value]]" + } + default { error "unrecognized parameter $key" } -- 2.30.2