diff --git a/Documentation/cli/README.md b/Documentation/cli/README.md index f9eb75bc..11314e86 100644 --- a/Documentation/cli/README.md +++ b/Documentation/cli/README.md @@ -6,56 +6,88 @@ The configuration file `config.yml` contains all the configurable options and th # Commands +## Running the program + Command | Description --------|------------ -[args](#args) | Print function arguments. -[break](#break) | Sets a breakpoint. -[breakpoints](#breakpoints) | Print out info for active breakpoints. [call](#call) | Resumes process, injecting a function call (EXPERIMENTAL!!!) -[check](#check) | Creates a checkpoint at the current position. -[checkpoints](#checkpoints) | Print out info for existing checkpoints. -[clear](#clear) | Deletes breakpoint. -[clear-checkpoint](#clear-checkpoint) | Deletes checkpoint. -[clearall](#clearall) | Deletes multiple breakpoints. -[condition](#condition) | Set breakpoint condition. -[config](#config) | Changes configuration parameters. [continue](#continue) | Run until breakpoint or program termination. -[deferred](#deferred) | Executes command in the context of a deferred call. -[disassemble](#disassemble) | Disassembler. -[down](#down) | Move the current frame down. -[edit](#edit) | Open where you are in $DELVE_EDITOR or $EDITOR -[examinemem](#examinemem) | Examine memory: -[exit](#exit) | Exit the debugger. -[frame](#frame) | Set the current frame, or execute command on a different frame. -[funcs](#funcs) | Print list of functions. -[goroutine](#goroutine) | Shows or changes current goroutine -[goroutines](#goroutines) | List program goroutines. -[help](#help) | Prints the help message. -[libraries](#libraries) | List loaded dynamic libraries -[list](#list) | Show source code. -[locals](#locals) | Print local variables. [next](#next) | Step over to next source line. -[on](#on) | Executes a command when a breakpoint is hit. -[print](#print) | Evaluate an expression. -[regs](#regs) | Print contents of CPU registers. [restart](#restart) | Restart process from a checkpoint or event. -[rev](#rev) | Reverses the execution of the target program for the command specified. [rewind](#rewind) | Run backwards until breakpoint or program termination. -[set](#set) | Changes the value of a variable. -[source](#source) | Executes a file containing a list of delve commands -[sources](#sources) | Print list of source files. -[stack](#stack) | Print stack trace. [step](#step) | Single step through program. [step-instruction](#step-instruction) | Single step a single cpu instruction. [stepout](#stepout) | Step out of the current function. -[thread](#thread) | Switch to the specified thread. -[threads](#threads) | Print out info for every traced thread. + + +## Manipulating breakpoints + +Command | Description +--------|------------ +[break](#break) | Sets a breakpoint. +[breakpoints](#breakpoints) | Print out info for active breakpoints. +[clear](#clear) | Deletes breakpoint. +[clearall](#clearall) | Deletes multiple breakpoints. +[condition](#condition) | Set breakpoint condition. +[on](#on) | Executes a command when a breakpoint is hit. [trace](#trace) | Set tracepoint. -[types](#types) | Print list of types -[up](#up) | Move the current frame up. + + +## Viewing program variables and memory + +Command | Description +--------|------------ +[args](#args) | Print function arguments. +[examinemem](#examinemem) | Examine memory: +[locals](#locals) | Print local variables. +[print](#print) | Evaluate an expression. +[regs](#regs) | Print contents of CPU registers. +[set](#set) | Changes the value of a variable. [vars](#vars) | Print package variables. [whatis](#whatis) | Prints type of an expression. + +## Listing and switching between threads and goroutines + +Command | Description +--------|------------ +[goroutine](#goroutine) | Shows or changes current goroutine +[goroutines](#goroutines) | List program goroutines. +[thread](#thread) | Switch to the specified thread. +[threads](#threads) | Print out info for every traced thread. + + +## Viewing the call stack and selecting frames + +Command | Description +--------|------------ +[deferred](#deferred) | Executes command in the context of a deferred call. +[down](#down) | Move the current frame down. +[frame](#frame) | Set the current frame, or execute command on a different frame. +[stack](#stack) | Print stack trace. +[up](#up) | Move the current frame up. + + +## Other commands + +Command | Description +--------|------------ +[check](#check) | Creates a checkpoint at the current position. +[checkpoints](#checkpoints) | Print out info for existing checkpoints. +[clear-checkpoint](#clear-checkpoint) | Deletes checkpoint. +[config](#config) | Changes configuration parameters. +[disassemble](#disassemble) | Disassembler. +[edit](#edit) | Open where you are in $DELVE_EDITOR or $EDITOR +[exit](#exit) | Exit the debugger. +[funcs](#funcs) | Print list of functions. +[help](#help) | Prints the help message. +[libraries](#libraries) | List loaded dynamic libraries +[list](#list) | Show source code. +[rev](#rev) | Reverses the execution of the target program for the command specified. +[source](#source) | Executes a file containing a list of delve commands +[sources](#sources) | Print list of source files. +[types](#types) | Print list of types + ## args Print function arguments. diff --git a/pkg/terminal/command.go b/pkg/terminal/command.go index ae0df28f..f3c5a7b7 100644 --- a/pkg/terminal/command.go +++ b/pkg/terminal/command.go @@ -60,6 +60,7 @@ type cmdfunc func(t *Term, ctx callContext, args string) error type command struct { aliases []string builtinAliases []string + group commandGroup allowedPrefixes cmdPrefix helpMsg string cmdFn cmdfunc @@ -112,21 +113,21 @@ func DebugCommands(client service.Client) *Commands { help [command] Type "help" followed by the name of a command for more information about it.`}, - {aliases: []string{"break", "b"}, cmdFn: breakpoint, helpMsg: `Sets a breakpoint. + {aliases: []string{"break", "b"}, group: breakCmds, cmdFn: breakpoint, helpMsg: `Sets a breakpoint. break [name] See $GOPATH/src/github.com/go-delve/delve/Documentation/cli/locspec.md for the syntax of linespec. See also: "help on", "help cond" and "help clear"`}, - {aliases: []string{"trace", "t"}, cmdFn: tracepoint, helpMsg: `Set tracepoint. + {aliases: []string{"trace", "t"}, group: breakCmds, cmdFn: tracepoint, helpMsg: `Set tracepoint. trace [name] A tracepoint is a breakpoint that does not stop the execution of the program, instead when the tracepoint is hit a notification is displayed. See $GOPATH/src/github.com/go-delve/delve/Documentation/cli/locspec.md for the syntax of linespec. See also: "help on", "help cond" and "help clear"`}, - {aliases: []string{"restart", "r"}, cmdFn: restart, helpMsg: `Restart process. + {aliases: []string{"restart", "r"}, group: runCmds, cmdFn: restart, helpMsg: `Restart process. For recorded targets the command takes the following forms: @@ -141,17 +142,17 @@ For live targets the command takes the following forms: If newargv is omitted the process is restarted (or re-recorded) with the same argument vector. If -noargs is specified instead, the argument vector is cleared. `}, - {aliases: []string{"continue", "c"}, cmdFn: c.cont, helpMsg: "Run until breakpoint or program termination."}, - {aliases: []string{"step", "s"}, cmdFn: c.step, helpMsg: "Single step through program."}, - {aliases: []string{"step-instruction", "si"}, allowedPrefixes: revPrefix, cmdFn: c.stepInstruction, helpMsg: "Single step a single cpu instruction."}, - {aliases: []string{"next", "n"}, cmdFn: c.next, helpMsg: `Step over to next source line. + {aliases: []string{"continue", "c"}, group: runCmds, cmdFn: c.cont, helpMsg: "Run until breakpoint or program termination."}, + {aliases: []string{"step", "s"}, group: runCmds, cmdFn: c.step, helpMsg: "Single step through program."}, + {aliases: []string{"step-instruction", "si"}, group: runCmds, allowedPrefixes: revPrefix, cmdFn: c.stepInstruction, helpMsg: "Single step a single cpu instruction."}, + {aliases: []string{"next", "n"}, group: runCmds, cmdFn: c.next, helpMsg: `Step over to next source line. next [count] Optional [count] argument allows you to skip multiple lines. `}, - {aliases: []string{"stepout", "so"}, cmdFn: c.stepout, helpMsg: "Step out of the current function."}, - {aliases: []string{"call"}, cmdFn: c.call, helpMsg: `Resumes process, injecting a function call (EXPERIMENTAL!!!) + {aliases: []string{"stepout", "so"}, group: runCmds, cmdFn: c.stepout, helpMsg: "Step out of the current function."}, + {aliases: []string{"call"}, group: runCmds, cmdFn: c.call, helpMsg: `Resumes process, injecting a function call (EXPERIMENTAL!!!) call [-unsafe] @@ -167,19 +168,19 @@ Current limitations: - calling a function will resume execution of all goroutines. - only supported on linux's native backend. `}, - {aliases: []string{"threads"}, cmdFn: threads, helpMsg: "Print out info for every traced thread."}, - {aliases: []string{"thread", "tr"}, cmdFn: thread, helpMsg: `Switch to the specified thread. + {aliases: []string{"threads"}, group: goroutineCmds, cmdFn: threads, helpMsg: "Print out info for every traced thread."}, + {aliases: []string{"thread", "tr"}, group: goroutineCmds, cmdFn: thread, helpMsg: `Switch to the specified thread. thread `}, - {aliases: []string{"clear"}, cmdFn: clear, helpMsg: `Deletes breakpoint. + {aliases: []string{"clear"}, group: breakCmds, cmdFn: clear, helpMsg: `Deletes breakpoint. clear `}, - {aliases: []string{"clearall"}, cmdFn: clearAll, helpMsg: `Deletes multiple breakpoints. + {aliases: []string{"clearall"}, group: breakCmds, cmdFn: clearAll, helpMsg: `Deletes multiple breakpoints. clearall [] If called with the linespec argument it will delete all the breakpoints matching the linespec. If linespec is omitted all breakpoints are deleted.`}, - {aliases: []string{"goroutines", "grs"}, cmdFn: goroutines, helpMsg: `List program goroutines. + {aliases: []string{"goroutines", "grs"}, group: goroutineCmds, cmdFn: goroutines, helpMsg: `List program goroutines. goroutines [-u (default: user location)|-r (runtime location)|-g (go statement location)|-s (start location)] [ -t (stack trace)] @@ -193,7 +194,7 @@ Print out info for every goroutine. The flag controls what information is shown -l displays goroutine's labels If no flag is specified the default is -u.`}, - {aliases: []string{"goroutine", "gr"}, allowedPrefixes: onPrefix, cmdFn: c.goroutine, helpMsg: `Shows or changes current goroutine + {aliases: []string{"goroutine", "gr"}, group: goroutineCmds, allowedPrefixes: onPrefix, cmdFn: c.goroutine, helpMsg: `Shows or changes current goroutine goroutine goroutine @@ -202,16 +203,16 @@ If no flag is specified the default is -u.`}, Called without arguments it will show information about the current goroutine. Called with a single argument it will switch to the specified goroutine. Called with more arguments it will execute a command on the specified goroutine.`}, - {aliases: []string{"breakpoints", "bp"}, cmdFn: breakpoints, helpMsg: "Print out info for active breakpoints."}, - {aliases: []string{"print", "p"}, allowedPrefixes: onPrefix | deferredPrefix, cmdFn: printVar, helpMsg: `Evaluate an expression. + {aliases: []string{"breakpoints", "bp"}, group: breakCmds, cmdFn: breakpoints, helpMsg: "Print out info for active breakpoints."}, + {aliases: []string{"print", "p"}, group: dataCmds, allowedPrefixes: onPrefix | deferredPrefix, cmdFn: printVar, helpMsg: `Evaluate an expression. [goroutine ] [frame ] print See $GOPATH/src/github.com/go-delve/delve/Documentation/cli/expr.md for a description of supported expressions.`}, - {aliases: []string{"whatis"}, cmdFn: whatisCommand, helpMsg: `Prints type of an expression. + {aliases: []string{"whatis"}, group: dataCmds, cmdFn: whatisCommand, helpMsg: `Prints type of an expression. whatis `}, - {aliases: []string{"set"}, cmdFn: setVar, helpMsg: `Changes the value of a variable. + {aliases: []string{"set"}, group: dataCmds, cmdFn: setVar, helpMsg: `Changes the value of a variable. [goroutine ] [frame ] set = @@ -231,24 +232,24 @@ If regex is specified only the functions matching it will be returned.`}, types [] If regex is specified only the types matching it will be returned.`}, - {aliases: []string{"args"}, allowedPrefixes: onPrefix | deferredPrefix, cmdFn: args, helpMsg: `Print function arguments. + {aliases: []string{"args"}, allowedPrefixes: onPrefix | deferredPrefix, group: dataCmds, cmdFn: args, helpMsg: `Print function arguments. [goroutine ] [frame ] args [-v] [] If regex is specified only function arguments with a name matching it will be returned. If -v is specified more information about each function argument will be shown.`}, - {aliases: []string{"locals"}, allowedPrefixes: onPrefix | deferredPrefix, cmdFn: locals, helpMsg: `Print local variables. + {aliases: []string{"locals"}, allowedPrefixes: onPrefix | deferredPrefix, group: dataCmds, cmdFn: locals, helpMsg: `Print local variables. [goroutine ] [frame ] locals [-v] [] The name of variables that are shadowed in the current scope will be shown in parenthesis. If regex is specified only local variables with a name matching it will be returned. If -v is specified more information about each local variable will be shown.`}, - {aliases: []string{"vars"}, cmdFn: vars, helpMsg: `Print package variables. + {aliases: []string{"vars"}, cmdFn: vars, group: dataCmds, helpMsg: `Print package variables. vars [-v] [] If regex is specified only package variables with a name matching it will be returned. If -v is specified more information about each package variable will be shown.`}, - {aliases: []string{"regs"}, cmdFn: regs, helpMsg: `Print contents of CPU registers. + {aliases: []string{"regs"}, cmdFn: regs, group: dataCmds, helpMsg: `Print contents of CPU registers. regs [-a] @@ -263,7 +264,7 @@ When connected to a headless instance started with the --accept-multiclient, pas [goroutine ] [frame ] list [] Show source around current point or provided linespec.`}, - {aliases: []string{"stack", "bt"}, allowedPrefixes: onPrefix, cmdFn: stackCommand, helpMsg: `Print stack trace. + {aliases: []string{"stack", "bt"}, allowedPrefixes: onPrefix, group: stackCmds, cmdFn: stackCommand, helpMsg: `Print stack trace. [goroutine ] [frame ] stack [] [-full] [-offsets] [-defer] [-a ] [-adepth ] [-mode ] @@ -278,6 +279,7 @@ Show source around current point or provided linespec.`}, fromg - starts from the registers stored in the runtime.g struct `}, {aliases: []string{"frame"}, + group: stackCmds, cmdFn: func(t *Term, ctx callContext, arg string) error { return c.frameCommand(t, ctx, arg, frameSet) }, @@ -289,6 +291,7 @@ Show source around current point or provided linespec.`}, The first form sets frame used by subsequent commands such as "print" or "set". The second form runs the command on the given frame.`}, {aliases: []string{"up"}, + group: stackCmds, cmdFn: func(t *Term, ctx callContext, arg string) error { return c.frameCommand(t, ctx, arg, frameUp) }, @@ -299,6 +302,7 @@ The second form runs the command on the given frame.`}, Move the current frame up by . The second form runs the command on the given frame.`}, {aliases: []string{"down"}, + group: stackCmds, cmdFn: func(t *Term, ctx callContext, arg string) error { return c.frameCommand(t, ctx, arg, frameDown) }, @@ -308,7 +312,7 @@ Move the current frame up by . The second form runs the command on the given down [] Move the current frame down by . The second form runs the command on the given frame.`}, - {aliases: []string{"deferred"}, cmdFn: c.deferredCommand, helpMsg: `Executes command in the context of a deferred call. + {aliases: []string{"deferred"}, group: stackCmds, cmdFn: c.deferredCommand, helpMsg: `Executes command in the context of a deferred call. deferred @@ -328,12 +332,12 @@ If no argument is specified the function being executed in the selected stack fr -a disassembles the specified address range -l disassembles the specified function`}, - {aliases: []string{"on"}, cmdFn: c.onCmd, helpMsg: `Executes a command when a breakpoint is hit. + {aliases: []string{"on"}, group: breakCmds, cmdFn: c.onCmd, helpMsg: `Executes a command when a breakpoint is hit. on . Supported commands: print, stack and goroutine)`}, - {aliases: []string{"condition", "cond"}, cmdFn: conditionCmd, helpMsg: `Set breakpoint condition. + {aliases: []string{"condition", "cond"}, group: breakCmds, cmdFn: conditionCmd, helpMsg: `Set breakpoint condition. condition . @@ -369,7 +373,7 @@ Defines as an alias to or removes an alias.`}, If locspec is omitted edit will open the current source file in the editor, otherwise it will open the specified location.`}, {aliases: []string{"libraries"}, cmdFn: libraries, helpMsg: `List loaded dynamic libraries`}, - {aliases: []string{"examinemem", "x"}, cmdFn: examineMemoryCmd, helpMsg: `Examine memory: + {aliases: []string{"examinemem", "x"}, group: dataCmds, cmdFn: examineMemoryCmd, helpMsg: `Examine memory: examinemem [-fmt ] [-len ]
@@ -385,6 +389,7 @@ For example: if client == nil || client.Recorded() { c.cmds = append(c.cmds, command{ aliases: []string{"rewind", "rw"}, + group: runCmds, cmdFn: rewind, helpMsg: "Run backwards until breakpoint or program termination.", }) @@ -526,22 +531,31 @@ func (c *Commands) help(t *Term, ctx callContext, args string) error { } fmt.Println("The following commands are available:") - w := new(tabwriter.Writer) - w.Init(os.Stdout, 0, 8, 0, '-', 0) - for _, cmd := range c.cmds { - h := cmd.helpMsg - if idx := strings.Index(h, "\n"); idx >= 0 { - h = h[:idx] + + for _, cgd := range commandGroupDescriptions { + fmt.Printf("\n%s:\n", cgd.description) + w := new(tabwriter.Writer) + w.Init(os.Stdout, 0, 8, 0, '-', 0) + for _, cmd := range c.cmds { + if cmd.group != cgd.group { + continue + } + h := cmd.helpMsg + if idx := strings.Index(h, "\n"); idx >= 0 { + h = h[:idx] + } + if len(cmd.aliases) > 1 { + fmt.Fprintf(w, " %s (alias: %s) \t %s\n", cmd.aliases[0], strings.Join(cmd.aliases[1:], " | "), h) + } else { + fmt.Fprintf(w, " %s \t %s\n", cmd.aliases[0], h) + } } - if len(cmd.aliases) > 1 { - fmt.Fprintf(w, " %s (alias: %s) \t %s\n", cmd.aliases[0], strings.Join(cmd.aliases[1:], " | "), h) - } else { - fmt.Fprintf(w, " %s \t %s\n", cmd.aliases[0], h) + if err := w.Flush(); err != nil { + return err } } - if err := w.Flush(); err != nil { - return err - } + + fmt.Println() fmt.Println("Type help followed by a command for full documentation.") return nil } diff --git a/pkg/terminal/docgen.go b/pkg/terminal/docgen.go index 04972186..bcc2b368 100644 --- a/pkg/terminal/docgen.go +++ b/pkg/terminal/docgen.go @@ -33,18 +33,26 @@ func (commands *Commands) WriteMarkdown(w io.Writer) { fmt.Fprint(w, "The configuration file `config.yml` contains all the configurable options and their default values. ") fmt.Fprint(w, "The command history is stored in `.dbg_history`.\n\n") - fmt.Fprint(w, "# Commands\n\n") + fmt.Fprint(w, "# Commands\n") - fmt.Fprint(w, "Command | Description\n") - fmt.Fprint(w, "--------|------------\n") - for _, cmd := range commands.cmds { - h := cmd.helpMsg - if idx := strings.Index(h, "\n"); idx >= 0 { - h = h[:idx] + for _, cgd := range commandGroupDescriptions { + fmt.Fprintf(w, "\n## %s\n\n", cgd.description) + + fmt.Fprint(w, "Command | Description\n") + fmt.Fprint(w, "--------|------------\n") + for _, cmd := range commands.cmds { + if cmd.group != cgd.group { + continue + } + h := cmd.helpMsg + if idx := strings.Index(h, "\n"); idx >= 0 { + h = h[:idx] + } + fmt.Fprintf(w, "[%s](#%s) | %s\n", cmd.aliases[0], cmd.aliases[0], h) } - fmt.Fprintf(w, "[%s](#%s) | %s\n", cmd.aliases[0], cmd.aliases[0], h) + fmt.Fprint(w, "\n") + } - fmt.Fprint(w, "\n") for _, cmd := range commands.cmds { fmt.Fprintf(w, "## %s\n%s\n\n", cmd.aliases[0], replaceDocPath(cmd.helpMsg)) diff --git a/pkg/terminal/groups.go b/pkg/terminal/groups.go new file mode 100644 index 00000000..29c19f3b --- /dev/null +++ b/pkg/terminal/groups.go @@ -0,0 +1,26 @@ +package terminal + +type commandGroup uint8 + +const ( + otherCmds commandGroup = iota + breakCmds + runCmds + dataCmds + goroutineCmds + stackCmds +) + +type commandGroupDescription struct { + description string + group commandGroup +} + +var commandGroupDescriptions = []commandGroupDescription{ + {"Running the program", runCmds}, + {"Manipulating breakpoints", breakCmds}, + {"Viewing program variables and memory", dataCmds}, + {"Listing and switching between threads and goroutines", goroutineCmds}, + {"Viewing the call stack and selecting frames", stackCmds}, + {"Other commands", otherCmds}, +}