]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Fix DAP launch and configurationDone requests
authorTom Tromey <tromey@adacore.com>
Thu, 18 Jan 2024 14:35:48 +0000 (07:35 -0700)
committerTom Tromey <tromey@adacore.com>
Mon, 12 Feb 2024 17:43:17 +0000 (10:43 -0700)
Co-workers at AdaCore pointed out that gdb incorrectly implements the
DAP launch and configurationDone requests.  It's somewhat strange to
me, but the spec does in fact say that configuration requests should
occur before the executable is known to gdb.  This was clarified in
this bug report against the spec:

    https://github.com/microsoft/debug-adapter-protocol/issues/452

Fixing 'launch' to start the inferior was straightforward, but this
then required some changes to how breakpoints are handled.  In
particular, now gdb will emit the "pending" reason on a breakpoint,
and will suppress breakpoint events during breakpoint setting.

30 files changed:
gdb/python/lib/gdb/dap/breakpoint.py
gdb/python/lib/gdb/dap/launch.py
gdb/testsuite/gdb.dap/ada-arrays.exp
gdb/testsuite/gdb.dap/ada-nested.exp
gdb/testsuite/gdb.dap/ada-scopes.exp
gdb/testsuite/gdb.dap/args-env.exp
gdb/testsuite/gdb.dap/assign.exp
gdb/testsuite/gdb.dap/basic-dap.exp
gdb/testsuite/gdb.dap/bt-nodebug.exp
gdb/testsuite/gdb.dap/catch-exception.exp
gdb/testsuite/gdb.dap/children.exp
gdb/testsuite/gdb.dap/cond-bp.exp
gdb/testsuite/gdb.dap/cwd.exp
gdb/testsuite/gdb.dap/cxx-exception.exp
gdb/testsuite/gdb.dap/eof.exp
gdb/testsuite/gdb.dap/frameless.exp
gdb/testsuite/gdb.dap/hover.exp
gdb/testsuite/gdb.dap/lazy-string.exp
gdb/testsuite/gdb.dap/log-message.exp
gdb/testsuite/gdb.dap/memory.exp
gdb/testsuite/gdb.dap/modules.exp
gdb/testsuite/gdb.dap/pause.exp
gdb/testsuite/gdb.dap/ptrref.exp
gdb/testsuite/gdb.dap/rust-slices.exp
gdb/testsuite/gdb.dap/scopes.exp
gdb/testsuite/gdb.dap/sources.exp
gdb/testsuite/gdb.dap/stack-format.exp
gdb/testsuite/gdb.dap/stop-at-main.exp
gdb/testsuite/gdb.dap/terminate.exp
gdb/testsuite/lib/dap-support.exp

index 87e746472fb088d89569faa5cc5f7a8028da9f9a..b4fb1127c2d753fc177d55ab3cd83ac6c9f47501 100644 (file)
@@ -28,17 +28,6 @@ from .startup import in_gdb_thread, log_stack, parse_and_eval, LogLevel, DAPExce
 from .typecheck import type_check
 
 
-@in_gdb_thread
-def _bp_modified(event):
-    send_event(
-        "breakpoint",
-        {
-            "reason": "changed",
-            "breakpoint": _breakpoint_descriptor(event),
-        },
-    )
-
-
 # True when suppressing new breakpoint events.
 _suppress_bp = False
 
@@ -55,6 +44,19 @@ def suppress_new_breakpoint_event():
         _suppress_bp = saved
 
 
+@in_gdb_thread
+def _bp_modified(event):
+    global _suppress_bp
+    if not _suppress_bp:
+        send_event(
+            "breakpoint",
+            {
+                "reason": "changed",
+                "breakpoint": _breakpoint_descriptor(event),
+            },
+        )
+
+
 @in_gdb_thread
 def _bp_created(event):
     global _suppress_bp
@@ -70,13 +72,15 @@ def _bp_created(event):
 
 @in_gdb_thread
 def _bp_deleted(event):
-    send_event(
-        "breakpoint",
-        {
-            "reason": "removed",
-            "breakpoint": _breakpoint_descriptor(event),
-        },
-    )
+    global _suppress_bp
+    if not _suppress_bp:
+        send_event(
+            "breakpoint",
+            {
+                "reason": "removed",
+                "breakpoint": _breakpoint_descriptor(event),
+            },
+        )
 
 
 gdb.events.breakpoint_created.connect(_bp_created)
@@ -97,11 +101,10 @@ def _breakpoint_descriptor(bp):
     "Return the Breakpoint object descriptor given a gdb Breakpoint."
     result = {
         "id": bp.number,
-        # We always use True here, because this field just indicates
-        # that breakpoint creation was successful -- and if we have a
-        # breakpoint, the creation succeeded.
-        "verified": True,
+        "verified": not bp.pending,
     }
+    if bp.pending:
+        result["reason"] = "pending"
     if bp.locations:
         # Just choose the first location, because DAP doesn't allow
         # multiple locations.  See
@@ -146,52 +149,55 @@ def _set_breakpoints_callback(kind, specs, creator):
         saved_map = {}
     breakpoint_map[kind] = {}
     result = []
