diff --git a/proctl/breakpoints.go b/proctl/breakpoints.go index f7b37a16..fabb78b6 100644 --- a/proctl/breakpoints.go +++ b/proctl/breakpoints.go @@ -9,21 +9,25 @@ import ( // point including the byte of data that originally was stored at that // address. type BreakPoint struct { + // File & line information for printing. FunctionName string File string Line int - Addr uint64 - OriginalData []byte - ID int - Temp bool - hardware bool - reg int + + Addr uint64 // Address breakpoint is set for. + OriginalData []byte // If software breakpoint, the data we replace with breakpoint instruction. + ID int // Monotonically increasing ID. + Temp bool // Whether this is a temp breakpoint (for next'ing). + hardware bool // Breakpoint using CPU debug registers. + reg int // If hardware breakpoint, what debug register it belongs to. } func (bp *BreakPoint) String() string { return fmt.Sprintf("Breakpoint %d at %#v %s:%d", bp.ID, bp.Addr, bp.File, bp.Line) } +// Clear this breakpoint appropriately depending on whether it is a +// hardware or software breakpoint. func (bp *BreakPoint) Clear(thread *ThreadContext) (*BreakPoint, error) { if bp.hardware { if err := clearHardwareBreakpoint(bp.reg, thread.Id); err != nil { diff --git a/proctl/doc.go b/proctl/doc.go new file mode 100644 index 00000000..6d75d00b --- /dev/null +++ b/proctl/doc.go @@ -0,0 +1,20 @@ +// proctl is a low-level package that provides methods to manipulate +// the process we are debugging, and methods to read and write from +// the virtual memory of the process. +// +// proctl implements the core features of this debugger, including all +// process manipulation (step, next, continue, halt) as well as providing +// methods to evaluate variables and read them from the virtual memory of +// the process we are debugging. +// +// What follows is a breakdown of the division of responsibility by file: +// +// * proctl(_*).go/c - Data structures and methods for manipulating an entire process. +// * threads(_*).go/c - Data structures and methods for manipulating individual threads. +// * variablges.go - Data structures and methods for evaluation of variables. +// * breakpoints(_*).go - Data structures and methods for setting / clearing breakpoints. +// * registers_*.go - Data structures and methods for obtaining register information. +// * stack.go - Functions for unwinding the stack. +// * ptrace_*.go - Ptrace stubs for missing stdlib functionality. +// +package proctl diff --git a/proctl/proctl.go b/proctl/proctl.go index 9317a613..fcbd1311 100644 --- a/proctl/proctl.go +++ b/proctl/proctl.go @@ -1,5 +1,3 @@ -// Package proctl provides functions for attaching to and manipulating -// a process during the debug session. package proctl import ( diff --git a/proctl/variables.go b/proctl/variables.go index c6348cf0..262b12c1 100644 --- a/proctl/variables.go +++ b/proctl/variables.go @@ -15,37 +15,47 @@ import ( ) const ( - maxVariableRecurse = 1 - maxArrayValues = 64 + ptrsize uintptr = unsafe.Sizeof(int(1)) // Size of a pointer. + + maxVariableRecurse = 1 // How far to recurse when evaluating nested types. + maxArrayValues = 64 // Max value for reading large arrays. ChanRecv = "chan receive" ChanSend = "chan send" ) +// Represents an evaluated variable. type Variable struct { Name string Value string Type string } +// Represents a runtime M (OS thread) structure. type M struct { - procid int - spinning uint8 - blocked uint8 - curg uintptr + procid int // Thread ID or port. + spinning uint8 // Busy looping. + blocked uint8 // Waiting on futex / semaphore. + curg uintptr // Current G running on this thread. } +// Represents a runtime G (goroutine) structure (at least the +// fields that Delve is interested in). type G struct { - Id int - PC uint64 - SP uint64 - GoPC uint64 - File string - Line int - Func *gosym.Func - WaitReason string + Id int // Goroutine ID + PC uint64 // PC of goroutine when it was parked. + SP uint64 // SP of goroutine when it was parked. + GoPC uint64 // PC of 'go' statement that created this goroutine. + WaitReason string // Reason for goroutine being parked. + + // Information on goroutine location. + File string + Line int + Func *gosym.Func } +// Returns whether the goroutine is blocked on +// a channel read operation. func (g *G) ChanRecvBlocked() bool { return g.WaitReason == ChanRecv } @@ -60,8 +70,6 @@ func (g *G) chanRecvReturnAddr(dbp *DebuggedProcess) (uint64, error) { return topLoc.addr, nil } -const ptrsize uintptr = unsafe.Sizeof(int(1)) - // Parses and returns select info on the internal M // data structures used by the Go scheduler. func (thread *ThreadContext) AllM() ([]*M, error) { @@ -80,7 +88,6 @@ func (thread *ThreadContext) AllM() ([]*M, error) { return nil, fmt.Errorf("allm contains no M pointers") } - // parse addresses procidInstructions, err := instructionsFor("procid", thread.Process, reader, true) if err != nil { return nil, err