dlv: Misc refactors

This commit is contained in:
Hubert Krauze
2016-03-09 15:11:58 +00:00
committed by Derek Parker
parent ff0ec8ce00
commit 37f124817d
12 changed files with 71 additions and 77 deletions

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -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
}

View File

@ -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)
}

View File

@ -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"
)

View File

@ -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, "[")

View File

@ -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

View File

@ -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)
}

View File

@ -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
}
}