package shared import ( "fmt" "os" "os/exec" "strings" "syscall" ) var ( isDebugging bool ) // Finds the Delve binary to use. Either uses the SOONG_DELVE_PATH environment // variable or if that is unset, looks at $PATH. func ResolveDelveBinary() string { result := os.Getenv("SOONG_DELVE_PATH") if result == "" { result, _ = exec.LookPath("dlv") } return result } // Returns whether the current process is running under Delve due to // ReexecWithDelveMaybe(). func IsDebugging() bool { return isDebugging } // Re-executes the binary in question under the control of Delve when // delveListen is not the empty string. delvePath gives the path to the Delve. func ReexecWithDelveMaybe(delveListen, delvePath string) { isDebugging = os.Getenv("SOONG_DELVE_REEXECUTED") == "true" if isDebugging || delveListen == "" { return } if delvePath == "" { fmt.Fprintln(os.Stderr, "Delve debugging requested but failed to find dlv") os.Exit(1) } soongDelveEnv := []string{} for _, env := range os.Environ() { idx := strings.IndexRune(env, '=') if idx != -1 { soongDelveEnv = append(soongDelveEnv, env) } } soongDelveEnv = append(soongDelveEnv, "SOONG_DELVE_REEXECUTED=true") dlvArgv := []string{ delvePath, "--listen=:" + delveListen, "--headless=true", "--api-version=2", "exec", os.Args[0], "--", } dlvArgv = append(dlvArgv, os.Args[1:]...) syscall.Exec(delvePath, dlvArgv, soongDelveEnv) fmt.Fprintln(os.Stderr, "exec() failed while trying to reexec with Delve") os.Exit(1) }