diff --git a/service/debugger/locations.go b/service/debugger/locations.go index d4ba98f5..50e433a3 100644 --- a/service/debugger/locations.go +++ b/service/debugger/locations.go @@ -228,6 +228,25 @@ func (loc *NormalLocationSpec) FileMatch(path string) bool { return strings.HasSuffix(path, loc.Base) && (path[len(path)-len(loc.Base)-1] == filepath.Separator) } +type AmbiguousLocationError struct { + Location string + CandidatesString []string + CandidatesLocation []api.Location +} + +func (ale AmbiguousLocationError) Error() string { + var candidates []string + if ale.CandidatesLocation != nil { + for i := range ale.CandidatesLocation { + candidates = append(candidates, ale.CandidatesLocation[i].Function.Name) + } + + } else { + candidates = ale.CandidatesString + } + return fmt.Sprintf("Location \"%s\" ambiguous: %s…", ale.Location, strings.Join(candidates, ", ")) +} + func (loc *NormalLocationSpec) Find(d *Debugger, locStr string) ([]api.Location, error) { funcs := d.process.Funcs() files := d.process.Sources() @@ -280,7 +299,7 @@ func (loc *NormalLocationSpec) Find(d *Debugger, locStr string) ([]api.Location, case 0: return nil, fmt.Errorf("Location \"%s\" not found", locStr) default: - return nil, fmt.Errorf("Location \"%s\" ambiguous: %s…", locStr, strings.Join(candidates, ", ")) + return nil, AmbiguousLocationError{Location: locStr, CandidatesString: candidates} } } diff --git a/terminal/command.go b/terminal/command.go index 5d7caf9e..60ef895c 100644 --- a/terminal/command.go +++ b/terminal/command.go @@ -15,6 +15,7 @@ import ( "github.com/derekparker/delve/service" "github.com/derekparker/delve/service/api" + "github.com/derekparker/delve/service/debugger" ) type cmdfunc func(client service.Client, args ...string) error @@ -68,6 +69,7 @@ func DebugCommands(client service.Client) *Commands { {aliases: []string{"regs"}, cmdFn: regs, helpMsg: "Print contents of CPU registers."}, {aliases: []string{"exit", "quit", "q"}, cmdFn: exitCommand, helpMsg: "Exit the debugger."}, {aliases: []string{"stack", "bt"}, cmdFn: stackCommand, helpMsg: "stack [ []]. Prints stack."}, + {aliases: []string{"list"}, cmdFn: listCommand, helpMsg: "list . Show source around current point or provided linespec."}, } return c @@ -503,6 +505,29 @@ func stackCommand(client service.Client, args ...string) error { return nil } +func listCommand(client service.Client, args ...string) error { + if len(args) == 0 { + state, err := client.GetState() + if err != nil { + return err + } + printcontext(state) + return nil + } + + locs, err := client.FindLocation(args[0]) + if err != nil { + return err + } + + if len(locs) > 1 { + return debugger.AmbiguousLocationError{Location: args[0], CandidatesLocation: locs} + } + + printfile(locs[0].File, locs[0].Line, false) + return nil +} + func printStack(stack []api.Location, ind string) { for i := range stack { name := "(nil)" @@ -525,8 +550,6 @@ func printcontext(state *api.DebuggerState) error { return nil } - var context []string - var fn *api.Function if state.CurrentThread.Function != nil { fn = state.CurrentThread.Function @@ -564,14 +587,20 @@ func printcontext(state *api.DebuggerState) error { return nil } - file, err := os.Open(state.CurrentThread.File) + return printfile(state.CurrentThread.File, state.CurrentThread.Line, true) +} + +func printfile(filename string, line int, showArrow bool) error { + file, err := os.Open(filename) if err != nil { return err } defer file.Close() + var context []string + buf := bufio.NewReader(file) - l := state.CurrentThread.Line + l := line for i := 1; i < l-5; i++ { _, err := buf.ReadString('\n') if err != nil && err != io.EOF { @@ -579,7 +608,12 @@ func printcontext(state *api.DebuggerState) error { } } - for i := l - 5; i <= l+5; i++ { + s := l - 5 + if s < 1 { + s = 1 + } + + for i := s; i <= l+5; i++ { line, err := buf.ReadString('\n') if err != nil { if err != io.EOF { @@ -591,9 +625,12 @@ func printcontext(state *api.DebuggerState) error { } } - arrow := " " - if i == l { - arrow = "=>" + var arrow string + if showArrow { + arrow = " " + if i == l { + arrow = "=>" + } } var lineNum string