terminal/starbind: allow modification of structs returned by API (#3872)

Structs returned to starlark scripts by API calls were immutable, this
made amend_breakpoint nearly impossible to use since its argument must
be a api.Breakpoint struct which the caller has received from
get_breakpoint and modified.
This commit is contained in:
Alessandro Arzilli 2024-12-05 04:09:59 +01:00 committed by GitHub
parent d97b471292
commit 698f838616
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 127 additions and 54 deletions

@ -0,0 +1,6 @@
bp = get_breakpoint(0, "afuncbreak").Breakpoint
bp.Stacktrace = 2
bp.HitCond = "== 2"
amend_breakpoint(bp)
bp2 = get_breakpoint(0, "afuncbreak").Breakpoint
print(bp)

@ -226,7 +226,7 @@ func genMapping(bindings []binding) []byte {
fmt.Fprintf(buf, "err := env.ctx.Client().CallAPI(%q, &rpcArgs, &rpcRet)\n", binding.fn.Name()) fmt.Fprintf(buf, "err := env.ctx.Client().CallAPI(%q, &rpcArgs, &rpcRet)\n", binding.fn.Name())
fmt.Fprintf(buf, "if err != nil { return starlark.None, err }\n") fmt.Fprintf(buf, "if err != nil { return starlark.None, err }\n")
fmt.Fprintf(buf, "return env.interfaceToStarlarkValue(rpcRet), nil\n") fmt.Fprintf(buf, "return env.interfaceToStarlarkValue(&rpcRet), nil\n")
fmt.Fprintf(buf, "})\n") fmt.Fprintf(buf, "})\n")

@ -57,6 +57,11 @@ func (env *Env) interfaceToStarlarkValue(v interface{}) starlark.Value {
return starlark.None return starlark.None
case error: case error:
return starlark.String(v.Error()) return starlark.String(v.Error())
case reflect.Value:
if v.Type().Kind() == reflect.Struct {
return structAsStarlarkValue{v, env}
}
return env.interfaceToStarlarkValue(v.Interface())
default: default:
vval := reflect.ValueOf(v) vval := reflect.ValueOf(v)
switch vval.Type().Kind() { switch vval.Type().Kind() {
@ -185,9 +190,48 @@ func (v structAsStarlarkValue) Attr(name string) (starlark.Value, error) {
} }
r := v.v.FieldByName(name) r := v.v.FieldByName(name)
if !r.IsValid() { if !r.IsValid() {
return starlark.None, fmt.Errorf("no field named %q in %T", name, v.v.Interface()) return starlark.None, starlark.NoSuchAttrError(fmt.Sprintf("no field named %q in %T", name, v.v.Interface()))
} }
return v.env.interfaceToStarlarkValue(r.Interface()), nil return v.env.interfaceToStarlarkValue(r), nil
}
func (v structAsStarlarkValue) SetField(name string, value starlark.Value) (err error) {
defer func() {
// reflect.Value.SetInt, SetFloat, etc panic
ierr := recover()
if ierr == nil {
return
}
err, _ = ierr.(error)
if err == nil {
panic(ierr)
}
err = fmt.Errorf("can not assign to %T.%q: %v", v.v.Interface(), name, err)
}()
if r, err := v.valueAttr(name); err != nil || r != nil {
return starlark.NoSuchAttrError(fmt.Sprintf("no field named %s in %T", name, v.v.Interface()))
}
r := v.v.FieldByName(name)
if !r.IsValid() {
return starlark.NoSuchAttrError(fmt.Sprintf("no field named %q in %T", name, v.v.Interface()))
}
switch value := value.(type) {
case starlark.Int:
n, ok := value.Int64()
if !ok {
return fmt.Errorf("can not assign big integer to %T.%q", v.v.Interface(), name)
}
r.SetInt(n)
case starlark.Float:
r.SetFloat(float64(value))
case starlark.String:
r.SetString(value.GoString())
case starlark.Bool:
r.SetBool(bool(value))
default:
return fmt.Errorf("can not assign value of type %T to %T.%q", value, v.v.Interface(), name)
}
return nil
} }
func (v structAsStarlarkValue) valueAttr(name string) (starlark.Value, error) { func (v structAsStarlarkValue) valueAttr(name string) (starlark.Value, error) {

@ -41,7 +41,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["amend_breakpoint"] = "builtin amend_breakpoint(Breakpoint)\n\namend_breakpoint allows user to update an existing breakpoint\nfor example to change the information retrieved when the\nbreakpoint is hit or to change, add or remove the break condition.\n\narg.Breakpoint.ID must be a valid breakpoint ID" doc["amend_breakpoint"] = "builtin amend_breakpoint(Breakpoint)\n\namend_breakpoint allows user to update an existing breakpoint\nfor example to change the information retrieved when the\nbreakpoint is hit or to change, add or remove the break condition.\n\narg.Breakpoint.ID must be a valid breakpoint ID"
r["ancestors"] = starlark.NewBuiltin("ancestors", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["ancestors"] = starlark.NewBuiltin("ancestors", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -88,7 +88,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["ancestors"] = "builtin ancestors(GoroutineID, NumAncestors, Depth)\n\nancestors returns the stacktraces for the ancestors of a goroutine." doc["ancestors"] = "builtin ancestors(GoroutineID, NumAncestors, Depth)\n\nancestors returns the stacktraces for the ancestors of a goroutine."
r["attached_to_existing_process"] = starlark.NewBuiltin("attached_to_existing_process", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["attached_to_existing_process"] = starlark.NewBuiltin("attached_to_existing_process", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -101,7 +101,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["attached_to_existing_process"] = "builtin attached_to_existing_process()\n\nattached_to_existing_process returns whether we attached to a running process or not" doc["attached_to_existing_process"] = "builtin attached_to_existing_process()\n\nattached_to_existing_process returns whether we attached to a running process or not"
r["build_id"] = starlark.NewBuiltin("build_id", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["build_id"] = starlark.NewBuiltin("build_id", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -114,7 +114,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["build_id"] = "builtin build_id()" doc["build_id"] = "builtin build_id()"
r["cancel_next"] = starlark.NewBuiltin("cancel_next", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["cancel_next"] = starlark.NewBuiltin("cancel_next", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -127,7 +127,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["cancel_next"] = "builtin cancel_next()" doc["cancel_next"] = "builtin cancel_next()"
r["checkpoint"] = starlark.NewBuiltin("checkpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["checkpoint"] = starlark.NewBuiltin("checkpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -158,7 +158,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["checkpoint"] = "builtin checkpoint(Where)" doc["checkpoint"] = "builtin checkpoint(Where)"
r["clear_breakpoint"] = starlark.NewBuiltin("clear_breakpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["clear_breakpoint"] = starlark.NewBuiltin("clear_breakpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -197,7 +197,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["clear_breakpoint"] = "builtin clear_breakpoint(Id, Name)\n\nclear_breakpoint deletes a breakpoint by Name (if Name is not an\nempty string) or by ID." doc["clear_breakpoint"] = "builtin clear_breakpoint(Id, Name)\n\nclear_breakpoint deletes a breakpoint by Name (if Name is not an\nempty string) or by ID."
r["clear_checkpoint"] = starlark.NewBuiltin("clear_checkpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["clear_checkpoint"] = starlark.NewBuiltin("clear_checkpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -228,7 +228,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["clear_checkpoint"] = "builtin clear_checkpoint(ID)" doc["clear_checkpoint"] = "builtin clear_checkpoint(ID)"
r["raw_command"] = starlark.NewBuiltin("raw_command", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["raw_command"] = starlark.NewBuiltin("raw_command", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -302,7 +302,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["raw_command"] = "builtin raw_command(Name, ThreadID, GoroutineID, ReturnInfoLoadConfig, Expr, UnsafeCall)\n\nraw_command interrupts, continues and steps through the program." doc["raw_command"] = "builtin raw_command(Name, ThreadID, GoroutineID, ReturnInfoLoadConfig, Expr, UnsafeCall)\n\nraw_command interrupts, continues and steps through the program."
r["create_breakpoint"] = starlark.NewBuiltin("create_breakpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["create_breakpoint"] = starlark.NewBuiltin("create_breakpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -357,7 +357,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["create_breakpoint"] = "builtin create_breakpoint(Breakpoint, LocExpr, SubstitutePathRules, Suspended)\n\ncreate_breakpoint creates a new breakpoint. The client is expected to populate `CreateBreakpointIn`\nwith an `api.Breakpoint` struct describing where to set the breakpoint. For more information on\nhow to properly request a breakpoint via the `api.Breakpoint` struct see the documentation for\n`debugger.CreateBreakpoint` here: https://pkg.go.dev/github.com/go-delve/delve/service/debugger#Debugger.CreateBreakpoint." doc["create_breakpoint"] = "builtin create_breakpoint(Breakpoint, LocExpr, SubstitutePathRules, Suspended)\n\ncreate_breakpoint creates a new breakpoint. The client is expected to populate `CreateBreakpointIn`\nwith an `api.Breakpoint` struct describing where to set the breakpoint. For more information on\nhow to properly request a breakpoint via the `api.Breakpoint` struct see the documentation for\n`debugger.CreateBreakpoint` here: https://pkg.go.dev/github.com/go-delve/delve/service/debugger#Debugger.CreateBreakpoint."
r["create_ebpf_tracepoint"] = starlark.NewBuiltin("create_ebpf_tracepoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["create_ebpf_tracepoint"] = starlark.NewBuiltin("create_ebpf_tracepoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -388,7 +388,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["create_ebpf_tracepoint"] = "builtin create_ebpf_tracepoint(FunctionName)" doc["create_ebpf_tracepoint"] = "builtin create_ebpf_tracepoint(FunctionName)"
r["create_watchpoint"] = starlark.NewBuiltin("create_watchpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["create_watchpoint"] = starlark.NewBuiltin("create_watchpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -437,7 +437,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["create_watchpoint"] = "builtin create_watchpoint(Scope, Expr, Type)" doc["create_watchpoint"] = "builtin create_watchpoint(Scope, Expr, Type)"
r["debug_info_directories"] = starlark.NewBuiltin("debug_info_directories", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["debug_info_directories"] = starlark.NewBuiltin("debug_info_directories", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -476,7 +476,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["debug_info_directories"] = "builtin debug_info_directories(Set, List)" doc["debug_info_directories"] = "builtin debug_info_directories(Set, List)"
r["detach"] = starlark.NewBuiltin("detach", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["detach"] = starlark.NewBuiltin("detach", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -507,7 +507,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["detach"] = "builtin detach(Kill)\n\ndetach detaches the debugger, optionally killing the process." doc["detach"] = "builtin detach(Kill)\n\ndetach detaches the debugger, optionally killing the process."
r["disassemble"] = starlark.NewBuiltin("disassemble", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["disassemble"] = starlark.NewBuiltin("disassemble", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -564,7 +564,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["disassemble"] = "builtin disassemble(Scope, StartPC, EndPC, Flavour)\n\ndisassemble code.\n\nIf both StartPC and EndPC are non-zero the specified range will be disassembled, otherwise the function containing StartPC will be disassembled.\n\nScope is used to mark the instruction the specified goroutine is stopped at.\n\nDisassemble will also try to calculate the destination address of an absolute indirect CALL if it happens to be the instruction the selected goroutine is stopped at." doc["disassemble"] = "builtin disassemble(Scope, StartPC, EndPC, Flavour)\n\ndisassemble code.\n\nIf both StartPC and EndPC are non-zero the specified range will be disassembled, otherwise the function containing StartPC will be disassembled.\n\nScope is used to mark the instruction the specified goroutine is stopped at.\n\nDisassemble will also try to calculate the destination address of an absolute indirect CALL if it happens to be the instruction the selected goroutine is stopped at."
r["dump_cancel"] = starlark.NewBuiltin("dump_cancel", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["dump_cancel"] = starlark.NewBuiltin("dump_cancel", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -577,7 +577,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["dump_cancel"] = "builtin dump_cancel()\n\ndump_cancel cancels the core dump." doc["dump_cancel"] = "builtin dump_cancel()\n\ndump_cancel cancels the core dump."
r["dump_start"] = starlark.NewBuiltin("dump_start", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["dump_start"] = starlark.NewBuiltin("dump_start", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -608,7 +608,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["dump_start"] = "builtin dump_start(Destination)\n\ndump_start starts a core dump to arg.Destination." doc["dump_start"] = "builtin dump_start(Destination)\n\ndump_start starts a core dump to arg.Destination."
r["dump_wait"] = starlark.NewBuiltin("dump_wait", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["dump_wait"] = starlark.NewBuiltin("dump_wait", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -639,7 +639,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["dump_wait"] = "builtin dump_wait(Wait)\n\ndump_wait waits for the core dump to finish or for arg.Wait milliseconds.\nWait == 0 means return immediately.\nReturns the core dump status" doc["dump_wait"] = "builtin dump_wait(Wait)\n\ndump_wait waits for the core dump to finish or for arg.Wait milliseconds.\nWait == 0 means return immediately.\nReturns the core dump status"
r["eval"] = starlark.NewBuiltin("eval", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["eval"] = starlark.NewBuiltin("eval", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -691,7 +691,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["eval"] = "builtin eval(Scope, Expr, Cfg)\n\neval returns a variable in the specified context.\n\nSee https://github.com/go-delve/delve/blob/master/Documentation/cli/expr.md\nfor a description of acceptable values of arg.Expr." doc["eval"] = "builtin eval(Scope, Expr, Cfg)\n\neval returns a variable in the specified context.\n\nSee https://github.com/go-delve/delve/blob/master/Documentation/cli/expr.md\nfor a description of acceptable values of arg.Expr."
r["examine_memory"] = starlark.NewBuiltin("examine_memory", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["examine_memory"] = starlark.NewBuiltin("examine_memory", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -730,7 +730,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["examine_memory"] = "builtin examine_memory(Address, Length)" doc["examine_memory"] = "builtin examine_memory(Address, Length)"
r["find_location"] = starlark.NewBuiltin("find_location", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["find_location"] = starlark.NewBuiltin("find_location", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -787,7 +787,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["find_location"] = "builtin find_location(Scope, Loc, IncludeNonExecutableLines, SubstitutePathRules)\n\nfind_location returns concrete location information described by a location expression.\n\n\tloc ::= <filename>:<line> | <function>[:<line>] | /<regex>/ | (+|-)<offset> | <line> | *<address>\n\t* <filename> can be the full path of a file or just a suffix\n\t* <function> ::= <package>.<receiver type>.<name> | <package>.(*<receiver type>).<name> | <receiver type>.<name> | <package>.<name> | (*<receiver type>).<name> | <name>\n\t <function> must be unambiguous\n\t* /<regex>/ will return a location for each function matched by regex\n\t* +<offset> returns a location for the line that is <offset> lines after the current line\n\t* -<offset> returns a location for the line that is <offset> lines before the current line\n\t* <line> returns a location for a line in the current file\n\t* *<address> returns the location corresponding to the specified address\n\nNOTE: this function does not actually set breakpoints." doc["find_location"] = "builtin find_location(Scope, Loc, IncludeNonExecutableLines, SubstitutePathRules)\n\nfind_location returns concrete location information described by a location expression.\n\n\tloc ::= <filename>:<line> | <function>[:<line>] | /<regex>/ | (+|-)<offset> | <line> | *<address>\n\t* <filename> can be the full path of a file or just a suffix\n\t* <function> ::= <package>.<receiver type>.<name> | <package>.(*<receiver type>).<name> | <receiver type>.<name> | <package>.<name> | (*<receiver type>).<name> | <name>\n\t <function> must be unambiguous\n\t* /<regex>/ will return a location for each function matched by regex\n\t* +<offset> returns a location for the line that is <offset> lines after the current line\n\t* -<offset> returns a location for the line that is <offset> lines before the current line\n\t* <line> returns a location for a line in the current file\n\t* *<address> returns the location corresponding to the specified address\n\nNOTE: this function does not actually set breakpoints."
r["follow_exec"] = starlark.NewBuiltin("follow_exec", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["follow_exec"] = starlark.NewBuiltin("follow_exec", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -826,7 +826,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["follow_exec"] = "builtin follow_exec(Enable, Regex)\n\nfollow_exec enables or disables follow exec mode." doc["follow_exec"] = "builtin follow_exec(Enable, Regex)\n\nfollow_exec enables or disables follow exec mode."
r["follow_exec_enabled"] = starlark.NewBuiltin("follow_exec_enabled", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["follow_exec_enabled"] = starlark.NewBuiltin("follow_exec_enabled", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -839,7 +839,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["follow_exec_enabled"] = "builtin follow_exec_enabled()\n\nfollow_exec_enabled returns true if follow exec mode is enabled." doc["follow_exec_enabled"] = "builtin follow_exec_enabled()\n\nfollow_exec_enabled returns true if follow exec mode is enabled."
r["function_return_locations"] = starlark.NewBuiltin("function_return_locations", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["function_return_locations"] = starlark.NewBuiltin("function_return_locations", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -870,7 +870,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["function_return_locations"] = "builtin function_return_locations(FnName)\n\nfunction_return_locations is the implements the client call of the same name. Look at client documentation for more information." doc["function_return_locations"] = "builtin function_return_locations(FnName)\n\nfunction_return_locations is the implements the client call of the same name. Look at client documentation for more information."
r["get_breakpoint"] = starlark.NewBuiltin("get_breakpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["get_breakpoint"] = starlark.NewBuiltin("get_breakpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -909,7 +909,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["get_breakpoint"] = "builtin get_breakpoint(Id, Name)\n\nget_breakpoint gets a breakpoint by Name (if Name is not an empty string) or by ID." doc["get_breakpoint"] = "builtin get_breakpoint(Id, Name)\n\nget_breakpoint gets a breakpoint by Name (if Name is not an empty string) or by ID."
r["get_buffered_tracepoints"] = starlark.NewBuiltin("get_buffered_tracepoints", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["get_buffered_tracepoints"] = starlark.NewBuiltin("get_buffered_tracepoints", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -922,7 +922,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["get_buffered_tracepoints"] = "builtin get_buffered_tracepoints()" doc["get_buffered_tracepoints"] = "builtin get_buffered_tracepoints()"
r["get_thread"] = starlark.NewBuiltin("get_thread", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["get_thread"] = starlark.NewBuiltin("get_thread", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -953,7 +953,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["get_thread"] = "builtin get_thread(Id)\n\nget_thread gets a thread by its ID." doc["get_thread"] = "builtin get_thread(Id)\n\nget_thread gets a thread by its ID."
r["guess_substitute_path"] = starlark.NewBuiltin("guess_substitute_path", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["guess_substitute_path"] = starlark.NewBuiltin("guess_substitute_path", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -984,7 +984,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["guess_substitute_path"] = "builtin guess_substitute_path(Args)" doc["guess_substitute_path"] = "builtin guess_substitute_path(Args)"
r["is_multiclient"] = starlark.NewBuiltin("is_multiclient", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["is_multiclient"] = starlark.NewBuiltin("is_multiclient", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -997,7 +997,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["is_multiclient"] = "builtin is_multiclient()" doc["is_multiclient"] = "builtin is_multiclient()"
r["last_modified"] = starlark.NewBuiltin("last_modified", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["last_modified"] = starlark.NewBuiltin("last_modified", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -1010,7 +1010,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["last_modified"] = "builtin last_modified()" doc["last_modified"] = "builtin last_modified()"
r["breakpoints"] = starlark.NewBuiltin("breakpoints", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["breakpoints"] = starlark.NewBuiltin("breakpoints", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -1041,7 +1041,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["breakpoints"] = "builtin breakpoints(All)\n\nbreakpoints gets all breakpoints." doc["breakpoints"] = "builtin breakpoints(All)\n\nbreakpoints gets all breakpoints."
r["checkpoints"] = starlark.NewBuiltin("checkpoints", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["checkpoints"] = starlark.NewBuiltin("checkpoints", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -1054,7 +1054,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["checkpoints"] = "builtin checkpoints()" doc["checkpoints"] = "builtin checkpoints()"
r["dynamic_libraries"] = starlark.NewBuiltin("dynamic_libraries", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["dynamic_libraries"] = starlark.NewBuiltin("dynamic_libraries", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -1067,7 +1067,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["dynamic_libraries"] = "builtin dynamic_libraries()" doc["dynamic_libraries"] = "builtin dynamic_libraries()"
r["function_args"] = starlark.NewBuiltin("function_args", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["function_args"] = starlark.NewBuiltin("function_args", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -1110,7 +1110,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["function_args"] = "builtin function_args(Scope, Cfg)\n\nfunction_args lists all arguments to the current function" doc["function_args"] = "builtin function_args(Scope, Cfg)\n\nfunction_args lists all arguments to the current function"
r["functions"] = starlark.NewBuiltin("functions", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["functions"] = starlark.NewBuiltin("functions", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -1149,7 +1149,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["functions"] = "builtin functions(Filter, FollowCalls)\n\nfunctions lists all functions in the process matching filter." doc["functions"] = "builtin functions(Filter, FollowCalls)\n\nfunctions lists all functions in the process matching filter."
r["goroutines"] = starlark.NewBuiltin("goroutines", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["goroutines"] = starlark.NewBuiltin("goroutines", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -1215,7 +1215,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["goroutines"] = "builtin goroutines(Start, Count, Filters, GoroutineGroupingOptions, EvalScope)\n\ngoroutines lists all goroutines.\nIf Count is specified ListGoroutines will return at the first Count\ngoroutines and an index in Nextg, that can be passed as the Start\nparameter, to get more goroutines from ListGoroutines.\nPassing a value of Start that wasn't returned by ListGoroutines will skip\nan undefined number of goroutines.\n\nIf arg.Filters are specified the list of returned goroutines is filtered\napplying the specified filters.\nFor example:\n\n\tListGoroutinesFilter{ Kind: ListGoroutinesFilterUserLoc, Negated: false, Arg: \"afile.go\" }\n\nwill only return goroutines whose UserLoc contains \"afile.go\" as a substring.\nMore specifically a goroutine matches a location filter if the specified\nlocation, formatted like this:\n\n\tfilename:lineno in function\n\ncontains Arg[0] as a substring.\n\nFilters can also be applied to goroutine labels:\n\n\tListGoroutineFilter{ Kind: ListGoroutinesFilterLabel, Negated: false, Arg: \"key=value\" }\n\nthis filter will only return goroutines that have a key=value label.\n\nIf arg.GroupBy is not GoroutineFieldNone then the goroutines will\nbe grouped with the specified criterion.\nIf the value of arg.GroupBy is GoroutineLabel goroutines will\nbe grouped by the value of the label with key GroupByKey.\nFor each group a maximum of MaxGroupMembers example goroutines are\nreturned, as well as the total number of goroutines in the group." doc["goroutines"] = "builtin goroutines(Start, Count, Filters, GoroutineGroupingOptions, EvalScope)\n\ngoroutines lists all goroutines.\nIf Count is specified ListGoroutines will return at the first Count\ngoroutines and an index in Nextg, that can be passed as the Start\nparameter, to get more goroutines from ListGoroutines.\nPassing a value of Start that wasn't returned by ListGoroutines will skip\nan undefined number of goroutines.\n\nIf arg.Filters are specified the list of returned goroutines is filtered\napplying the specified filters.\nFor example:\n\n\tListGoroutinesFilter{ Kind: ListGoroutinesFilterUserLoc, Negated: false, Arg: \"afile.go\" }\n\nwill only return goroutines whose UserLoc contains \"afile.go\" as a substring.\nMore specifically a goroutine matches a location filter if the specified\nlocation, formatted like this:\n\n\tfilename:lineno in function\n\ncontains Arg[0] as a substring.\n\nFilters can also be applied to goroutine labels:\n\n\tListGoroutineFilter{ Kind: ListGoroutinesFilterLabel, Negated: false, Arg: \"key=value\" }\n\nthis filter will only return goroutines that have a key=value label.\n\nIf arg.GroupBy is not GoroutineFieldNone then the goroutines will\nbe grouped with the specified criterion.\nIf the value of arg.GroupBy is GoroutineLabel goroutines will\nbe grouped by the value of the label with key GroupByKey.\nFor each group a maximum of MaxGroupMembers example goroutines are\nreturned, as well as the total number of goroutines in the group."
r["local_vars"] = starlark.NewBuiltin("local_vars", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["local_vars"] = starlark.NewBuiltin("local_vars", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -1258,7 +1258,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["local_vars"] = "builtin local_vars(Scope, Cfg)\n\nlocal_vars lists all local variables in scope." doc["local_vars"] = "builtin local_vars(Scope, Cfg)\n\nlocal_vars lists all local variables in scope."
r["package_vars"] = starlark.NewBuiltin("package_vars", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["package_vars"] = starlark.NewBuiltin("package_vars", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -1299,7 +1299,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["package_vars"] = "builtin package_vars(Filter, Cfg)\n\npackage_vars lists all package variables in the context of the current thread." doc["package_vars"] = "builtin package_vars(Filter, Cfg)\n\npackage_vars lists all package variables in the context of the current thread."
r["packages_build_info"] = starlark.NewBuiltin("packages_build_info", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["packages_build_info"] = starlark.NewBuiltin("packages_build_info", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -1338,7 +1338,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["packages_build_info"] = "builtin packages_build_info(IncludeFiles, Filter)\n\npackages_build_info returns the list of packages used by the program along with\nthe directory where each package was compiled and optionally the list of\nfiles constituting the package.\nNote that the directory path is a best guess and may be wrong is a tool\nother than cmd/go is used to perform the build." doc["packages_build_info"] = "builtin packages_build_info(IncludeFiles, Filter)\n\npackages_build_info returns the list of packages used by the program along with\nthe directory where each package was compiled and optionally the list of\nfiles constituting the package.\nNote that the directory path is a best guess and may be wrong is a tool\nother than cmd/go is used to perform the build."
r["registers"] = starlark.NewBuiltin("registers", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["registers"] = starlark.NewBuiltin("registers", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -1388,7 +1388,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["registers"] = "builtin registers(ThreadID, IncludeFp, Scope)\n\nregisters lists registers and their values.\nIf ListRegistersIn.Scope is not nil the registers of that eval scope will\nbe returned, otherwise ListRegistersIn.ThreadID will be used." doc["registers"] = "builtin registers(ThreadID, IncludeFp, Scope)\n\nregisters lists registers and their values.\nIf ListRegistersIn.Scope is not nil the registers of that eval scope will\nbe returned, otherwise ListRegistersIn.ThreadID will be used."
r["sources"] = starlark.NewBuiltin("sources", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["sources"] = starlark.NewBuiltin("sources", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -1419,7 +1419,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["sources"] = "builtin sources(Filter)\n\nsources lists all source files in the process matching filter." doc["sources"] = "builtin sources(Filter)\n\nsources lists all source files in the process matching filter."
r["targets"] = starlark.NewBuiltin("targets", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["targets"] = starlark.NewBuiltin("targets", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -1432,7 +1432,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["targets"] = "builtin targets()\n\ntargets returns the list of targets we are currently attached to." doc["targets"] = "builtin targets()\n\ntargets returns the list of targets we are currently attached to."
r["threads"] = starlark.NewBuiltin("threads", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["threads"] = starlark.NewBuiltin("threads", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -1445,7 +1445,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["threads"] = "builtin threads()\n\nthreads lists all threads." doc["threads"] = "builtin threads()\n\nthreads lists all threads."
r["types"] = starlark.NewBuiltin("types", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["types"] = starlark.NewBuiltin("types", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -1476,7 +1476,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["types"] = "builtin types(Filter)\n\ntypes lists all types in the process matching filter." doc["types"] = "builtin types(Filter)\n\ntypes lists all types in the process matching filter."
r["process_pid"] = starlark.NewBuiltin("process_pid", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["process_pid"] = starlark.NewBuiltin("process_pid", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -1489,7 +1489,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["process_pid"] = "builtin process_pid()\n\nprocess_pid returns the pid of the process we are debugging." doc["process_pid"] = "builtin process_pid()\n\nprocess_pid returns the pid of the process we are debugging."
r["recorded"] = starlark.NewBuiltin("recorded", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["recorded"] = starlark.NewBuiltin("recorded", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -1502,7 +1502,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["recorded"] = "builtin recorded()" doc["recorded"] = "builtin recorded()"
r["restart"] = starlark.NewBuiltin("restart", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["restart"] = starlark.NewBuiltin("restart", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -1573,7 +1573,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["restart"] = "builtin restart(Position, ResetArgs, NewArgs, Rerecord, Rebuild, NewRedirects)\n\nrestart restarts program." doc["restart"] = "builtin restart(Position, ResetArgs, NewArgs, Rerecord, Rebuild, NewRedirects)\n\nrestart restarts program."
r["set_expr"] = starlark.NewBuiltin("set_expr", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["set_expr"] = starlark.NewBuiltin("set_expr", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -1622,7 +1622,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["set_expr"] = "builtin set_expr(Scope, Symbol, Value)\n\nset_expr sets the value of a variable. Only numerical types and\npointers are currently supported." doc["set_expr"] = "builtin set_expr(Scope, Symbol, Value)\n\nset_expr sets the value of a variable. Only numerical types and\npointers are currently supported."
r["stacktrace"] = starlark.NewBuiltin("stacktrace", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["stacktrace"] = starlark.NewBuiltin("stacktrace", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -1693,7 +1693,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["stacktrace"] = "builtin stacktrace(Id, Depth, Full, Defers, Opts, Cfg)\n\nstacktrace returns stacktrace of goroutine Id up to the specified Depth.\n\nIf Full is set it will also the variable of all local variables\nand function arguments of all stack frames." doc["stacktrace"] = "builtin stacktrace(Id, Depth, Full, Defers, Opts, Cfg)\n\nstacktrace returns stacktrace of goroutine Id up to the specified Depth.\n\nIf Full is set it will also the variable of all local variables\nand function arguments of all stack frames."
r["state"] = starlark.NewBuiltin("state", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["state"] = starlark.NewBuiltin("state", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -1724,7 +1724,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["state"] = "builtin state(NonBlocking)\n\nstate returns the current debugger state." doc["state"] = "builtin state(NonBlocking)\n\nstate returns the current debugger state."
r["toggle_breakpoint"] = starlark.NewBuiltin("toggle_breakpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) { r["toggle_breakpoint"] = starlark.NewBuiltin("toggle_breakpoint", func(thread *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
@ -1763,7 +1763,7 @@ func (env *Env) starlarkPredeclare() (starlark.StringDict, map[string]string) {
if err != nil { if err != nil {
return starlark.None, err return starlark.None, err
} }
return env.interfaceToStarlarkValue(rpcRet), nil return env.interfaceToStarlarkValue(&rpcRet), nil
}) })
doc["toggle_breakpoint"] = "builtin toggle_breakpoint(Id, Name)\n\ntoggle_breakpoint toggles on or off a breakpoint by Name (if Name is not an\nempty string) or by ID." doc["toggle_breakpoint"] = "builtin toggle_breakpoint(Id, Name)\n\ntoggle_breakpoint toggles on or off a breakpoint by Name (if Name is not an\nempty string) or by ID."
return r, doc return r, doc

@ -16,6 +16,7 @@ func TestStarlarkExamples(t *testing.T) {
t.Run("echo_expr", func(t *testing.T) { testStarlarkEchoExpr(t, term) }) t.Run("echo_expr", func(t *testing.T) { testStarlarkEchoExpr(t, term) })
t.Run("find_array", func(t *testing.T) { testStarlarkFindArray(t, term) }) t.Run("find_array", func(t *testing.T) { testStarlarkFindArray(t, term) })
t.Run("map_iteration", func(t *testing.T) { testStarlarkMapIteration(t, term) }) t.Run("map_iteration", func(t *testing.T) { testStarlarkMapIteration(t, term) })
t.Run("amend_breakpoint", func(t *testing.T) { testStarlarkAmendBreakpoint(t, term) })
}) })
} }
@ -36,6 +37,19 @@ func testStarlarkExampleCreateBreakpointmain(t *testing.T, term *FakeTerminal) {
if !strings.Contains(out2p2, "main.afunc1") { if !strings.Contains(out2p2, "main.afunc1") {
t.Fatalf("create_breakpoint_runtime_func example failed") t.Fatalf("create_breakpoint_runtime_func example failed")
} }
bps, err := term.client.ListBreakpoints(false)
if err != nil {
t.Fatalf("Could not clear breakpoints: %v\n", err)
}
for _, bp := range bps {
if bp.ID <= 0 {
continue
}
_, err = term.client.ClearBreakpoint(bp.ID)
if err != nil {
t.Fatalf("Could not clear breakpoints: %v\n", err)
}
}
} }
func testStarlarkExampleSwitchToMainGoroutine(t *testing.T, term *FakeTerminal) { func testStarlarkExampleSwitchToMainGoroutine(t *testing.T, term *FakeTerminal) {
@ -118,6 +132,15 @@ func testStarlarkMapIteration(t *testing.T, term *FakeTerminal) {
t.Logf("%s", out) t.Logf("%s", out)
} }
func testStarlarkAmendBreakpoint(t *testing.T, term *FakeTerminal) {
term.MustExec("break afuncbreak main.afunc")
out := term.MustExec("source " + findStarFile("amend_breakpoint"))
t.Logf("%s", out)
if !strings.Contains(out, "Stacktrace:2") || !strings.Contains(out, `HitCond:"== 2"`) {
t.Fatalf("wrong output")
}
}
func TestStarlarkVariable(t *testing.T) { func TestStarlarkVariable(t *testing.T) {
withTestTerminal("testvariables2", t, func(term *FakeTerminal) { withTestTerminal("testvariables2", t, func(term *FakeTerminal) {
term.MustExec("continue") term.MustExec("continue")