parent
4aee281520
commit
c6de961be8
@ -39,6 +39,7 @@ Command | Description
|
||||
Command | Description
|
||||
--------|------------
|
||||
[args](#args) | Print function arguments.
|
||||
[display](#display) | Print value of an expression every time the program stops.
|
||||
[examinemem](#examinemem) | Examine memory:
|
||||
[locals](#locals) | Print local variables.
|
||||
[print](#print) | Evaluate an expression.
|
||||
@ -225,6 +226,17 @@ If no argument is specified the function being executed in the selected stack fr
|
||||
|
||||
Aliases: disass
|
||||
|
||||
## display
|
||||
Print value of an expression every time the program stops.
|
||||
|
||||
display -a <expression>
|
||||
display -d <number>
|
||||
|
||||
The '-a' option adds an expression to the list of expression printed every time the program stops. The '-d' option removes the specified expression from the list.
|
||||
|
||||
If display is called without arguments it will print the value of all expression in the list.
|
||||
|
||||
|
||||
## down
|
||||
Move the current frame down.
|
||||
|
||||
|
@ -384,6 +384,15 @@ Address is the memory location of the target to examine.
|
||||
For example:
|
||||
|
||||
x -fmt hex -len 20 0xc00008af38`},
|
||||
|
||||
{aliases: []string{"display"}, group: dataCmds, cmdFn: display, helpMsg: `Print value of an expression every time the program stops.
|
||||
|
||||
display -a <expression>
|
||||
display -d <number>
|
||||
|
||||
The '-a' option adds an expression to the list of expression printed every time the program stops. The '-d' option removes the specified expression from the list.
|
||||
|
||||
If display is called without arguments it will print the value of all expression in the list.`},
|
||||
}
|
||||
|
||||
if client == nil || client.Recorded() {
|
||||
@ -981,6 +990,7 @@ func restartRecorded(t *Term, ctx callContext, args string) error {
|
||||
}
|
||||
printcontext(t, state)
|
||||
printfile(t, state.CurrentThread.File, state.CurrentThread.Line, true)
|
||||
t.onStop()
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -1057,6 +1067,7 @@ func (c *Commands) cont(t *Term, ctx callContext, args string) error {
|
||||
if ctx.Prefix == revPrefix {
|
||||
return c.rewind(t, ctx, args)
|
||||
}
|
||||
defer t.onStop()
|
||||
c.frame = 0
|
||||
stateChan := t.client.Continue()
|
||||
var state *api.DebuggerState
|
||||
@ -1072,6 +1083,7 @@ func (c *Commands) cont(t *Term, ctx callContext, args string) error {
|
||||
}
|
||||
|
||||
func continueUntilCompleteNext(t *Term, state *api.DebuggerState, op string, shouldPrintFile bool) error {
|
||||
defer t.onStop()
|
||||
if !state.NextInProgress {
|
||||
if shouldPrintFile {
|
||||
printfile(t, state.CurrentThread.File, state.CurrentThread.Line, true)
|
||||
@ -1141,6 +1153,8 @@ func (c *Commands) stepInstruction(t *Term, ctx callContext, args string) error
|
||||
return notOnFrameZeroErr
|
||||
}
|
||||
|
||||
defer t.onStop()
|
||||
|
||||
var fn func() (*api.DebuggerState, error)
|
||||
if ctx.Prefix == revPrefix {
|
||||
fn = t.client.ReverseStepInstruction
|
||||
@ -2386,6 +2400,37 @@ func clearCheckpoint(t *Term, ctx callContext, args string) error {
|
||||
return t.client.ClearCheckpoint(id)
|
||||
}
|
||||
|
||||
func display(t *Term, ctx callContext, args string) error {
|
||||
const (
|
||||
addOption = "-a "
|
||||
delOption = "-d "
|
||||
)
|
||||
switch {
|
||||
case args == "":
|
||||
t.printDisplays()
|
||||
|
||||
case strings.HasPrefix(args, addOption):
|
||||
args = strings.TrimSpace(args[len(addOption):])
|
||||
if args == "" {
|
||||
return fmt.Errorf("not enough arguments")
|
||||
}
|
||||
t.addDisplay(args)
|
||||
t.printDisplay(len(t.displays) - 1)
|
||||
|
||||
case strings.HasPrefix(args, delOption):
|
||||
args = strings.TrimSpace(args[len(delOption):])
|
||||
n, err := strconv.Atoi(args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%q is not a number", args)
|
||||
}
|
||||
return t.removeDisplay(n)
|
||||
|
||||
default:
|
||||
return fmt.Errorf("wrong arguments")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func formatBreakpointName(bp *api.Breakpoint, upcase bool) string {
|
||||
thing := "breakpoint"
|
||||
if bp.Tracepoint {
|
||||
|
@ -54,6 +54,7 @@ type Term struct {
|
||||
dumb bool
|
||||
stdout io.Writer
|
||||
InitFile string
|
||||
displays []string
|
||||
|
||||
starlarkEnv *starbind.Env
|
||||
|
||||
@ -432,6 +433,50 @@ func (t *Term) loadConfig() api.LoadConfig {
|
||||
return r
|
||||
}
|
||||
|
||||
func (t *Term) removeDisplay(n int) error {
|
||||
if n < 0 || n >= len(t.displays) {
|
||||
return fmt.Errorf("%d is out of range", n)
|
||||
}
|
||||
t.displays[n] = ""
|
||||
for i := len(t.displays) - 1; i >= 0; i-- {
|
||||
if t.displays[i] != "" {
|
||||
t.displays = t.displays[:i+1]
|
||||
return nil
|
||||
}
|
||||
}
|
||||
t.displays = t.displays[:0]
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Term) addDisplay(expr string) {
|
||||
t.displays = append(t.displays, expr)
|
||||
}
|
||||
|
||||
func (t *Term) printDisplay(i int) {
|
||||
expr := t.displays[i]
|
||||
val, err := t.client.EvalVariable(api.EvalScope{GoroutineID: -1}, expr, ShortLoadConfig)
|
||||
if err != nil {
|
||||
if isErrProcessExited(err) {
|
||||
return
|
||||
}
|
||||
fmt.Printf("%d: %s = error %v\n", i, expr, err)
|
||||
return
|
||||
}
|
||||
fmt.Printf("%d: %s = %s\n", i, val.Name, val.SinglelineString())
|
||||
}
|
||||
|
||||
func (t *Term) printDisplays() {
|
||||
for i := range t.displays {
|
||||
if t.displays[i] != "" {
|
||||
t.printDisplay(i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Term) onStop() {
|
||||
t.printDisplays()
|
||||
}
|
||||
|
||||
// isErrProcessExited returns true if `err` is an RPC error equivalent of proc.ErrProcessExited
|
||||
func isErrProcessExited(err error) bool {
|
||||
rpcError, ok := err.(rpc.ServerError)
|
||||
|
Loading…
Reference in New Issue
Block a user