ci: add Gitea CI workflows and release pipeline
Test / vet (push) Successful in 44s
Release / build (amd64, linux) (push) Successful in 39s
Release / build (arm64, linux) (push) Successful in 38s
Release / build (loong64, linux) (push) Successful in 39s
Release / build (riscv64, linux) (push) Successful in 39s
Test / test (push) Successful in 1m58s
Release / release (push) Successful in 18s
Test / build (push) Successful in 37s
Test / vet (push) Successful in 44s
Release / build (amd64, linux) (push) Successful in 39s
Release / build (arm64, linux) (push) Successful in 38s
Release / build (loong64, linux) (push) Successful in 39s
Release / build (riscv64, linux) (push) Successful in 39s
Test / test (push) Successful in 1m58s
Release / release (push) Successful in 18s
Test / build (push) Successful in 37s
Assisted-by: DeepSeek V4 Pro
This commit is contained in:
+16
-17
@@ -1,8 +1,6 @@
|
||||
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
//go:build linux && amd64
|
||||
|
||||
package debug
|
||||
|
||||
import "fmt"
|
||||
@@ -85,14 +83,15 @@ func (c *Condition) Eval(regs *Regs) bool {
|
||||
}
|
||||
|
||||
// Breakpoints manages the set of breakpoints for a Session.
|
||||
// Breakpoints manages software breakpoints for a debuggee.
|
||||
type Breakpoints struct {
|
||||
s *Session
|
||||
t tracer
|
||||
bps map[uint64]*Breakpoint
|
||||
}
|
||||
|
||||
// NewBreakpoints creates a breakpoint manager for the session.
|
||||
func NewBreakpoints(s *Session) *Breakpoints {
|
||||
return &Breakpoints{s: s, bps: make(map[uint64]*Breakpoint)}
|
||||
// NewBreakpoints creates a new breakpoint manager.
|
||||
func NewBreakpoints(t tracer) *Breakpoints {
|
||||
return &Breakpoints{t: t, bps: make(map[uint64]*Breakpoint)}
|
||||
}
|
||||
|
||||
// Set installs a breakpoint at addr (replaces any existing one).
|
||||
@@ -108,14 +107,14 @@ func (bm *Breakpoints) SetWithCond(addr uint64, label string, cond *Condition) (
|
||||
return bp, nil
|
||||
}
|
||||
// Read the original byte.
|
||||
word, err := bm.s.Peek(addr)
|
||||
word, err := bm.t.Peek(addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
orig := byte(word)
|
||||
// Patch with INT3 (0xCC), preserving the rest of the word.
|
||||
patched := (word &^ 0xFF) | 0xCC
|
||||
if err := bm.s.Poke(addr, patched); err != nil {
|
||||
if err := bm.t.Poke(addr, patched); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bp := &Breakpoint{Addr: addr, Label: label, Orig: orig, Enabled: true, Cond: cond}
|
||||
@@ -160,12 +159,12 @@ func (bm *Breakpoints) Clear(addr uint64) error {
|
||||
if !ok {
|
||||
return fmt.Errorf("debug: no breakpoint at %#x", addr)
|
||||
}
|
||||
word, err := bm.s.Peek(addr)
|
||||
word, err := bm.t.Peek(addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
restored := (word &^ 0xFF) | uint64(bp.Orig)
|
||||
if err := bm.s.Poke(addr, restored); err != nil {
|
||||
if err := bm.t.Poke(addr, restored); err != nil {
|
||||
return err
|
||||
}
|
||||
delete(bm.bps, addr)
|
||||
@@ -211,24 +210,24 @@ func (bm *Breakpoints) HandleTrap(regs *Regs) *Breakpoint {
|
||||
if bp.Cond != nil && !bp.Cond.Eval(regs) {
|
||||
// Condition not met — restore the byte but do NOT rewind RIP.
|
||||
// The process continues from the next instruction (past the INT3).
|
||||
word, err := bm.s.Peek(trapAddr)
|
||||
word, err := bm.t.Peek(trapAddr)
|
||||
if err == nil {
|
||||
restored := (word &^ 0xFF) | uint64(bp.Orig)
|
||||
bm.s.Poke(trapAddr, restored)
|
||||
bm.t.Poke(trapAddr, restored)
|
||||
}
|
||||
// RIP is already past the INT3 (trapAddr + 1). Don't rewind.
|
||||
return nil
|
||||
}
|
||||
bp.hits++
|
||||
// Restore the original byte.
|
||||
word, err := bm.s.Peek(trapAddr)
|
||||
word, err := bm.t.Peek(trapAddr)
|
||||
if err == nil {
|
||||
restored := (word &^ 0xFF) | uint64(bp.Orig)
|
||||
bm.s.Poke(trapAddr, restored)
|
||||
bm.t.Poke(trapAddr, restored)
|
||||
}
|
||||
// Rewind RIP to re-execute the original instruction.
|
||||
regs.RIP = trapAddr
|
||||
bm.s.SetRegs(regs)
|
||||
bm.t.SetRegs(regs)
|
||||
return bp
|
||||
}
|
||||
|
||||
@@ -240,10 +239,10 @@ func (bm *Breakpoints) Reinsert(addr uint64) error {
|
||||
if !ok || !bp.Enabled {
|
||||
return nil
|
||||
}
|
||||
word, err := bm.s.Peek(addr)
|
||||
word, err := bm.t.Peek(addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
patched := (word &^ 0xFF) | 0xCC
|
||||
return bm.s.Poke(addr, patched)
|
||||
return bm.t.Poke(addr, patched)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user