Repository: go-delve/delve
Pull request #2618 (2021-07-23 18:38:54)

service/dap: fix backend parsing in replay mode
Replay mode configuration suffered during a rebase, and the issue was not caught by the unittests because there were none testing that replay mode args get set up and passed to `debugger.New` correctly. Because we added backend parsing (#2567) in parallel with replay/core support (#2367), `CoreFile` was set in `replay` mode, but `rr` backend was replaced with `"default"`, so this was treated as a `core` mode instead:
https://github.com/go-delve/delve/blob/658d36cb1909cd4267e538b10f2f84df8f752216/service/debugger/debugger.go#L167-L177

@lggomez 


Patch:
diff --git a/service/dap/server.go b/service/dap/server.go
index 4a5d5b68..ae87eb53 100644
--- a/service/dap/server.go
+++ b/service/dap/server.go
@@ -772,6 +772,20 @@ func (s *Server) onLaunchRequest(request *dap.LaunchRequest) {
 		return
 	}
 
+	backend, ok := request.Arguments["backend"]
+	if ok {
+		backendParsed, ok := backend.(string)
+		if !ok {
+			s.sendErrorResponse(request.Request,
+				FailedToLaunch, "Failed to launch",
+				fmt.Sprintf("'backend' attribute '%v' in debug configuration is not a string.", backend))
+			return
+		}
+		s.config.Debugger.Backend = backendParsed
+	} else {
+		s.config.Debugger.Backend = "default"
+	}
+
 	if mode == "replay" {
 		traceDirPath, _ := request.Arguments["traceDirPath"].(string)
 
@@ -891,20 +905,6 @@ func (s *Server) onLaunchRequest(request *dap.LaunchRequest) {
 		}
 	}
 
-	backend, ok := request.Arguments["backend"]
-	if ok {
-		backendParsed, ok := backend.(string)
-		if !ok {
-			s.sendErrorResponse(request.Request,
-				FailedToLaunch, "Failed to launch",
-				fmt.Sprintf("'backend' attribute '%v' in debug configuration is not a string.", backend))
-			return
-		}
-		s.config.Debugger.Backend = backendParsed
-	} else {
-		s.config.Debugger.Backend = "default"
-	}
-
 	s.config.ProcessArgs = append([]string{program}, targetArgs...)
 	s.config.Debugger.WorkingDir = filepath.Dir(program)
 


Test patch:
diff --git a/service/dap/server_test.go b/service/dap/server_test.go
index 8e1b9903..bb20000c 100644
--- a/service/dap/server_test.go
+++ b/service/dap/server_test.go
@@ -4753,19 +4753,33 @@ func TestBadLaunchRequests(t *testing.T) {
 		client.LaunchRequestWithArgs(map[string]interface{}{"mode": "debug", "program": fixture.Source, "noDebug": true, "cwd": "dir/invalid"})
 		checkFailedToLaunch(client.ExpectErrorResponse(t)) // invalid directory, the error message is system-dependent.
 
-		// Bad parameters on "replay" and "core" modes
+		// Bad "replay" parameters
+		// These errors come from dap layer
 		client.LaunchRequestWithArgs(map[string]interface{}{"mode": "replay", "traceDirPath": ""})
 		checkFailedToLaunchWithMessage(client.ExpectInvisibleErrorResponse(t),
 			"Failed to launch: The 'traceDirPath' attribute is missing in debug configuration.")
-		client.LaunchRequestWithArgs(map[string]interface{}{"mode": "core", "coreFilePath": ""})
-		checkFailedToLaunchWithMessage(client.ExpectInvisibleErrorResponse(t),
-			"Failed to launch: The program attribute is missing in debug configuration.")
 		client.LaunchRequestWithArgs(map[string]interface{}{"mode": "replay", "program": fixture.Source, "traceDirPath": ""})
 		checkFailedToLaunchWithMessage(client.ExpectInvisibleErrorResponse(t),
 			"Failed to launch: The 'traceDirPath' attribute is missing in debug configuration.")
+		// These errors come from debugger layer
+		if _, err := exec.LookPath("rr"); err != nil {
+			client.LaunchRequestWithArgs(map[string]interface{}{"mode": "replay", "backend": "ignored", "traceDirPath": ".."})
+			checkFailedToLaunchWithMessage(client.ExpectInvisibleErrorResponse(t),
+				"Failed to launch: backend unavailable")
+		}
+
+		// Bad "core" parameters
+		// These errors come from dap layer
+		client.LaunchRequestWithArgs(map[string]interface{}{"mode": "core", "coreFilePath": ""})
+		checkFailedToLaunchWithMessage(client.ExpectInvisibleErrorResponse(t),
+			"Failed to launch: The program attribute is missing in debug configuration.")
 		client.LaunchRequestWithArgs(map[string]interface{}{"mode": "core", "program": fixture.Source, "coreFilePath": ""})
 		checkFailedToLaunchWithMessage(client.ExpectInvisibleErrorResponse(t),
 			"Failed to launch: The 'coreFilePath' attribute is missing in debug configuration.")
+		// These errors come from debugger layer
+		client.LaunchRequestWithArgs(map[string]interface{}{"mode": "core", "backend": "ignored", "program": fixture.Source, "coreFilePath": fixture.Source})
+		checkFailedToLaunchWithMessage(client.ExpectInvisibleErrorResponse(t),
+			"Failed to launch: unrecognized core format")
 
 		// We failed to launch the program. Make sure shutdown still works.
 		client.DisconnectRequest()