mirror of
https://github.com/go-delve/delve.git
synced 2025-10-29 09:46:56 +08:00
dlv: Misc refactors
This commit is contained in:
committed by
Derek Parker
parent
ff0ec8ce00
commit
37f124817d
@ -255,7 +255,7 @@ func traceCmd(cmd *cobra.Command, args []string) {
|
||||
return 1
|
||||
}
|
||||
for i := range funcs {
|
||||
_, err := client.CreateBreakpoint(&api.Breakpoint{FunctionName: funcs[i], Tracepoint: true, Line: -1, Stacktrace: traceStackDepth})
|
||||
_, err = client.CreateBreakpoint(&api.Breakpoint{FunctionName: funcs[i], Tracepoint: true, Line: -1, Stacktrace: traceStackDepth})
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
return 1
|
||||
|
||||
@ -24,7 +24,7 @@ type Config struct {
|
||||
func LoadConfig() *Config {
|
||||
err := createConfigPath()
|
||||
if err != nil {
|
||||
fmt.Printf("Could not create config directory: %v.")
|
||||
fmt.Printf("Could not create config directory: %v.", err)
|
||||
return nil
|
||||
}
|
||||
fullConfigFile, err := GetConfigFilePath(configFile)
|
||||
|
||||
@ -25,8 +25,8 @@ type Breakpoint struct {
|
||||
|
||||
// Breakpoint information
|
||||
Tracepoint bool // Tracepoint flag
|
||||
Stacktrace int // Number of stack frames to retrieve
|
||||
Goroutine bool // Retrieve goroutine information
|
||||
Stacktrace int // Number of stack frames to retrieve
|
||||
Variables []string // Variables to evaluate
|
||||
HitCount map[int]uint64 // Number of times a breakpoint has been reached in a certain goroutine
|
||||
TotalHitCount uint64 // Number of times a breakpoint has been reached
|
||||
|
||||
35
proc/eval.go
35
proc/eval.go
@ -9,10 +9,10 @@ import (
|
||||
"go/parser"
|
||||
"go/printer"
|
||||
"go/token"
|
||||
"golang.org/x/debug/dwarf"
|
||||
"reflect"
|
||||
|
||||
"github.com/derekparker/delve/dwarf/reader"
|
||||
"golang.org/x/debug/dwarf"
|
||||
)
|
||||
|
||||
// EvalExpression returns the value of the given expression.
|
||||
@ -430,25 +430,26 @@ func (scope *EvalScope) evalIdent(node *ast.Ident) (*Variable, error) {
|
||||
|
||||
// try to interpret this as a local variable
|
||||
v, err := scope.extractVarInfo(node.Name)
|
||||
if err != nil {
|
||||
origErr := err
|
||||
// workaround: sometimes go inserts an entry for '&varname' instead of varname
|
||||
v, err = scope.extractVarInfo("&" + node.Name)
|
||||
if err != nil {
|
||||
// if it's not a local variable then it could be a package variable w/o explicit package name
|
||||
_, _, fn := scope.Thread.dbp.PCToLine(scope.PC)
|
||||
if fn != nil {
|
||||
if v, err := scope.packageVarAddr(fn.PackageName() + "." + node.Name); err == nil {
|
||||
v.Name = node.Name
|
||||
return v, nil
|
||||
}
|
||||
}
|
||||
return nil, origErr
|
||||
}
|
||||
if err == nil {
|
||||
return v, nil
|
||||
}
|
||||
origErr := err
|
||||
// workaround: sometimes go inserts an entry for '&varname' instead of varname
|
||||
v, err = scope.extractVarInfo("&" + node.Name)
|
||||
if err == nil {
|
||||
v = v.maybeDereference()
|
||||
v.Name = node.Name
|
||||
return v, nil
|
||||
}
|
||||
return v, nil
|
||||
// if it's not a local variable then it could be a package variable w/o explicit package name
|
||||
_, _, fn := scope.Thread.dbp.PCToLine(scope.PC)
|
||||
if fn != nil {
|
||||
if v, err = scope.packageVarAddr(fn.PackageName() + "." + node.Name); err == nil {
|
||||
v.Name = node.Name
|
||||
return v, nil
|
||||
}
|
||||
}
|
||||
return nil, origErr
|
||||
}
|
||||
|
||||
// Evaluates expressions <subexpr>.<field name> where subexpr is not a package name
|
||||
|
||||
@ -49,11 +49,11 @@ type Process struct {
|
||||
goSymTable *gosym.Table
|
||||
frameEntries frame.FrameDescriptionEntries
|
||||
lineInfo line.DebugLines
|
||||
firstStart bool
|
||||
os *OSProcessDetails
|
||||
arch Arch
|
||||
breakpointIDCounter int
|
||||
tempBreakpointIDCounter int
|
||||
firstStart bool
|
||||
halt bool
|
||||
exited bool
|
||||
ptraceChan chan func()
|
||||
|
||||
@ -84,9 +84,9 @@ func (n NullAddrError) Error() string {
|
||||
type StackIterator struct {
|
||||
pc, sp uint64
|
||||
top bool
|
||||
atend bool
|
||||
frame Stackframe
|
||||
dbp *Process
|
||||
atend bool
|
||||
err error
|
||||
}
|
||||
|
||||
|
||||
@ -396,16 +396,16 @@ func (thread *Thread) onRuntimeBreakpoint() bool {
|
||||
return loc.Fn != nil && loc.Fn.Name == "runtime.breakpoint"
|
||||
}
|
||||
|
||||
// Returns true if this thread is on the goroutine requested by the current 'next' command
|
||||
func (th *Thread) onNextGoroutine() (bool, error) {
|
||||
// onNextGorutine returns true if this thread is on the goroutine requested by the current 'next' command
|
||||
func (thread *Thread) onNextGoroutine() (bool, error) {
|
||||
var bp *Breakpoint
|
||||
for i := range th.dbp.Breakpoints {
|
||||
if th.dbp.Breakpoints[i].Temp {
|
||||
bp = th.dbp.Breakpoints[i]
|
||||
for i := range thread.dbp.Breakpoints {
|
||||
if thread.dbp.Breakpoints[i].Temp {
|
||||
bp = thread.dbp.Breakpoints[i]
|
||||
}
|
||||
}
|
||||
if bp == nil {
|
||||
return false, nil
|
||||
}
|
||||
return bp.checkCondition(th)
|
||||
return bp.checkCondition(thread)
|
||||
}
|
||||
|
||||
@ -8,11 +8,12 @@ import (
|
||||
"go/constant"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"golang.org/x/debug/dwarf"
|
||||
"reflect"
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/debug/dwarf"
|
||||
|
||||
"github.com/derekparker/delve/dwarf/op"
|
||||
"github.com/derekparker/delve/dwarf/reader"
|
||||
)
|
||||
|
||||
@ -3,6 +3,7 @@ package api
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
@ -13,14 +14,14 @@ const (
|
||||
indentString = "\t"
|
||||
)
|
||||
|
||||
// Returns a representation of v on a single line
|
||||
// SinglelineString returns a representation of v on a single line.
|
||||
func (v *Variable) SinglelineString() string {
|
||||
var buf bytes.Buffer
|
||||
v.writeTo(&buf, true, false, true, "")
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// Returns a representation of v on multiple lines
|
||||
// MultilineString returns a representation of v on multiple lines.
|
||||
func (v *Variable) MultilineString(indent string) string {
|
||||
var buf bytes.Buffer
|
||||
buf.WriteString(indent)
|
||||
@ -28,7 +29,7 @@ func (v *Variable) MultilineString(indent string) string {
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func (v *Variable) writeTo(buf *bytes.Buffer, top, newlines, includeType bool, indent string) {
|
||||
func (v *Variable) writeTo(buf io.Writer, top, newlines, includeType bool, indent string) {
|
||||
if v.Unreadable != "" {
|
||||
fmt.Fprintf(buf, "(unreadable %s)", v.Unreadable)
|
||||
return
|
||||
@ -101,7 +102,7 @@ func (v *Variable) writeTo(buf *bytes.Buffer, top, newlines, includeType bool, i
|
||||
}
|
||||
}
|
||||
|
||||
func (v *Variable) writeStringTo(buf *bytes.Buffer) {
|
||||
func (v *Variable) writeStringTo(buf io.Writer) {
|
||||
s := v.Value
|
||||
if len(s) != int(v.Len) {
|
||||
s = fmt.Sprintf("%s...+%d more", s, int(v.Len)-len(s))
|
||||
@ -109,21 +110,21 @@ func (v *Variable) writeStringTo(buf *bytes.Buffer) {
|
||||
fmt.Fprintf(buf, "%q", s)
|
||||
}
|
||||
|
||||
func (v *Variable) writeSliceTo(buf *bytes.Buffer, newlines, includeType bool, indent string) {
|
||||
func (v *Variable) writeSliceTo(buf io.Writer, newlines, includeType bool, indent string) {
|
||||
if includeType {
|
||||
fmt.Fprintf(buf, "%s len: %d, cap: %d, ", v.Type, v.Len, v.Cap)
|
||||
}
|
||||
v.writeSliceOrArrayTo(buf, newlines, indent)
|
||||
}
|
||||
|
||||
func (v *Variable) writeArrayTo(buf *bytes.Buffer, newlines, includeType bool, indent string) {
|
||||
func (v *Variable) writeArrayTo(buf io.Writer, newlines, includeType bool, indent string) {
|
||||
if includeType {
|
||||
fmt.Fprintf(buf, "%s ", v.Type)
|
||||
}
|
||||
v.writeSliceOrArrayTo(buf, newlines, indent)
|
||||
}
|
||||
|
||||
func (v *Variable) writeStructTo(buf *bytes.Buffer, newlines, includeType bool, indent string) {
|
||||
func (v *Variable) writeStructTo(buf io.Writer, newlines, includeType bool, indent string) {
|
||||
if int(v.Len) != len(v.Children) {
|
||||
fmt.Fprintf(buf, "(*%s)(0x%x)", v.Type, v.Addr)
|
||||
return
|
||||
@ -157,7 +158,7 @@ func (v *Variable) writeStructTo(buf *bytes.Buffer, newlines, includeType bool,
|
||||
fmt.Fprintf(buf, "}")
|
||||
}
|
||||
|
||||
func (v *Variable) writeMapTo(buf *bytes.Buffer, newlines, includeType bool, indent string) {
|
||||
func (v *Variable) writeMapTo(buf io.Writer, newlines, includeType bool, indent string) {
|
||||
if includeType {
|
||||
fmt.Fprintf(buf, "%s ", v.Type)
|
||||
}
|
||||
@ -261,7 +262,7 @@ func (v *Variable) shouldNewlineStruct(newlines bool) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (v *Variable) writeSliceOrArrayTo(buf *bytes.Buffer, newlines bool, indent string) {
|
||||
func (v *Variable) writeSliceOrArrayTo(buf io.Writer, newlines bool, indent string) {
|
||||
nl := v.shouldNewlineArray(newlines)
|
||||
fmt.Fprintf(buf, "[")
|
||||
|
||||
|
||||
@ -3,10 +3,11 @@ package api
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/derekparker/delve/proc"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"unicode"
|
||||
|
||||
"github.com/derekparker/delve/proc"
|
||||
)
|
||||
|
||||
// DebuggerState represents the current context of the debugger.
|
||||
@ -46,10 +47,10 @@ type Breakpoint struct {
|
||||
|
||||
// tracepoint flag
|
||||
Tracepoint bool `json:"continue"`
|
||||
// number of stack frames to retrieve
|
||||
Stacktrace int `json:"stacktrace"`
|
||||
// retrieve goroutine information
|
||||
Goroutine bool `json:"goroutine"`
|
||||
// number of stack frames to retrieve
|
||||
Stacktrace int `json:"stacktrace"`
|
||||
// variables to evaluate
|
||||
Variables []string `json:"variables,omitempty"`
|
||||
// number of times a breakpoint has been reached in a certain goroutine
|
||||
|
||||
@ -311,24 +311,23 @@ func (c *Commands) goroutine(t *Term, ctx callContext, argstr string) error {
|
||||
}
|
||||
if args[0] == "" {
|
||||
return printscope(t)
|
||||
} else {
|
||||
gid, err := strconv.Atoi(argstr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
oldState, err := t.client.GetState()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newState, err := t.client.SwitchGoroutine(gid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Switched from %d to %d (thread %d)\n", oldState.SelectedGoroutine.ID, gid, newState.CurrentThread.ID)
|
||||
return nil
|
||||
}
|
||||
gid, err := strconv.Atoi(argstr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
oldState, err := t.client.GetState()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newState, err := t.client.SwitchGoroutine(gid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Switched from %d to %d (thread %d)\n", oldState.SelectedGoroutine.ID, gid, newState.CurrentThread.ID)
|
||||
return nil
|
||||
case 2:
|
||||
args = append(args, "")
|
||||
}
|
||||
@ -345,8 +344,6 @@ func (c *Commands) goroutine(t *Term, ctx callContext, argstr string) error {
|
||||
func (c *Commands) frame(t *Term, ctx callContext, args string) error {
|
||||
v := strings.SplitN(args, " ", 3)
|
||||
|
||||
var err error
|
||||
|
||||
switch len(v) {
|
||||
case 0, 1:
|
||||
return errors.New("not enough arguments")
|
||||
@ -354,6 +351,7 @@ func (c *Commands) frame(t *Term, ctx callContext, args string) error {
|
||||
v = append(v, "")
|
||||
}
|
||||
|
||||
var err error
|
||||
ctx.Prefix = scopePrefix
|
||||
ctx.Scope.Frame, err = strconv.Atoi(v[0])
|
||||
if err != nil {
|
||||
@ -592,7 +590,7 @@ func setBreakpoint(t *Term, tracepoint bool, argstr string) error {
|
||||
requestedBp.Name = ""
|
||||
locspec = argstr
|
||||
var err2 error
|
||||
locs, err2 = t.client.FindLocation(api.EvalScope{-1, 0}, locspec)
|
||||
locs, err2 = t.client.FindLocation(api.EvalScope{GoroutineID: -1, Frame: 0}, locspec)
|
||||
if err2 != nil {
|
||||
return err
|
||||
}
|
||||
@ -1051,13 +1049,11 @@ func exitCommand(t *Term, ctx callContext, args string) error {
|
||||
return ExitRequestError{}
|
||||
}
|
||||
|
||||
func getBreakpointByIDOrName(t *Term, arg string) (bp *api.Breakpoint, err error) {
|
||||
func getBreakpointByIDOrName(t *Term, arg string) (*api.Breakpoint, error) {
|
||||
if id, err := strconv.Atoi(arg); err == nil {
|
||||
bp, err = t.client.GetBreakpoint(id)
|
||||
} else {
|
||||
bp, err = t.client.GetBreakpointByName(arg)
|
||||
return t.client.GetBreakpoint(id)
|
||||
}
|
||||
return
|
||||
return t.client.GetBreakpointByName(arg)
|
||||
}
|
||||
|
||||
func (c *Commands) onCmd(t *Term, ctx callContext, argstr string) error {
|
||||
@ -1154,7 +1150,6 @@ func formatBreakpointLocation(bp *api.Breakpoint) string {
|
||||
p := ShortenFilePath(bp.File)
|
||||
if bp.FunctionName != "" {
|
||||
return fmt.Sprintf("%#v for %s() %s:%d", bp.Addr, bp.FunctionName, p, bp.Line)
|
||||
} else {
|
||||
return fmt.Sprintf("%#v for %s:%d", bp.Addr, p, bp.Line)
|
||||
}
|
||||
return fmt.Sprintf("%#v for %s:%d", bp.Addr, p, bp.Line)
|
||||
}
|
||||
|
||||
@ -102,7 +102,6 @@ func (t *Term) Run() (int, error) {
|
||||
}
|
||||
}
|
||||
|
||||
var status int
|
||||
for {
|
||||
cmdstr, err := t.promptForInput()
|
||||
if err != nil {
|
||||
@ -110,8 +109,7 @@ func (t *Term) Run() (int, error) {
|
||||
fmt.Println("exit")
|
||||
return t.handleExit()
|
||||
}
|
||||
err, status = fmt.Errorf("Prompt for input failed.\n"), 1
|
||||
break
|
||||
return 1, fmt.Errorf("Prompt for input failed.\n")
|
||||
}
|
||||
|
||||
cmdstr, args := parseCommand(cmdstr)
|
||||
@ -129,8 +127,6 @@ func (t *Term) Run() (int, error) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return status, nil
|
||||
}
|
||||
|
||||
// Println prints a line to the terminal.
|
||||
@ -158,10 +154,10 @@ func (t *Term) promptForInput() (string, error) {
|
||||
func (t *Term) handleExit() (int, error) {
|
||||
fullHistoryFile, err := config.GetConfigFilePath(historyFile)
|
||||
if err != nil {
|
||||
fmt.Println("Error saving history file:", err)
|
||||
fmt.Println("Error saving history file: ", err)
|
||||
} else {
|
||||
if f, err := os.OpenFile(fullHistoryFile, os.O_RDWR, 0666); err == nil {
|
||||
_, err := t.line.WriteHistory(f)
|
||||
_, err = t.line.WriteHistory(f)
|
||||
if err != nil {
|
||||
fmt.Println("readline history error: ", err)
|
||||
}
|
||||
@ -183,8 +179,7 @@ func (t *Term) handleExit() (int, error) {
|
||||
answer = strings.ToLower(strings.TrimSpace(answer))
|
||||
kill = (answer != "n" && answer != "no")
|
||||
}
|
||||
err = t.client.Detach(kill)
|
||||
if err != nil {
|
||||
if err := t.client.Detach(kill); err != nil {
|
||||
return 1, err
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user