1*333d2b36SAndroid Build Coastguard Workerpackage shared 2*333d2b36SAndroid Build Coastguard Worker 3*333d2b36SAndroid Build Coastguard Workerimport ( 4*333d2b36SAndroid Build Coastguard Worker "fmt" 5*333d2b36SAndroid Build Coastguard Worker "os" 6*333d2b36SAndroid Build Coastguard Worker "os/exec" 7*333d2b36SAndroid Build Coastguard Worker "strings" 8*333d2b36SAndroid Build Coastguard Worker "syscall" 9*333d2b36SAndroid Build Coastguard Worker) 10*333d2b36SAndroid Build Coastguard Worker 11*333d2b36SAndroid Build Coastguard Workervar ( 12*333d2b36SAndroid Build Coastguard Worker isDebugging bool 13*333d2b36SAndroid Build Coastguard Worker) 14*333d2b36SAndroid Build Coastguard Worker 15*333d2b36SAndroid Build Coastguard Worker// Finds the Delve binary to use. Either uses the SOONG_DELVE_PATH environment 16*333d2b36SAndroid Build Coastguard Worker// variable or if that is unset, looks at $PATH. 17*333d2b36SAndroid Build Coastguard Workerfunc ResolveDelveBinary() string { 18*333d2b36SAndroid Build Coastguard Worker result := os.Getenv("SOONG_DELVE_PATH") 19*333d2b36SAndroid Build Coastguard Worker if result == "" { 20*333d2b36SAndroid Build Coastguard Worker result, _ = exec.LookPath("dlv") 21*333d2b36SAndroid Build Coastguard Worker } 22*333d2b36SAndroid Build Coastguard Worker 23*333d2b36SAndroid Build Coastguard Worker return result 24*333d2b36SAndroid Build Coastguard Worker} 25*333d2b36SAndroid Build Coastguard Worker 26*333d2b36SAndroid Build Coastguard Worker// Returns whether the current process is running under Delve due to 27*333d2b36SAndroid Build Coastguard Worker// ReexecWithDelveMaybe(). 28*333d2b36SAndroid Build Coastguard Workerfunc IsDebugging() bool { 29*333d2b36SAndroid Build Coastguard Worker return isDebugging 30*333d2b36SAndroid Build Coastguard Worker} 31*333d2b36SAndroid Build Coastguard Worker 32*333d2b36SAndroid Build Coastguard Worker// Re-executes the binary in question under the control of Delve when 33*333d2b36SAndroid Build Coastguard Worker// delveListen is not the empty string. delvePath gives the path to the Delve. 34*333d2b36SAndroid Build Coastguard Workerfunc ReexecWithDelveMaybe(delveListen, delvePath string) { 35*333d2b36SAndroid Build Coastguard Worker isDebugging = os.Getenv("SOONG_DELVE_REEXECUTED") == "true" 36*333d2b36SAndroid Build Coastguard Worker if isDebugging || delveListen == "" { 37*333d2b36SAndroid Build Coastguard Worker return 38*333d2b36SAndroid Build Coastguard Worker } 39*333d2b36SAndroid Build Coastguard Worker 40*333d2b36SAndroid Build Coastguard Worker if delvePath == "" { 41*333d2b36SAndroid Build Coastguard Worker fmt.Fprintln(os.Stderr, "Delve debugging requested but failed to find dlv") 42*333d2b36SAndroid Build Coastguard Worker os.Exit(1) 43*333d2b36SAndroid Build Coastguard Worker } 44*333d2b36SAndroid Build Coastguard Worker 45*333d2b36SAndroid Build Coastguard Worker soongDelveEnv := []string{} 46*333d2b36SAndroid Build Coastguard Worker for _, env := range os.Environ() { 47*333d2b36SAndroid Build Coastguard Worker idx := strings.IndexRune(env, '=') 48*333d2b36SAndroid Build Coastguard Worker if idx != -1 { 49*333d2b36SAndroid Build Coastguard Worker soongDelveEnv = append(soongDelveEnv, env) 50*333d2b36SAndroid Build Coastguard Worker } 51*333d2b36SAndroid Build Coastguard Worker } 52*333d2b36SAndroid Build Coastguard Worker 53*333d2b36SAndroid Build Coastguard Worker soongDelveEnv = append(soongDelveEnv, "SOONG_DELVE_REEXECUTED=true") 54*333d2b36SAndroid Build Coastguard Worker 55*333d2b36SAndroid Build Coastguard Worker dlvArgv := []string{ 56*333d2b36SAndroid Build Coastguard Worker delvePath, 57*333d2b36SAndroid Build Coastguard Worker "--listen=:" + delveListen, 58*333d2b36SAndroid Build Coastguard Worker "--headless=true", 59*333d2b36SAndroid Build Coastguard Worker "--api-version=2", 60*333d2b36SAndroid Build Coastguard Worker "exec", 61*333d2b36SAndroid Build Coastguard Worker os.Args[0], 62*333d2b36SAndroid Build Coastguard Worker "--", 63*333d2b36SAndroid Build Coastguard Worker } 64*333d2b36SAndroid Build Coastguard Worker 65*333d2b36SAndroid Build Coastguard Worker dlvArgv = append(dlvArgv, os.Args[1:]...) 66*333d2b36SAndroid Build Coastguard Worker syscall.Exec(delvePath, dlvArgv, soongDelveEnv) 67*333d2b36SAndroid Build Coastguard Worker fmt.Fprintln(os.Stderr, "exec() failed while trying to reexec with Delve") 68*333d2b36SAndroid Build Coastguard Worker os.Exit(1) 69*333d2b36SAndroid Build Coastguard Worker} 70