"net"
"os"
"os/exec"
+ "os/signal"
"path/filepath"
"runtime"
"strings"
lldb.Stdout = os.Stdout
var out bytes.Buffer
lldb.Stderr = io.MultiWriter(&out, os.Stderr)
- err = lldb.Run()
+ err = lldb.Start()
+ if err == nil {
+ // Forward SIGQUIT to the lldb driver which in turn will forward
+ // to the running program.
+ sigs := make(chan os.Signal, 1)
+ signal.Notify(sigs, syscall.SIGQUIT)
+ proc := lldb.Process
+ go func() {
+ for sig := range sigs {
+ proc.Signal(sig)
+ }
+ }()
+ err = lldb.Wait()
+ signal.Stop(sigs)
+ close(sigs)
+ }
// If the program was not started it can be retried without papering over
// real test failures.
started := bytes.HasPrefix(out.Bytes(), []byte("lldb: running program"))
const lldbDriver = `
import sys
import os
+import signal
exe, device_exe, args = sys.argv[1], sys.argv[2], sys.argv[3:]
event = lldb.SBEvent()
running = False
+prev_handler = None
while True:
if not listener.WaitForEvent(1, event):
continue
sys.stderr.write(out)
state = process.GetStateFromEvent(event)
if state in [lldb.eStateCrashed, lldb.eStateDetached, lldb.eStateUnloaded, lldb.eStateExited]:
+ if running:
+ signal.signal(signal.SIGQUIT, prev_handler)
break
elif state == lldb.eStateConnected:
process.RemoteLaunch(args, env, None, None, None, None, 0, False, err)
process.Kill()
debugger.Terminate()
sys.exit(1)
+ # Forward SIGQUIT to the program.
+ def signal_handler(signal, frame):
+ process.Signal(signal)
+ prev_handler = signal.signal(signal.SIGQUIT, signal_handler)
# Tell the Go driver that the program is running and should not be retried.
sys.stderr.write("lldb: running program\n")
running = True