diff options
Diffstat (limited to 'shared/debug.go')
-rw-r--r-- | shared/debug.go | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/shared/debug.go b/shared/debug.go new file mode 100644 index 000000000..5392f2b79 --- /dev/null +++ b/shared/debug.go @@ -0,0 +1,69 @@ +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) +} |