提交 aa8ad889 编写于 作者: D Derek Parker

Improve documentation

上级 e001bbff
......@@ -36,6 +36,8 @@ type BreakPoint struct {
temp bool
}
// Returned when trying to set a breakpoint at
// an address that already has a breakpoint set for it.
type BreakPointExistsError struct {
file string
line int
......@@ -46,6 +48,16 @@ func (bpe BreakPointExistsError) Error() string {
return fmt.Sprintf("Breakpoint exists at %s:%d at %x", bpe.file, bpe.line, bpe.addr)
}
// InvalidAddressError represents the result of
// attempting to set a breakpoint at an invalid address.
type InvalidAddressError struct {
address uint64
}
func (iae InvalidAddressError) Error() string {
return fmt.Sprintf("Invalid address %#v\n", iae.address)
}
func PtracePokeUser(tid int, off, addr uintptr) error {
_, _, err := sys.Syscall6(sys.SYS_PTRACE, sys.PTRACE_POKEUSR, uintptr(tid), uintptr(off), uintptr(addr), 0, 0)
if err != syscall.Errno(0) {
......@@ -63,6 +75,7 @@ func PtracePeekUser(tid int, off uintptr) (uintptr, error) {
return val, nil
}
// Returns whether or not a breakpoint has been set for the given address.
func (dbp *DebuggedProcess) BreakpointExists(addr uint64) bool {
for _, bp := range dbp.HWBreakPoints {
if bp != nil && bp.Addr == addr {
......
......@@ -37,12 +37,15 @@ type DebuggedProcess struct {
halt bool
}
// A ManualStopError happens when the user triggers a
// manual stop via SIGERM.
type ManualStopError struct{}
func (mse ManualStopError) Error() string {
return "Manual stop requested"
}
// Attach to an existing process with the given PID.
func Attach(pid int) (*DebuggedProcess, error) {
dbp, err := newDebugProcess(pid, true)
if err != nil {
......@@ -65,6 +68,9 @@ func Attach(pid int) (*DebuggedProcess, error) {
return dbp, nil
}
// Create and begin debugging a new process. First entry in
// `cmd` is the program to run, and then rest are the arguments
// to be supplied to that process.
func Launch(cmd []string) (*DebuggedProcess, error) {
proc := exec.Command(cmd[0])
proc.Args = cmd
......@@ -120,6 +126,8 @@ func newDebugProcess(pid int, attach bool) (*DebuggedProcess, error) {
return &dbp, nil
}
// Attach to a newly created thread, and store that thread in our list of
// known threads.
func (dbp *DebuggedProcess) AttachThread(tid int) (*ThreadContext, error) {
if thread, ok := dbp.Threads[tid]; ok {
return thread, nil
......@@ -146,6 +154,8 @@ func (dbp *DebuggedProcess) AttachThread(tid int) (*ThreadContext, error) {
return dbp.addThread(tid)
}
// Returns whether or not Delve thinks the debugged
// process is currently executing.
func (dbp *DebuggedProcess) Running() bool {
return dbp.running
}
......@@ -204,6 +214,8 @@ func (dbp *DebuggedProcess) FindLocation(str string) (uint64, error) {
}
}
// Sends out a request that the debugged process halt
// execution. Sends SIGSTOP to all threads.
func (dbp *DebuggedProcess) RequestManualStop() {
dbp.halt = true
for _, th := range dbp.Threads {
......@@ -215,7 +227,8 @@ func (dbp *DebuggedProcess) RequestManualStop() {
dbp.running = false
}
// Sets a breakpoint in the current thread.
// Sets a breakpoint, adding it to our list of known breakpoints. Uses
// the "current thread" when setting the breakpoint.
func (dbp *DebuggedProcess) Break(addr uint64) (*BreakPoint, error) {
return dbp.CurrentThread.Break(addr)
}
......@@ -357,14 +370,6 @@ func (dbp *DebuggedProcess) Registers() (Registers, error) {
return dbp.CurrentThread.Registers()
}
type InvalidAddressError struct {
address uint64
}
func (iae InvalidAddressError) Error() string {
return fmt.Sprintf("Invalid address %#v\n", iae.address)
}
func (dbp *DebuggedProcess) CurrentPC() (uint64, error) {
return dbp.CurrentThread.CurrentPC()
}
......
......@@ -3,19 +3,27 @@ package proctl
import (
"encoding/binary"
"fmt"
sys "golang.org/x/sys/unix"
"github.com/derekparker/delve/dwarf/frame"
)
// ThreadContext represents a single thread of execution in the
// traced program.
// ThreadContext represents a single thread in the traced process
// Id represents the thread id, Process holds a reference to the
// DebuggedProcess struct that contains info on the process as
// a whole, and Status represents the last result of a `wait` call
// on this thread.
type ThreadContext struct {
Id int
Process *DebuggedProcess
Status *sys.WaitStatus
}
// An interface for a generic register type. The
// interface encapsulates the generic values / actions
// we need independant of arch. The concrete register types
// will be different depending on OS/Arch.
type Registers interface {
PC() uint64
SP() uint64
......@@ -32,7 +40,7 @@ func (thread *ThreadContext) Registers() (Registers, error) {
return regs, nil
}
// Returns the current PC for this thread id.
// Returns the current PC for this thread.
func (thread *ThreadContext) CurrentPC() (uint64, error) {
regs, err := thread.Registers()
if err != nil {
......@@ -76,6 +84,10 @@ func (thread *ThreadContext) Clear(addr uint64) (*BreakPoint, error) {
return thread.Process.clearBreakpoint(thread.Id, addr)
}
// Continue the execution of this thread. This method takes
// software breakpoints into consideration and ensures that
// we step over any breakpoints. It will restore the instruction,
// step, and then restore the breakpoint and continue.
func (thread *ThreadContext) Continue() error {
// Check whether we are stopped at a breakpoint, and
// if so, single step over it before continuing.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册