fix(debug): handle mapping edges, stray traps and dying debuggees
Assisted-by: GLM 5.3
This commit is contained in:
@@ -7,6 +7,7 @@ package debug
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/bits"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
@@ -83,7 +84,10 @@ func (s *Session) setDbRegs(dr *dbreg) error {
|
||||
// EXCP_SOFTSTP_EL0/EXCP_WATCHPT_EL0 with TRAP_TRACE (sys/arm64/arm64/
|
||||
// trap.c); the watchpoint address rides the FAR register, so a stop whose
|
||||
// reported address falls inside an armed watchpoint's byte range is a
|
||||
// watchpoint and everything else is a single step.
|
||||
// watchpoint and everything else is a single step. The byte range comes
|
||||
// from DBGWCR's byte-address-select bits (ARM DDI 0487, DBGWCR<n>_EL1):
|
||||
// bit i watches the address plus i, so the range spans the lowest set bit
|
||||
// to the highest set bit inclusive.
|
||||
func archStopTrace(s *Session, siAddr uint64) (StopReason, uint64) {
|
||||
dr, err := s.getDbRegs()
|
||||
if err != nil {
|
||||
@@ -94,7 +98,14 @@ func archStopTrace(s *Session, siAddr uint64) (StopReason, uint64) {
|
||||
if ctrl&1 == 0 || dr.DbWatchregs[slot].Addr == 0 {
|
||||
continue
|
||||
}
|
||||
if bas := (ctrl >> 5) & 0xFF; bas != 0 && siAddr >= dr.DbWatchregs[slot].Addr && siAddr < dr.DbWatchregs[slot].Addr+8 {
|
||||
bas := uint8((ctrl >> 5) & 0xFF)
|
||||
if bas == 0 {
|
||||
continue
|
||||
}
|
||||
lo := bits.TrailingZeros8(bas)
|
||||
hi := 7 - bits.LeadingZeros8(bas)
|
||||
addr := dr.DbWatchregs[slot].Addr
|
||||
if siAddr >= addr+uint64(lo) && siAddr < addr+uint64(hi)+1 {
|
||||
return StopWatchpoint, siAddr
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user