diff --git a/Documentation/usage/dlv_replay.md b/Documentation/usage/dlv_replay.md index fcc995b8..8cec2ef9 100644 --- a/Documentation/usage/dlv_replay.md +++ b/Documentation/usage/dlv_replay.md @@ -17,7 +17,8 @@ dlv replay [trace directory] [flags] ### Options ``` - -h, --help help for replay + -h, --help help for replay + -p, --onprocess int Pass onprocess pid to rr. ``` ### Options inherited from parent commands diff --git a/cmd/dlv/cmds/commands.go b/cmd/dlv/cmds/commands.go index e27653fd..c98c047b 100644 --- a/cmd/dlv/cmds/commands.go +++ b/cmd/dlv/cmds/commands.go @@ -91,6 +91,8 @@ var ( conf *config.Config loadConfErr error + + rrOnProcessPid int ) const dlvCommandLongDesc = `Delve is a source level debugger for Go programs. @@ -368,6 +370,10 @@ https://github.com/mozilla/rr os.Exit(execute(0, []string{}, conf, args[0], debugger.ExecutingOther, args, buildFlags)) }, } + + replayCommand.Flags().IntVarP(&rrOnProcessPid, "onprocess", "p", 0, + "Pass onprocess pid to rr.") + rootCommand.AddCommand(replayCommand) } @@ -981,6 +987,7 @@ func execute(attachPid int, processArgs []string, conf *config.Config, coreFile TTY: tty, Redirects: redirects, DisableASLR: disableASLR, + RrOnProcessPid: rrOnProcessPid, }, }) default: diff --git a/pkg/proc/gdbserial/rr.go b/pkg/proc/gdbserial/rr.go index 52a32080..ca70850b 100644 --- a/pkg/proc/gdbserial/rr.go +++ b/pkg/proc/gdbserial/rr.go @@ -124,12 +124,21 @@ func Record(cmd []string, wd string, quiet bool, redirects [3]string) (tracedir // Replay starts an instance of rr in replay mode, with the specified trace // directory, and connects to it. -func Replay(tracedir string, quiet, deleteOnDetach bool, debugInfoDirs []string) (*proc.TargetGroup, error) { +func Replay(tracedir string, quiet, deleteOnDetach bool, debugInfoDirs []string, rrOnProcessPid int) (*proc.TargetGroup, error) { if err := checkRRAvailable(); err != nil { return nil, err } - rrcmd := exec.Command("rr", "replay", "--dbgport=0", tracedir) + args := []string{ + "replay", + "--dbgport=0", + } + if rrOnProcessPid != 0 { + args = append(args, fmt.Sprintf("--onprocess=%d", rrOnProcessPid)) + } + args = append(args, tracedir) + + rrcmd := exec.Command("rr", args...) rrcmd.Stdout = os.Stdout stderr, err := rrcmd.StderrPipe() if err != nil { @@ -284,7 +293,7 @@ func RecordAndReplay(cmd []string, wd string, quiet bool, debugInfoDirs []string if tracedir == "" { return nil, "", err } - t, err := Replay(tracedir, quiet, true, debugInfoDirs) + t, err := Replay(tracedir, quiet, true, debugInfoDirs, 0) return t, tracedir, err } diff --git a/service/debugger/debugger.go b/service/debugger/debugger.go index 64b15564..c58eeb2b 100644 --- a/service/debugger/debugger.go +++ b/service/debugger/debugger.go @@ -141,6 +141,8 @@ type Config struct { // DisableASLR disables ASLR DisableASLR bool + + RrOnProcessPid int } // New creates a new Debugger. ProcessArgs specify the commandline arguments for the @@ -174,7 +176,7 @@ func New(config *Config, processArgs []string) (*Debugger, error) { switch d.config.Backend { case "rr": d.log.Infof("opening trace %s", d.config.CoreFile) - d.target, err = gdbserial.Replay(d.config.CoreFile, false, false, d.config.DebugInfoDirectories) + d.target, err = gdbserial.Replay(d.config.CoreFile, false, false, d.config.DebugInfoDirectories, d.config.RrOnProcessPid) default: d.log.Infof("opening core file %s (executable %s)", d.config.CoreFile, d.processArgs[0]) d.target, err = core.OpenCore(d.config.CoreFile, d.processArgs[0], d.config.DebugInfoDirectories) @@ -333,7 +335,7 @@ func (d *Debugger) recordingRun(run func() (string, error)) (*proc.TargetGroup, return nil, err } - return gdbserial.Replay(tracedir, false, true, d.config.DebugInfoDirectories) + return gdbserial.Replay(tracedir, false, true, d.config.DebugInfoDirectories, 0) } // Attach will attach to the process specified by 'pid'.