mirror of
https://github.com/go-delve/delve.git
synced 2025-10-28 20:53:42 +08:00
Two bugfixes regarding stale executable files, and executables changing between restarts (#689)
* service/debugger: Restore breakpoints using file:line on restart Restoring by address can cause the breakpoint to be inserted in the middle of an instruction if the executable file has changed. * terminal: Warn of stale executable when printing source
This commit is contained in:
committed by
Derek Parker
parent
8f0646e426
commit
f4aaffbbf3
@ -11,6 +11,7 @@ import (
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/derekparker/delve/proc"
|
||||
"github.com/derekparker/delve/service/api"
|
||||
@ -81,6 +82,12 @@ func (d *Debugger) ProcessPid() int {
|
||||
return d.process.Pid
|
||||
}
|
||||
|
||||
// LastModified returns the time that the process' executable was last
|
||||
// modified.
|
||||
func (d *Debugger) LastModified() time.Time {
|
||||
return d.process.LastModified
|
||||
}
|
||||
|
||||
// Detach detaches from the target process.
|
||||
// If `kill` is true we will kill the process after
|
||||
// detaching.
|
||||
@ -100,7 +107,7 @@ func (d *Debugger) detach(kill bool) error {
|
||||
|
||||
// Restart will restart the target process, first killing
|
||||
// and then exec'ing it again.
|
||||
func (d *Debugger) Restart() error {
|
||||
func (d *Debugger) Restart() ([]api.DiscardedBreakpoint, error) {
|
||||
d.processMutex.Lock()
|
||||
defer d.processMutex.Unlock()
|
||||
|
||||
@ -110,30 +117,38 @@ func (d *Debugger) Restart() error {
|
||||
}
|
||||
// Ensure the process is in a PTRACE_STOP.
|
||||
if err := stopProcess(d.ProcessPid()); err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
if err := d.detach(true); err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
p, err := proc.Launch(d.config.ProcessArgs, d.config.WorkingDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not launch process: %s", err)
|
||||
return nil, fmt.Errorf("could not launch process: %s", err)
|
||||
}
|
||||
discarded := []api.DiscardedBreakpoint{}
|
||||
for _, oldBp := range d.breakpoints() {
|
||||
if oldBp.ID < 0 {
|
||||
continue
|
||||
}
|
||||
if len(oldBp.File) > 0 {
|
||||
oldBp.Addr, err = d.process.FindFileLocation(oldBp.File, oldBp.Line)
|
||||
if err != nil {
|
||||
discarded = append(discarded, api.DiscardedBreakpoint{oldBp, err})
|
||||
continue
|
||||
}
|
||||
}
|
||||
newBp, err := p.SetBreakpoint(oldBp.Addr, proc.UserBreakpoint, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
if err := copyBreakpointInfo(newBp, oldBp); err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
d.process = p
|
||||
return nil
|
||||
return discarded, nil
|
||||
}
|
||||
|
||||
// State returns the current state of the debugger.
|
||||
|
||||
Reference in New Issue
Block a user