-    for spec in specs:
-        # It makes sense to reuse a breakpoint even if the condition
-        # or ignore count differs, so remove these entries from the
-        # spec first.
-        (condition, hit_condition) = _remove_entries(spec, "condition", "hitCondition")
-        keyspec = frozenset(spec.items())
-
-        # Create or reuse a breakpoint.  If asked, set the condition
-        # or the ignore count.  Catch errors coming from gdb and
-        # report these as an "unverified" breakpoint.
-        bp = None
-        try:
-            if keyspec in saved_map:
-                bp = saved_map.pop(keyspec)
-            else:
-                with suppress_new_breakpoint_event():
+    with suppress_new_breakpoint_event():
+        for spec in specs:
+            # It makes sense to reuse a breakpoint even if the condition
+            # or ignore count differs, so remove these entries from the
+            # spec first.
+            (condition, hit_condition) = _remove_entries(
+                spec, "condition", "hitCondition"
+            )
+            keyspec = frozenset(spec.items())
+
+            # Create or reuse a breakpoint.  If asked, set the condition
+            # or the ignore count.  Catch errors coming from gdb and
+            # report these as an "unverified" breakpoint.
+            bp = None
+            try:
+                if keyspec in saved_map:
+                    bp = saved_map.pop(keyspec)
+                else:
                     bp = creator(**spec)
 
