aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohan Sternerup <johan.sternerup@gmail.com>2024-06-01 18:16:32 +0200
committerTom Tromey <tromey@adacore.com>2024-06-06 10:25:19 -0600
commit61e608693b53a13c48d509a45b329f7ef9dfaa19 (patch)
tree1ef979e3630820f7fdd12b4644e6c2fa0d696bd7
parent42dc1b7f621755ab0587be5e313b4b0918738952 (diff)
downloadgdb-61e608693b53a13c48d509a45b329f7ef9dfaa19.zip
gdb-61e608693b53a13c48d509a45b329f7ef9dfaa19.tar.gz
gdb-61e608693b53a13c48d509a45b329f7ef9dfaa19.tar.bz2
DAP: Handle "stepOut" request in outermost frame
Previously a "stepOut" request when in the outermost frame would result in a sucessful response even though gdb internally would reject the associated "finish" request, which means no stoppedEvent would ever be sent back to the client. Thus the client would believe the inferior was still running and as a consequence reject subsequent "next" and "stepIn" requests from the user. The solution is to execute the underlying finish command as a background command, i.e. `finish &`. If we're in the outermost frame an exception will be raised immediately, which we can now capture and report back to the client as success=False so then the absence of a `stopped` event is no longer a problem. We also make use of the `defer_stop_event` option to prevent a stop event from reaching the client until the response has been sent. Approved-By: Tom Tromey <tom@tromey.com>
-rw-r--r--gdb/python/lib/gdb/dap/next.py4
-rw-r--r--gdb/testsuite/gdb.dap/step-out.exp11
2 files changed, 13 insertions, 2 deletions
diff --git a/gdb/python/lib/gdb/dap/next.py b/gdb/python/lib/gdb/dap/next.py
index 1dc1d6d..7e06b1b 100644
--- a/gdb/python/lib/gdb/dap/next.py
+++ b/gdb/python/lib/gdb/dap/next.py
@@ -73,10 +73,10 @@ def step_in(
exec_and_expect_stop(cmd)
-@request("stepOut", response=False)
+@request("stepOut", defer_stop_events=True)
def step_out(*, threadId: int, singleThread: bool = False, **args):
_handle_thread_step(threadId, singleThread, True)
- exec_and_expect_stop("finish")
+ exec_and_expect_stop("finish &", propagate_exception=True)
# This is a server-side request because it is funny: it wants to
diff --git a/gdb/testsuite/gdb.dap/step-out.exp b/gdb/testsuite/gdb.dap/step-out.exp
index 757f4eb..31c50bb 100644
--- a/gdb/testsuite/gdb.dap/step-out.exp
+++ b/gdb/testsuite/gdb.dap/step-out.exp
@@ -79,4 +79,15 @@ gdb_assert {[dict get $varlist variablesReference] > 0} \
gdb_assert {[dict get $varlist name] == "(return)"} \
"variable is return value"
+set response_and_events [dap_request_and_response stepOut {o threadId [i 1]}]
+set response [lindex $response_and_events 0]
+if {[dict get $response success] == "true"} {
+ fail "stepOut from outermost frame should not succeed"
+} else {
+ pass "stepOut from outermost frame failed like it should"
+}
+
+dap_check_request_and_response "still stopped and may request backtrace" \
+ stackTrace {o threadId [i 1]}
+
dap_shutdown