Merge "Call Delve using exec() instead of "dlv attach"."
This commit is contained in:
commit
ad37304762
2 changed files with 38 additions and 45 deletions
|
@ -15,9 +15,11 @@
|
|||
package android
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"android/soong/env"
|
||||
)
|
||||
|
@ -30,28 +32,59 @@ import (
|
|||
// a manifest regeneration.
|
||||
|
||||
var originalEnv map[string]string
|
||||
var SoongDelveListen string
|
||||
var SoongDelvePath string
|
||||
var soongDelveListen string
|
||||
var soongDelvePath string
|
||||
var soongDelveEnv []string
|
||||
|
||||
func init() {
|
||||
// Delve support needs to read this environment variable very early, before NewConfig has created a way to
|
||||
// access originalEnv with dependencies. Store the value where soong_build can find it, it will manually
|
||||
// ensure the dependencies are created.
|
||||
SoongDelveListen = os.Getenv("SOONG_DELVE")
|
||||
SoongDelvePath, _ = exec.LookPath("dlv")
|
||||
soongDelveListen = os.Getenv("SOONG_DELVE")
|
||||
soongDelvePath, _ = exec.LookPath("dlv")
|
||||
|
||||
originalEnv = make(map[string]string)
|
||||
soongDelveEnv = []string{}
|
||||
for _, env := range os.Environ() {
|
||||
idx := strings.IndexRune(env, '=')
|
||||
if idx != -1 {
|
||||
originalEnv[env[:idx]] = env[idx+1:]
|
||||
if env[:idx] != "SOONG_DELVE" {
|
||||
soongDelveEnv = append(soongDelveEnv, env)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clear the environment to prevent use of os.Getenv(), which would not provide dependencies on environment
|
||||
// variable values. The environment is available through ctx.Config().Getenv, ctx.Config().IsEnvTrue, etc.
|
||||
os.Clearenv()
|
||||
}
|
||||
|
||||
func ReexecWithDelveMaybe() {
|
||||
if soongDelveListen == "" {
|
||||
return
|
||||
}
|
||||
|
||||
if soongDelvePath == "" {
|
||||
fmt.Fprintln(os.Stderr, "SOONG_DELVE is set but failed to find dlv")
|
||||
os.Exit(1)
|
||||
}
|
||||
dlvArgv := []string{
|
||||
soongDelvePath,
|
||||
"--listen=:" + soongDelveListen,
|
||||
"--headless=true",
|
||||
"--api-version=2",
|
||||
"exec",
|
||||
os.Args[0],
|
||||
"--",
|
||||
}
|
||||
dlvArgv = append(dlvArgv, os.Args[1:]...)
|
||||
os.Chdir(absSrcDir)
|
||||
syscall.Exec(soongDelvePath, dlvArgv, soongDelveEnv)
|
||||
fmt.Fprintln(os.Stderr, "exec() failed while trying to reexec with Delve")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// getenv checks either os.Getenv or originalEnv so that it works before or after the init()
|
||||
// function above. It doesn't add any dependencies on the environment variable, so it should
|
||||
// only be used for values that won't change. For values that might change use ctx.Config().Getenv.
|
||||
|
|
|
@ -18,12 +18,7 @@ import (
|
|||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/google/blueprint/bootstrap"
|
||||
|
||||
|
@ -55,42 +50,7 @@ func newNameResolver(config android.Config) *android.NameResolver {
|
|||
}
|
||||
|
||||
func main() {
|
||||
if android.SoongDelveListen != "" {
|
||||
if android.SoongDelvePath == "" {
|
||||
fmt.Fprintln(os.Stderr, "SOONG_DELVE is set but failed to find dlv")
|
||||
os.Exit(1)
|
||||
}
|
||||
pid := strconv.Itoa(os.Getpid())
|
||||
cmd := []string{android.SoongDelvePath,
|
||||
"attach", pid,
|
||||
"--headless",
|
||||
"-l", android.SoongDelveListen,
|
||||
"--api-version=2",
|
||||
"--accept-multiclient",
|
||||
"--log",
|
||||
}
|
||||
|
||||
fmt.Println("Starting", strings.Join(cmd, " "))
|
||||
dlv := exec.Command(cmd[0], cmd[1:]...)
|
||||
dlv.Stdout = os.Stdout
|
||||
dlv.Stderr = os.Stderr
|
||||
dlv.Stdin = nil
|
||||
|
||||
// Put dlv into its own process group so we can kill it and the child process it starts.
|
||||
dlv.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||
|
||||
err := dlv.Start()
|
||||
if err != nil {
|
||||
// Print the error starting dlv and continue.
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
// Kill the process group for dlv when soong_build exits.
|
||||
defer syscall.Kill(-dlv.Process.Pid, syscall.SIGKILL)
|
||||
// Wait to give dlv a chance to connect and pause the process.
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
android.ReexecWithDelveMaybe()
|
||||
flag.Parse()
|
||||
|
||||
// The top-level Blueprints file is passed as the first argument.
|
||||
|
|
Loading…
Reference in a new issue