-            bp.condition = condition
-            if hit_condition is None:
-                bp.ignore_count = 0
-            else:
-                bp.ignore_count = int(
-                    parse_and_eval(hit_condition, global_context=True)
+                bp.condition = condition
+                if hit_condition is None:
+                    bp.ignore_count = 0
+                else:
+                    bp.ignore_count = int(
+                        parse_and_eval(hit_condition, global_context=True)
+                    )
+
+                # Reaching this spot means success.
+                breakpoint_map[kind][keyspec] = bp
+                result.append(_breakpoint_descriptor(bp))
+            # Exceptions other than gdb.error are possible here.
+            except Exception as e:
+                # Don't normally want to see this, as it interferes with
+                # the test suite.
+                log_stack(LogLevel.FULL)
+                # Maybe the breakpoint was made but setting an attribute
+                # failed.  We still want this to fail.
+                if bp is not None:
+                    bp.delete()
+                # Breakpoint creation failed.
+                result.append(
+                    {
+                        "verified": False,
+                        "reason": "failed",
+                        "message": str(e),
+                    }
                 )
 
-            # Reaching this spot means success.
-            breakpoint_map[kind][keyspec] = bp
-            result.append(_breakpoint_descriptor(bp))
-        # Exceptions other than gdb.error are possible here.
-        except Exception as e:
-            # Don't normally want to see this, as it interferes with
-            # the test suite.
-            log_stack(LogLevel.FULL)
-            # Maybe the breakpoint was made but setting an attribute
-            # failed.  We still want this to fail.
-            if bp is not None:
-                bp.delete()
-            # Breakpoint creation failed.
-            result.append(
-                {
-                    "verified": False,
-                    "message": str(e),
-                }
-            )
-
     # Delete any breakpoints that were not reused.
     for entry in saved_map.values():
         entry.delete()
index 184af16955c92418dea7602c165e127ce64ee075..6783d999621b25c96fd73d8bb2a545f390d2dd55 100644 (file)
@@ -23,16 +23,6 @@ from .server import request, capability
 from .startup import exec_and_log, DAPException
 
 
-# The program being launched, or None.  This should only be accessed
-# from the gdb thread.
-_program = None
-
-
-# True if the program was attached, False otherwise.  This should only
-# be accessed from the gdb thread.
-_attach = False
-
-
 # Any parameters here are necessarily extensions -- DAP requires this
 # from implementations.  Any additions or changes here should be
 # documented in the gdb manual.
@@ -46,10 +36,6 @@ def launch(
     stopAtBeginningOfMainSubprogram: bool = False,
     **extra,
 ):
-    global _program
-    _program = program
-    global _attach
-    _attach = False
     if cwd is not None:
         exec_and_log("cd " + cwd)
     if program is not None:
@@ -64,6 +50,8 @@ def launch(
         inf.clear_env()
         for name, value in env.items():
             inf.set_env(name, value)
+    expect_process("process")
+    exec_and_expect_stop("run")
 
 
 @request("attach")
@@ -74,11 +62,6 @@ def attach(
     target: Optional[str] = None,
     **args,
 ):
-    # Ensure configurationDone does not try to run.
-    global _attach
-    _attach = True
-    global _program
-    _program = program
     if program is not None:
         exec_and_log("file " + program)
     if pid is not None:
@@ -93,9 +76,7 @@ def attach(
 
 
 @capability("supportsConfigurationDoneRequest")
-@request("configurationDone", response=False)
+@request("configurationDone")
 def config_done(**args):
-    global _attach
-    if not _attach:
-        expect_process("process")
-        exec_and_expect_stop("run")
+    # Nothing to do.
+    return None
index 7928aa194245b05f3de8454878120731c89ae4d5..0de361f96bd78cfddf8f3cf67a26c794bef081aa 100644 (file)
@@ -29,7 +29,7 @@ if {[gdb_compile_ada "${srcfile}" "${binfile}" executable debug] != ""} {
   return -1
 }
 
-if {[dap_launch $testfile] == ""} {
+if {[dap_initialize] == ""} {
     return
 }
 
@@ -42,7 +42,11 @@ set obj [dap_check_request_and_response "set breakpoint by line number" \
                  [list s cstuff.c] $line]]
 set line_bpno [dap_get_breakpoint_number $obj]
 
-dap_check_request_and_response "start inferior" configurationDone
+dap_check_request_and_response "configurationDone" configurationDone
+
+if {[dap_launch $testfile] == ""} {
+    return
+}
 dap_wait_for_event_and_check "inferior started" thread "body reason" started
 
 dap_wait_for_event_and_check "stopped at line breakpoint" stopped \
index f543fef47ef6b024b426c7fd5bd5eaf1f952207e..3415da3e9cbd9ebe2a6055e7289b1e4270479b68 100644 (file)
@@ -27,7 +27,7 @@ if {[gdb_compile_ada "${srcfile}" "${binfile}" executable \
     return -1
 }
 
-if {[dap_launch $binfile] == ""} {
+if {[dap_initialize] == ""} {
     return
 }
 
@@ -39,8 +39,11 @@ set obj [dap_check_request_and_response "set breakpoint" \
                  [list s $srcfile] $line]]
 set fn_bpno [dap_get_breakpoint_number $obj]
 
-dap_check_request_and_response "start inferior" configurationDone
+dap_check_request_and_response "configurationDone" configurationDone
 
+if {[dap_launch $binfile] == ""} {
+    return
+}
 dap_wait_for_event_and_check "stopped at breakpoint" stopped \
     "body reason" breakpoint \
     "body hitBreakpointIds" $fn_bpno
index 070deadb3a190cad605dff48652200d307371e46..12004f8fc32009dc48a84e17cc371626f83db3fe 100644 (file)
@@ -25,7 +25,7 @@ if {[gdb_compile_ada "${srcfile}" "${binfile}" executable \
     return -1
 }
 
-if {[dap_launch $binfile] == ""} {
+if {[dap_initialize] == ""} {
     return
 }
 
@@ -37,8 +37,11 @@ set obj [dap_check_request_and_response "set breakpoint" \
                  [list s $srcfile] $line]]
 set fn_bpno [dap_get_breakpoint_number $obj]
 
-dap_check_request_and_response "start inferior" configurationDone
+dap_check_request_and_response "configurationDone" configurationDone
 
+if {[dap_launch $binfile] == ""} {
+    return
+}
 dap_wait_for_event_and_check "stopped at breakpoint" stopped \
     "body reason" breakpoint \
     "body hitBreakpointIds" $fn_bpno
index 0f07fd25aaeff4852dacd057ab1f592c31bdfe4a..d6511733348d78572a518a975bae4005a908a254 100644 (file)
@@ -25,7 +25,7 @@ if {[build_executable ${testfile}.exp $testfile] == -1} {
     return
 }
 
-if {[dap_launch $testfile arguments {a "b c"} env {{DEI something}}] == ""} {
+if {[dap_initialize] == ""} {
     return
 }
 
@@ -36,7 +36,11 @@ set obj [dap_check_request_and_response "set breakpoint by line number" \
                  [list s $srcfile] $line]]
 set line_bpno [dap_get_breakpoint_number $obj]
 
-dap_check_request_and_response "start inferior" configurationDone
+dap_check_request_and_response "configurationDone" configurationDone
+
+if {[dap_launch $testfile arguments {a "b c"} env {{DEI something}}] == ""} {
+    return
+}
 dap_wait_for_event_and_check "inferior started" thread "body reason" started
 
 dap_wait_for_event_and_check "stopped at line breakpoint" stopped \
index 386bf033f34d5fd4742eba2584115639c4d30e6c..6703a97bb7a549f3fce5885348ebd4dceac0def0 100644 (file)
@@ -31,7 +31,7 @@ set remote_python_file [gdb_remote_download host \
 save_vars GDBFLAGS {
     append GDBFLAGS " -iex \"source $remote_python_file\""
 
-    if {[dap_launch $testfile] == ""} {
+    if {[dap_initialize] == ""} {
        return
     }
 }
@@ -43,8 +43,11 @@ set obj [dap_check_request_and_response "set breakpoint by line number" \
                  [list s $srcfile] $line]]
 set line_bpno [dap_get_breakpoint_number $obj]
 
-dap_check_request_and_response "start inferior" configurationDone
+dap_check_request_and_response "configurationDone" configurationDone
 
+if {[dap_launch $testfile] == ""} {
+    return
+}
 dap_wait_for_event_and_check "stopped at line breakpoint" stopped \
     "body reason" breakpoint \
     "body hitBreakpointIds" $line_bpno
index 431ea3d213dda97b45fd2c0d5e1b8da115e0e5da..6ef9a5b0f6e11d0ca62b2e6afe6c4931245637c9 100644 (file)
@@ -25,7 +25,7 @@ if {[build_executable ${testfile}.exp $testfile] == -1} {
     return
 }
 
-if {[dap_launch $testfile] == ""} {
+if {[dap_initialize] == ""} {
     return
 }
 
@@ -72,21 +72,6 @@ if {$ok} {
     fail "check lack of new breakpoint event"
 }
 
-# Check that there are breakpoint locations on each line between FIRST
-# and BREAK.
-set first_line [gdb_get_line_number "FIRST"]
-set last_line [expr {$line - 1}]
-set obj [dap_check_request_and_response "breakpoint locations" \
-            breakpointLocations \
-            [format {o source [o path [%s]] line [i %d] endLine [i %d]} \
-                 [list s $srcfile] $first_line $last_line]]
-# We know gdb returns the lines in sorted order.
-foreach entry [dict get [lindex $obj 0] body breakpoints] {
-    gdb_assert {[dict get $entry line] == $first_line} \
-       "line $first_line in result"
-    incr first_line
-}
-
 # Note that in this request, we add a 'source' field to the
 # SourceBreakpoint object.  This isn't in the spec but it once caused
 # an incorrect exception in the Python code.  See PR dap/30820.
@@ -99,23 +84,15 @@ set obj [dap_check_request_and_response "reset breakpoint by line number" \
 set new_line_bpno [dap_get_breakpoint_number $obj]
 gdb_assert {$new_line_bpno == $line_bpno} "re-setting kept same breakpoint number"
 
-# This uses "&address_breakpoint_here" as the address -- this is a
-# hack because we know how this is implemented under the hood.
-set obj [dap_check_request_and_response "set breakpoint by address" \
-            setInstructionBreakpoints \
-            {o breakpoints [a [o instructionReference [s &address_breakpoint_here]]]}]
-set insn_bpno [dap_get_breakpoint_number $obj]
-
-set response [lindex $obj 0]
-set bplist [dict get $response body breakpoints]
-set insn_pc [dict get [lindex $bplist 0] instructionReference]
+dap_check_request_and_response "configurationDone" configurationDone
 
-dap_check_request_and_response "start inferior" configurationDone
+if {[dap_launch $testfile] == ""} {
+    return
+}
 dap_wait_for_event_and_check "inferior started" thread "body reason" started
 
 # While waiting for the stopped event, we might receive breakpoint changed
-# events indicating some breakpoint addresses were relocated.  Update INSN_PC
-# if necessary.
+# events indicating some breakpoint addresses were relocated.
 lassign [dap_wait_for_event_and_check "stopped at function breakpoint" stopped \
            "body reason" breakpoint \
            "body hitBreakpointIds" $fn_bpno] unused objs
@@ -136,12 +113,32 @@ foreach obj $objs {
 
     set breakpoint [dict get $body "breakpoint"]
     set breakpoint_id [dict get $breakpoint "id"]
+}
 
-    if { $breakpoint_id != $insn_bpno } {
-       continue
-    }
+# This uses "&address_breakpoint_here" as the address -- this is a
+# hack because we know how this is implemented under the hood.
+set obj [dap_check_request_and_response "set breakpoint by address" \
+            setInstructionBreakpoints \
+            {o breakpoints [a [o instructionReference [s &address_breakpoint_here]]]}]
+set insn_bpno [dap_get_breakpoint_number $obj]
+
+set response [lindex $obj 0]
+set bplist [dict get $response body breakpoints]
+set insn_pc [dict get [lindex $bplist 0] instructionReference]
 
-    set insn_pc [dict get $breakpoint "instructionReference"]
+# Check that there are breakpoint locations on each line between FIRST
+# and BREAK.
+set first_line [gdb_get_line_number "FIRST"]
+set last_line [expr {$line - 1}]
+set obj [dap_check_request_and_response "breakpoint locations" \
+            breakpointLocations \
+            [format {o source [o path [%s]] line [i %d] endLine [i %d]} \
+                 [list s $srcfile] $first_line $last_line]]
+# We know gdb returns the lines in sorted order.
+foreach entry [dict get [lindex $obj 0] body breakpoints] {
+    gdb_assert {[dict get $entry line] == $first_line} \
+       "line $first_line in result"
+    incr first_line
 }
 
 set obj [dap_check_request_and_response "evaluate global in function" \
index 57d4dacaedc3a687f9edd9d93df3cb404d5c97e7..550b9c5c5ac242c0449d49bf7b38140680d42683 100644 (file)
@@ -27,7 +27,7 @@ if {[build_executable_from_specs $testfile.exp $testfile {} \
     return
 }
 
-if {[dap_launch $testfile] == ""} {
+if {[dap_initialize] == ""} {
     return
 }
 
@@ -36,7 +36,11 @@ set obj [dap_check_request_and_response "set breakpoint on inner" \
             {o breakpoints [a [o name [s function_breakpoint_here]]]}]
 set fn_bpno [dap_get_breakpoint_number $obj]
 
-dap_check_request_and_response "start inferior" configurationDone
+dap_check_request_and_response "configurationDone" configurationDone
+
+if {[dap_launch $testfile] == ""} {
+    return
+}
 dap_wait_for_event_and_check "inferior started" thread "body reason" started
 
 lassign [dap_wait_for_event_and_check "stopped at function breakpoint" stopped \
index 8ca0a83ec718aee763606dd2fd81e0e67d48e983..166b862f9a7dfed31e5e5073ee2f89adba39e318 100644 (file)
@@ -25,7 +25,7 @@ if {[gdb_compile_ada "${srcfile}" "${binfile}" executable \
     return -1
 }
 
-if {[dap_launch $binfile] == ""} {
+if {[dap_initialize] == ""} {
     return
 }
 
@@ -61,8 +61,11 @@ foreach spec $bps {
     incr i
 }
 
-dap_check_request_and_response "start inferior" configurationDone
+dap_check_request_and_response "configurationDone" configurationDone
 
+if {[dap_launch $binfile] == ""} {
+    return
+}
 dap_wait_for_event_and_check "stopped at first raise" stopped \
     "body reason" breakpoint \
     "body hitBreakpointIds" 2
index b2444e06fb6838158c0da9813f7b87309d980319..f5dfe2cbb91e57183989a63b61351ec332f71d30 100644 (file)
@@ -31,7 +31,7 @@ set remote_python_file [gdb_remote_download host \
 save_vars GDBFLAGS {
     append GDBFLAGS " -iex \"source $remote_python_file\""
 
-    if {[dap_launch $testfile] == ""} {
+    if {[dap_initialize] == ""} {
        return
     }
 }
@@ -43,8 +43,11 @@ set obj [dap_check_request_and_response "set breakpoint by line number" \
                  [list s $srcfile] $line]]
 set line_bpno [dap_get_breakpoint_number $obj]
 
-dap_check_request_and_response "start inferior" configurationDone
+dap_check_request_and_response "configurationDone" configurationDone
 
+if {[dap_launch $testfile] == ""} {
+    return
+}
 dap_wait_for_event_and_check "stopped at line breakpoint" stopped \
     "body reason" breakpoint \
     "body hitBreakpointIds" $line_bpno
index 427776a5cbbde4821d9ec29d92a1cd7e73638da0..2bd52ba83a0d6d62b56e3616b0998ffb7f3d2f2b 100644 (file)
@@ -25,7 +25,7 @@ if {[build_executable ${testfile}.exp $testfile] == -1} {
     return
 }
 
-if {[dap_launch $testfile] == ""} {
+if {[dap_initialize] == ""} {
     return
 }
 
@@ -44,8 +44,13 @@ set i 1
 foreach bp [dict get [lindex $obj 0] body breakpoints] {
     gdb_assert {[dict get $bp verified] == "false"} \
        "breakpoint $i invalid"
-    gdb_assert {[dict get $bp message] != ""} \
-       "breakpoint $i has message"
+    if {$i == 1} {
+       gdb_assert {[dict get $bp reason] == "pending"} \
+           "breakpoint $i pending"
+    } else {
+       gdb_assert {[dict get $bp message] != ""} \
+           "breakpoint $i has message"
+    }
     incr i
 }
 
@@ -58,8 +63,11 @@ set obj [dap_check_request_and_response "set conditional breakpoint" \
                  [list s $srcfile] $line]]
 set fn_bpno [dap_get_breakpoint_number $obj]
 
-dap_check_request_and_response "start inferior" configurationDone
+dap_check_request_and_response "configurationDone" configurationDone
 
+if {[dap_launch $testfile] == ""} {
+    return
+}
 dap_wait_for_event_and_check "stopped at function breakpoint" stopped \
     "body reason" breakpoint \
     "body hitBreakpointIds" $fn_bpno
index 9e1d070435b8abf367b098fc7a33ddc4dc642331..6b8829965c522c7e34fea0e93566e42f07c8dcba 100644 (file)
@@ -25,6 +25,12 @@ if {[build_executable ${testfile}.exp $testfile $srcfile] == -1} {
     return
 }
 
+if {[dap_initialize] == ""} {
+    return
+}
+
+dap_check_request_and_response "configurationDone" configurationDone
+
 # 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]
@@ -32,7 +38,6 @@ 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
index 284aef4000973613a902a2ebdedc7c90db3797b7..b54b11a2c9afc8b8cebf50134c6256fb1aaaba7c 100644 (file)
@@ -24,7 +24,7 @@ if {[build_executable ${testfile}.exp $testfile $srcfile {debug c++}] == -1} {
     return
 }
 
-if {[dap_launch $testfile] == ""} {
+if {[dap_initialize] == ""} {
     return
 }
 
@@ -37,8 +37,11 @@ set bps [dict get [lindex $obj 0] body breakpoints]
 # breakpoints.
 gdb_assert {[llength $bps] == 3} "three breakpoints"
 
-dap_check_request_and_response "start inferior" configurationDone
+dap_check_request_and_response "configurationDone" configurationDone
 
+if {[dap_launch $testfile] == ""} {
+    return
+}
 dap_wait_for_event_and_check "stopped at throw" stopped \
     "body reason" breakpoint \
     "body hitBreakpointIds" 1
index 139c17ad3354212e5acac1430e5db3c7723aa2a7..9c17725c0d0e81e621371a8c678aad9741a8393d 100644 (file)
@@ -26,7 +26,7 @@ if {[build_executable ${testfile}.exp $testfile $srcfile] == -1} {
     return
 }
 
-if {[dap_launch $testfile] == ""} {
+if {[dap_initialize] == ""} {
     return
 }
 
index 9d25fc5902d06300bc2d3c7c0db0867c402991b9..63ee521af656ae441a9a211f7af687d55d2ecf87 100644 (file)
@@ -25,7 +25,7 @@ if {[build_executable ${testfile}.exp $testfile] == -1} {
     return
 }
 
-if {[dap_launch $testfile] == ""} {
+if {[dap_initialize] == ""} {
     return
 }
 
@@ -36,9 +36,12 @@ set obj [dap_check_request_and_response "set breakpoint by line number" \
                  [list s $srcfile] $line]]
 set line_bpno [dap_get_breakpoint_number $obj]
 
-dap_check_request_and_response "start inferior" configurationDone
-dap_wait_for_event_and_check "inferior started" thread "body reason" started
+dap_check_request_and_response "configurationDone" configurationDone
 
+if {[dap_launch $testfile] == ""} {
+    return
+}
+dap_wait_for_event_and_check "inferior started" thread "body reason" started
 dap_wait_for_event_and_check "stopped at line breakpoint" stopped \
     "body reason" breakpoint \
     "body hitBreakpointIds" $line_bpno
index f7b9fd702adb020b82380370fa302d190eec5623..0c80650b152e3636244aba0f8a9df007b8d26cf0 100644 (file)
@@ -25,7 +25,7 @@ if {[build_executable ${testfile}.exp $testfile] == -1} {
     return
 }
 
-if {[dap_launch $testfile] == ""} {
+if {[dap_initialize] == ""} {
     return
 }
 
@@ -36,7 +36,11 @@ set obj [dap_check_request_and_response "set breakpoint by line number" \
                  [list s $srcfile] $line]]
 set line_bpno [dap_get_breakpoint_number $obj]
 
-dap_check_request_and_response "start inferior" configurationDone
+dap_check_request_and_response "configurationDone" configurationDone
+
+if {[dap_launch $testfile] == ""} {
+    return
+}
 dap_wait_for_event_and_check "inferior started" thread "body reason" started
 
 dap_wait_for_event_and_check "stopped at breakpoint" stopped \
index 0249f142a6e3b1fc4318dbac3febd83203a21d62..54422209fdacbda59c9b932991733377e4b07351 100644 (file)
@@ -31,7 +31,7 @@ set remote_python_file [gdb_remote_download host \
 save_vars GDBFLAGS {
     append GDBFLAGS " -iex \"source $remote_python_file\""
 
-    if {[dap_launch $testfile] == ""} {
+    if {[dap_initialize] == ""} {
        return
     }
 }
@@ -43,8 +43,11 @@ set obj [dap_check_request_and_response "set breakpoint by line number" \
                  [list s $srcfile] $line]]
 set line_bpno [dap_get_breakpoint_number $obj]
 
-dap_check_request_and_response "start inferior" configurationDone
+dap_check_request_and_response "configurationDone" configurationDone
 
+if {[dap_launch $testfile] == ""} {
+    return
+}
 dap_wait_for_event_and_check "stopped at line breakpoint" stopped \
     "body reason" breakpoint \
     "body hitBreakpointIds" $line_bpno
index 4e3ecb7807bb7050493c5d490a1bc78567a94468..e966b962a7128d43943c8d2aca420eb9603ded75 100644 (file)
@@ -25,7 +25,7 @@ if {[build_executable ${testfile}.exp $testfile] == -1} {
     return
 }
 
-if {[dap_launch $testfile] == ""} {
+if {[dap_initialize] == ""} {
     return
 }
 
@@ -38,7 +38,11 @@ set obj [dap_check_request_and_response "set breakpoint" \
                  [list s $srcfile] $line]]
 set fn_bpno [dap_get_breakpoint_number $obj]
 
-dap_check_request_and_response "start inferior" configurationDone
+dap_check_request_and_response "configurationDone" configurationDone
+
+if {[dap_launch $testfile] == ""} {
+    return
+}
 dap_wait_for_event_and_check "inferior started" thread "body reason" started
 
 dap_wait_for_event_and_check "logging output" output \
index 481ab628be9a1be37d1b85d389d0b98f8eeb65a0..2e911f4dc773e8df36a3f4c8c2bb32ee4ad2bcd6 100644 (file)
@@ -25,7 +25,7 @@ if {[build_executable ${testfile}.exp $testfile] == -1} {
     return
 }
 
-if {[dap_launch $testfile] == ""} {
+if {[dap_initialize] == ""} {
     return
 }
 
@@ -36,7 +36,11 @@ set obj [dap_check_request_and_response "set breakpoint by line number" \
                  [list s $srcfile] $line]]
 set line_bpno [dap_get_breakpoint_number $obj]
 
-dap_check_request_and_response "start inferior" configurationDone
+dap_check_request_and_response "configurationDone" configurationDone
+
+if {[dap_launch $testfile] == ""} {
+    return
+}
 dap_wait_for_event_and_check "inferior started" thread "body reason" started
 
 dap_wait_for_event_and_check "stopped at line breakpoint" stopped \
index 4d53b90fa96f95a0eda5d6ead39e4a3c4ac3cba2..87cebda7131f2ac829f1c3c5479ce87ec7eff54a 100644 (file)
@@ -38,7 +38,7 @@ if {[build_executable ${testfile}.exp $testfile $srcfile \
     return
 }
 
-if {[dap_launch $testfile] == ""} {
+if {[dap_initialize] == ""} {
     return
 }
 
@@ -47,8 +47,11 @@ set obj [dap_check_request_and_response "set breakpoint on stop function" \
             {o breakpoints [a [o name [s stop]]]}]
 set fn_bpno [dap_get_breakpoint_number $obj]
 
-dap_check_request_and_response "start inferior" configurationDone
+dap_check_request_and_response "configurationDone" configurationDone
 
+if {[dap_launch $testfile] == ""} {
+    return
+}
 dap_wait_for_event_and_check "stopped at function breakpoint" stopped \
     "body reason" breakpoint \
     "body hitBreakpointIds" $fn_bpno
index e1e0d957fc6a08fad441985770701aeb7d5f7fa4..4d13dadd3ad157e60de0779a1fcc9bf036acfd13 100644 (file)
@@ -25,7 +25,7 @@ if {[build_executable ${testfile}.exp $testfile $srcfile] == -1} {
     return
 }
 
-if {[dap_launch $testfile] == ""} {
+if {[dap_initialize] == ""} {
     return
 }
 
@@ -41,7 +41,11 @@ dap_check_request_and_response "set conditional breakpoint" \
                                     condition [s "return_false()"]]]} \
         [list s $srcfile] $line]
 
-dap_check_request_and_response "start inferior" configurationDone
+dap_check_request_and_response "configurationDone" configurationDone
+
+if {[dap_launch $testfile] == ""} {
+    return
+}
 dap_wait_for_event_and_check "process event generated" process \
     "body startMethod" process
 dap_wait_for_event_and_check "inferior started" thread "body reason" started
index bcdbc5bb56c2325427346c0e50e8a03bd7ec5dc1..0552c3b98159bdea124ce3c03bb7d4c3170422bf 100644 (file)
@@ -23,7 +23,7 @@ if {[build_executable ${testfile}.exp $testfile $srcfile {debug c++}] == -1} {
     return
 }
 
-if {[dap_launch $testfile] == ""} {
+if {[dap_initialize] == ""} {
     return
 }
 
@@ -34,7 +34,11 @@ set obj [dap_check_request_and_response "set breakpoint by line number" \
                  [list s $srcfile] $line]]
 set line_bpno [dap_get_breakpoint_number $obj]
 
-dap_check_request_and_response "start inferior" configurationDone
+dap_check_request_and_response "configurationDone" configurationDone
+
+if {[dap_launch $testfile] == ""} {
+    return
+}
 dap_wait_for_event_and_check "inferior started" thread "body reason" started
 
 dap_wait_for_event_and_check "stopped at line breakpoint" stopped \
index 8a8c79c7088131931291975839d2888eb6d7efdb..c85568d69ea2d181c3f85b2480bfb2565bc6f829 100644 (file)
@@ -28,7 +28,7 @@ if {[build_executable ${testfile}.exp $testfile $srcfile {debug rust}] == -1} {
     return
 }
 
-if {[dap_launch $testfile] == ""} {
+if {[dap_initialize] == ""} {
     return
 }
 
@@ -39,7 +39,11 @@ set obj [dap_check_request_and_response "set breakpoint by line number" \
                  [list s $srcfile] $line]]
 set line_bpno [dap_get_breakpoint_number $obj]
 
-dap_check_request_and_response "start inferior" configurationDone
+dap_check_request_and_response "configurationDone" configurationDone
+
+if {[dap_launch $testfile] == ""} {
+    return
+}
 dap_wait_for_event_and_check "inferior started" thread "body reason" started
 
 dap_wait_for_event_and_check "stopped at line breakpoint" stopped \
index 0b0727cd875a256708966e9f0320573dd83282ad..aa3bb688c0e85f0492b578b40f3d235a1a4fb95f 100644 (file)
@@ -25,7 +25,7 @@ if {[build_executable ${testfile}.exp $testfile] == -1} {
     return
 }
 
-if {[dap_launch $testfile] == ""} {
+if {[dap_initialize] == ""} {
     return
 }
 
@@ -36,7 +36,11 @@ set obj [dap_check_request_and_response "set breakpoint by line number" \
                  [list s $srcfile] $line]]
 set line_bpno [dap_get_breakpoint_number $obj]
 
-dap_check_request_and_response "start inferior" configurationDone
+dap_check_request_and_response "configurationDone" configurationDone
+
+if {[dap_launch $testfile] == ""} {
+    return
+}
 dap_wait_for_event_and_check "inferior started" thread "body reason" started
 
 dap_wait_for_event_and_check "stopped at line breakpoint" stopped \
index 670084e56cf11397862866374252e4c4fdcf2649..b60681160af28b1c4bce0749842c46691652d51e 100644 (file)
@@ -25,6 +25,10 @@ if {[build_executable ${testfile}.exp $testfile] == -1} {
     return
 }
 
+if {[dap_initialize] == ""} {
+    return
+}
+
 if {[dap_launch $testfile stop_at_main 1] == ""} {
     return
 }
index af9d6d02efa8e719aff8b88b4e061a202b11fae5..b81183a016ebb8b1aa0bbf571d602ab4de26ebab 100644 (file)
@@ -31,7 +31,7 @@ set remote_python_file [gdb_remote_download host \
 save_vars GDBFLAGS {
     append GDBFLAGS " -iex \"source $remote_python_file\""
 
-    if {[dap_launch $testfile] == ""} {
+    if {[dap_initialize] == ""} {
        return
     }
 }
@@ -43,8 +43,11 @@ set obj [dap_check_request_and_response "set breakpoint by line number" \
                  [list s $srcfile] $line]]
 set line_bpno [dap_get_breakpoint_number $obj]
 
-dap_check_request_and_response "start inferior" configurationDone
+dap_check_request_and_response "configurationDone" configurationDone
 
+if {[dap_launch $testfile] == ""} {
+    return
+}
 dap_wait_for_event_and_check "stopped at line breakpoint" stopped \
     "body reason" breakpoint \
     "body hitBreakpointIds" $line_bpno
index f7eb9ac7a0da3fc5889f66dc1ca2491cfa526a79..4c3e57a23e4407443f72c43d51be49c4e5a06607 100644 (file)
@@ -25,11 +25,15 @@ if {[build_executable ${testfile}.exp $testfile $srcfile] == -1} {
     return
 }
 
-if {[dap_launch $testfile stop_at_main 1] == ""} {
+if {[dap_initialize] == ""} {
     return
 }
 
 dap_check_request_and_response "start inferior" configurationDone
+
+if {[dap_launch $testfile stop_at_main 1] == ""} {
+    return
+}
 # 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
index 9c3706447dc02d2af095a73251fd57f5aa9e6a1c..90d01945a64cec480258612694dc4c84ab02ebe9 100644 (file)
@@ -27,11 +27,15 @@ if {[build_executable ${testfile}.exp $testfile $srcfile] == -1} {
     return
 }
 
-if {[dap_launch $testfile] == ""} {
+if {[dap_initialize] == ""} {
     return
 }
 
 dap_check_request_and_response "start inferior" configurationDone
+
+if {[dap_launch $testfile] == ""} {
+    return
+}
 dap_wait_for_event_and_check "inferior started" thread "body reason" started
 
 dap_wait_for_event_and_check "terminated event" terminated
index 07259862b18b36cd05aca1d4260b6dfb35ae3594..979dfa2cd73989e5e486582107cb6811f177b665 100644 (file)
@@ -235,10 +235,9 @@ proc dap_check_request_and_response {name command {obj {}}} {
 
 # Start gdb, send a DAP initialization request and return the
 # response.  This approach lets the caller check the feature list, if
-# desired.  Callers not caring about this should probably use
-# dap_launch.  Returns the empty string on failure.  NAME is used as
-# the test name.
-proc dap_initialize {name} {
+# desired.  Returns the empty string on failure.  NAME is used as the
+# test name.
+proc dap_initialize {{name "initialize"}} {
     if {[dap_gdb_start]} {
        return ""
     }
@@ -249,11 +248,12 @@ proc dap_initialize {name} {
                     supportsMemoryReferences [l true]}]
 }
 
-# Start gdb, send a DAP initialize request, and then a launch request
-# specifying FILE as the program to use for the inferior.  Returns the
-# empty string on failure, or the response object from the launch
-# request.  If specified, ARGS is a dictionary of key-value pairs,
-# each passed to the launch request.  Valid keys are:
+# Send a launch request specifying FILE as the program to use for the
+# inferior.  Returns the empty string on failure, or the response
+# object from the launch request.  If specified, ARGS is a dictionary
+# of key-value pairs, each passed to the launch request.  Valid keys
+# are:
+#
 # * arguments - value is a list of strings passed as command-line
 #   arguments to the inferior
 # * env - value is a list of pairs of the form {VAR VALUE} that is
@@ -266,9 +266,6 @@ proc dap_initialize {name} {
 # After this proc is called, gdb will be ready to accept breakpoint
 # requests.
 proc dap_launch {file {args {}}} {
-    if {[dap_initialize "startup - initialize"] == ""} {
-       return ""
-    }
     set params "o program"
     append params " [format {[%s]} [list s [standard_output_file $file]]]"