Documentation
¶
Overview ¶
Package debugger implements a simple interactive debugger for starlark-go, aka go.starlark.net/starlark.
The debugger exposes a single breakpoint() function to ordinary Starlark code, which starts up an interactive REPL-style debugging session, in which users can examine the Starlark thread stack and manipulate values.
Stepping through code is not supported due to restrictions in starlark-go. See https://github.com/google/starlark-go/issues/304 for details.
Enabling and disabling breakpoints ¶
By default, all breakpoints are enabled. All breakpoint() calls can be globally disabled by calling Debugger.GlobalDisable, or reenabled with Debugger.GlobalEnable.
Debugger commands ¶
The debugger REPL has a few builtin commands implemented as functions:
Basic debugging:
where(), w() - prints a backtrace backtrace(), bt() - prints a backtrace (same as where) continue_(), c(), cont() - exits the debugger and continue Starlark execution quit(), q() - exits the debugger and fail Starlark execution
Variables:
vars() - prints all available variables and their values in the current frame globals() - returns a dict of global variables from the context of the code calling breakpoint() locals() - returns a dict of local variables from the context of the code calling breakpoint()
Frame manipulation:
frame(i), f(i) - switches the debugging context to the frame at the given index up(), u() - switches the debugging context to the upper frame (the caller of the current frame) up(i), u(i) - switches the debugging context to i'th upper frame (the i'th caller of the current frame) down(), d() - switches the debugging context to the lower frame (the callee of the current frame) down(i), d(i) - switches the debugging context to i'th lower frame (the i'th callee of the current frame)
Concurrency and reentrancy ¶
Since each debugger session takes over the entire os.Stdin, concurrent debugger sessions don't make sense. As such, upon entering the debugging session, a lock is taken, in order to prevent new debugging sessions from launched, and also to wait for previous sessions to finish. This lock is shared across all Debuggers.
Reentrant calls to breakpoint() (i.e., calls to breakpoint() from within a debugging session) are not supported and will be ignored with a warning.
Example ¶
package main
import (
"bytes"
"fmt"
"io"
"os"
"go.starlark.net/starlark"
"go.starlark.net/syntax"
"github.com/stripe/skycfg/debugger"
)
func main() {
// Run this example with
//
// go test -c github.com/stripe/skycfg/debugger && ./debugger.test -example
prog := `
def g():
closure = [42]
def f():
local_var = 1
breakpoint()
print("closure=" + str(closure))
return f
g()()
`
dbg := debugger.New()
thread := starlark.Thread{
Print: printWithPos,
}
starlark.ExecFileOptions(&syntax.FileOptions{}, &thread, "<prog>", prog, starlark.StringDict{
"predeclared": starlark.String("value"),
"breakpoint": dbg.Breakpoint(),
})
}
func printWithPos(thread *starlark.Thread, msg string) {
var buf bytes.Buffer
if thread.CallStackDepth() > 1 {
pos := thread.CallFrame(1).Pos
fmt.Fprintf(&buf, "[%v] ", pos)
}
fmt.Fprintf(&buf, msg)
buf.WriteByte('\n')
io.Copy(os.Stdout, &buf)
}
Output:
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var DefaultDebuggerSyntax = syntax.FileOptions{ Set: true, While: true, TopLevelControl: true, GlobalReassign: true, LoadBindsGlobally: true, Recursion: true, }
DefaultDebuggerSyntax defines the set of Starlark language features available within a debugging session.
Functions ¶
This section is empty.
Types ¶
type Debugger ¶
type Debugger struct {
// contains filtered or unexported fields
}
A Debugger captures shared state across debugging sessions. The same Debugger can be used concurrently from multiple starlark.Threads and goroutines, though as mentioned in the package documentation, only one debug session can be active across all Debuggers at any given point in time.
A new Debugger must be created using New.
func (*Debugger) Breakpoint ¶
Breakpoint returns the breakpoint() Starlark builtin to be added as a global. Breakpoint always returns the same value for the same Debugger.
func (*Debugger) GlobalDisable ¶
func (d *Debugger) GlobalDisable()
GlobalDisable disables all breakpoints.
func (*Debugger) GlobalEnable ¶
func (d *Debugger) GlobalEnable()
GlobalEnable reverses Debugger.GlobalDisable and enables all breakpoints.
func (*Debugger) SetSyntax ¶
func (d *Debugger) SetSyntax(opts *syntax.FileOptions)
SetSyntax sets the Starlark language options that can be used in a debugger session. If SetSyntax is never called, DefaultDebuggerSyntax is used.