service: fix breakpoint IDs after Restart with disabled breakpoints (#2425)

When restarting we must take care of setting breakpoint IDs correctly
so that enabled breakpoints do not end up having the same ID as a
disabled breakpoint, also we must make sure that breakpoints created
after restart will not get an ID already used by a disabled breakpoint.
This commit is contained in:
Alessandro Arzilli
2021-04-12 23:59:43 +02:00
committed by GitHub
parent f3d7b25fdf
commit 781ad72d62
3 changed files with 56 additions and 6 deletions

View File

@ -509,23 +509,27 @@ func (d *Debugger) Restart(rerecord bool, pos string, resetArgs bool, newArgs []
discarded := []api.DiscardedBreakpoint{}
breakpoints := api.ConvertBreakpoints(d.breakpoints())
d.target = p
maxID := 0
for _, oldBp := range breakpoints {
if oldBp.ID < 0 {
continue
}
if oldBp.ID > maxID {
maxID = oldBp.ID
}
if len(oldBp.File) > 0 {
addrs, err := proc.FindFileLocation(p, oldBp.File, oldBp.Line)
if err != nil {
discarded = append(discarded, api.DiscardedBreakpoint{Breakpoint: oldBp, Reason: err.Error()})
continue
}
createLogicalBreakpoint(d, addrs, oldBp)
createLogicalBreakpoint(d, addrs, oldBp, oldBp.ID)
} else {
// Avoid setting a breakpoint based on address when rebuilding
if rebuild {
continue
}
newBp, err := p.SetBreakpoint(oldBp.Addr, proc.UserBreakpoint, nil)
newBp, err := p.SetBreakpointWithID(oldBp.ID, oldBp.Addr)
if err != nil {
return nil, err
}
@ -534,6 +538,12 @@ func (d *Debugger) Restart(rerecord bool, pos string, resetArgs bool, newArgs []
}
}
}
for _, bp := range d.disabledBreakpoints {
if bp.ID > maxID {
maxID = bp.ID
}
}
d.target.SetNextBreakpointID(maxID)
return discarded, nil
}
@ -652,7 +662,7 @@ func (d *Debugger) CreateBreakpoint(requestedBp *api.Breakpoint) (*api.Breakpoin
return nil, err
}
createdBp, err := createLogicalBreakpoint(d, addrs, requestedBp)
createdBp, err := createLogicalBreakpoint(d, addrs, requestedBp, 0)
if err != nil {
return nil, err
}
@ -662,7 +672,7 @@ func (d *Debugger) CreateBreakpoint(requestedBp *api.Breakpoint) (*api.Breakpoin
// createLogicalBreakpoint creates one physical breakpoint for each address
// in addrs and associates all of them with the same logical breakpoint.
func createLogicalBreakpoint(d *Debugger, addrs []uint64, requestedBp *api.Breakpoint) (*api.Breakpoint, error) {
func createLogicalBreakpoint(d *Debugger, addrs []uint64, requestedBp *api.Breakpoint, id int) (*api.Breakpoint, error) {
p := d.target
if dbp, ok := d.disabledBreakpoints[requestedBp.ID]; ok {
@ -672,7 +682,11 @@ func createLogicalBreakpoint(d *Debugger, addrs []uint64, requestedBp *api.Break
bps := make([]*proc.Breakpoint, len(addrs))
var err error
for i := range addrs {
bps[i], err = p.SetBreakpoint(addrs[i], proc.UserBreakpoint, nil)
if id > 0 {
bps[i], err = p.SetBreakpointWithID(id, addrs[i])
} else {
bps[i], err = p.SetBreakpoint(addrs[i], proc.UserBreakpoint, nil)
}
if err != nil {
break
}
@ -871,7 +885,7 @@ func (d *Debugger) FindBreakpoint(id int) *api.Breakpoint {
func (d *Debugger) findBreakpoint(id int) []*proc.Breakpoint {
var bps []*proc.Breakpoint
for _, bp := range d.target.Breakpoints().M {
if bp.LogicalID == id {
if bp.IsUser() && bp.LogicalID == id {
bps = append(bps, bp)
}
}