Files
gasm-sdk/debug/stopinfo_linux.go
T

78 lines
2.1 KiB
Go
Raw Normal View History

// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
// SPDX-License-Identifier: BSD-3-Clause
//go:build linux
package debug
import (
"encoding/binary"
"syscall"
"unsafe"
)
// StopReason describes why the debuggee stopped.
type StopReason int
const (
StopNone StopReason = iota
StopBreakpoint // software breakpoint hit
StopWatchpoint // hardware watchpoint triggered
StopSingleStep // single-step completed
StopSignal // stopped by a signal
StopExited // process exited
)
// siginfo_t layout (Linux): si_signo, si_errno, si_code, then union.
// The si_addr field is at offset 16 on all supported architectures.
type siginfoT struct {
SiSigno int32
SiErrno int32
SiCode int32
_pad [125]byte
}
const (
trapBRKPT = 1 // software breakpoint
trapHWBRKPT = 4 // hardware watchpoint
)
// StopInfo returns the reason the debuggee stopped and the faulting address
// (for watchpoints, the watched address that was accessed).
func (s *Session) StopInfo() (StopReason, uint64) {
if s.exited {
return StopExited, 0
}
var info siginfoT
_, _, errno := syscall.Syscall6(
syscall.SYS_PTRACE,
uintptr(syscall.PTRACE_GETSIGINFO),
uintptr(s.pid),
0,
uintptr(unsafe.Pointer(&info)),
0, 0,
)
if errno != 0 {
return StopNone, 0
}
if info.SiSigno != int32(syscall.SIGTRAP) {
return StopSignal, uint64(info.SiCode)
}
switch info.SiCode {
case trapBRKPT:
return StopBreakpoint, 0
case trapHWBRKPT:
// si_addr sits at struct offset 16 (12 bytes of signo/errno/code
// plus 4 bytes of union alignment). The siginfo buffer is only
// 4-byte aligned, so the address is read byte-wise to keep the
// load aligned on riscv64 and loong64. What si_addr names is
// architecture-specific (the data address on arm64, the
// instruction pointer on x86), so the per-architecture
// archWatchpointAddr resolves it to the watched address.
addr := binary.LittleEndian.Uint64(info._pad[4:12])
return StopWatchpoint, archWatchpointAddr(s, addr)
default:
return StopSingleStep, 0
}
}