fix(debug): handle mapping edges, stray traps and dying debuggees

Assisted-by: GLM 5.3
This commit is contained in:
2026-10-02 00:40:54 +02:00
parent dd1782c538
commit f57377abb9
19 changed files with 726 additions and 97 deletions
+13 -2
View File
@@ -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
}
}