terminal: let 'list' work on file:line exprs that don't map to code (#1728)
Make the 'list' command succeed for file:line expressions that don't map to any instruction. Adds an argument to the FindLocations API call that makes FindLocations return if the expression can be parsed, even if it doesn't end up matching any instruction in debug_line.
This commit is contained in:
parent
d064d1fe05
commit
ccf57b9454
@ -29,7 +29,7 @@ create_breakpoint(Breakpoint) | Equivalent to API call [CreateBreakpoint](https:
|
||||
detach(Kill) | Equivalent to API call [Detach](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.Detach)
|
||||
disassemble(Scope, StartPC, EndPC, Flavour) | Equivalent to API call [Disassemble](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.Disassemble)
|
||||
eval(Scope, Expr, Cfg) | Equivalent to API call [Eval](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.Eval)
|
||||
find_location(Scope, Loc) | Equivalent to API call [FindLocation](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.FindLocation)
|
||||
find_location(Scope, Loc, IncludeNonExecutableLines) | Equivalent to API call [FindLocation](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.FindLocation)
|
||||
function_return_locations(FnName) | Equivalent to API call [FunctionReturnLocations](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.FunctionReturnLocations)
|
||||
get_breakpoint(Id, Name) | Equivalent to API call [GetBreakpoint](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.GetBreakpoint)
|
||||
get_thread(Id) | Equivalent to API call [GetThread](https://godoc.org/github.com/go-delve/delve/service/rpc2#RPCServer.GetThread)
|
||||
|
@ -377,6 +377,19 @@ func (bi *BinaryInfo) PCToLine(pc uint64) (string, int, *Function) {
|
||||
return f, ln, fn
|
||||
}
|
||||
|
||||
type ErrCouldNotFindLine struct {
|
||||
fileFound bool
|
||||
filename string
|
||||
lineno int
|
||||
}
|
||||
|
||||
func (err *ErrCouldNotFindLine) Error() string {
|
||||
if err.fileFound {
|
||||
return fmt.Sprintf("could not find statement at %s:%d, please use a line with a statement", err.filename, err.lineno)
|
||||
}
|
||||
return fmt.Sprintf("could not find file %s", err.filename)
|
||||
}
|
||||
|
||||
// LineToPC converts a file:line into a memory address.
|
||||
func (bi *BinaryInfo) LineToPC(filename string, lineno int) (pc uint64, fn *Function, err error) {
|
||||
fileFound := false
|
||||
@ -398,11 +411,7 @@ func (bi *BinaryInfo) LineToPC(filename string, lineno int) (pc uint64, fn *Func
|
||||
}
|
||||
}
|
||||
}
|
||||
if fileFound {
|
||||
return 0, nil, fmt.Errorf("could not find statement at %s:%d, please use a line with a statement", filename, lineno)
|
||||
} else {
|
||||
return 0, nil, fmt.Errorf("could not find file %s", filename)
|
||||
}
|
||||
return 0, nil, &ErrCouldNotFindLine{fileFound, filename, lineno}
|
||||
}
|
||||
|
||||
// AllPCsForFileLine returns all PC addresses for the given filename:lineno.
|
||||
|
@ -1182,7 +1182,7 @@ func clearAll(t *Term, ctx callContext, args string) error {
|
||||
|
||||
var locPCs map[uint64]struct{}
|
||||
if args != "" {
|
||||
locs, err := t.client.FindLocation(api.EvalScope{GoroutineID: -1, Frame: 0}, args)
|
||||
locs, err := t.client.FindLocation(api.EvalScope{GoroutineID: -1, Frame: 0}, args, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1282,7 +1282,7 @@ func setBreakpoint(t *Term, ctx callContext, tracepoint bool, argstr string) err
|
||||
}
|
||||
|
||||
requestedBp.Tracepoint = tracepoint
|
||||
locs, err := t.client.FindLocation(ctx.Scope, locspec)
|
||||
locs, err := t.client.FindLocation(ctx.Scope, locspec, true)
|
||||
if err != nil {
|
||||
if requestedBp.Name == "" {
|
||||
return err
|
||||
@ -1290,7 +1290,7 @@ func setBreakpoint(t *Term, ctx callContext, tracepoint bool, argstr string) err
|
||||
requestedBp.Name = ""
|
||||
locspec = argstr
|
||||
var err2 error
|
||||
locs, err2 = t.client.FindLocation(ctx.Scope, locspec)
|
||||
locs, err2 = t.client.FindLocation(ctx.Scope, locspec, true)
|
||||
if err2 != nil {
|
||||
return err
|
||||
}
|
||||
@ -1665,7 +1665,7 @@ func getLocation(t *Term, ctx callContext, args string, showContext bool) (file
|
||||
return loc.File, loc.Line, true, nil
|
||||
|
||||
default:
|
||||
locs, err := t.client.FindLocation(ctx.Scope, args)
|
||||
locs, err := t.client.FindLocation(ctx.Scope, args, false)
|
||||
if err != nil {
|
||||
return "", 0, false, err
|
||||
}
|
||||
@ -1724,7 +1724,7 @@ func disassCommand(t *Term, ctx callContext, args string) error {
|
||||
|
||||
switch cmd {
|
||||
case "":
|
||||
locs, err := t.client.FindLocation(ctx.Scope, "+0")
|
||||
locs, err := t.client.FindLocation(ctx.Scope, "+0", true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1744,7 +1744,7 @@ func disassCommand(t *Term, ctx callContext, args string) error {
|
||||
}
|
||||
disasm, disasmErr = t.client.DisassembleRange(ctx.Scope, uint64(startpc), uint64(endpc), api.IntelFlavour)
|
||||
case "-l":
|
||||
locs, err := t.client.FindLocation(ctx.Scope, rest)
|
||||
locs, err := t.client.FindLocation(ctx.Scope, rest, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -580,7 +580,7 @@ func listIsAt(t *testing.T, term *FakeTerminal, listcmd string, cur, start, end
|
||||
|
||||
t.Logf("%q: %q", listcmd, outstr)
|
||||
|
||||
if !strings.Contains(lines[0], fmt.Sprintf(":%d", cur)) {
|
||||
if cur >= 0 && !strings.Contains(lines[0], fmt.Sprintf(":%d", cur)) {
|
||||
t.Fatalf("Could not find current line number in first output line: %q", lines[0])
|
||||
}
|
||||
|
||||
@ -627,6 +627,8 @@ func TestListCmd(t *testing.T) {
|
||||
if err == nil {
|
||||
t.Fatalf("Expected error requesting 50th frame")
|
||||
}
|
||||
listIsAt(t, term, "list testvariables.go:1", -1, 1, 6)
|
||||
listIsAt(t, term, "list testvariables.go:10000", -1, 0, 0)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -470,6 +470,12 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
|
||||
return starlark.None, decorateError(thread, err)
|
||||
}
|
||||
}
|
||||
if len(args) > 2 && args[2] != starlark.None {
|
||||
err := unmarshalStarlarkValue(args[2], &rpcArgs.IncludeNonExecutableLines, "IncludeNonExecutableLines")
|
||||
if err != nil {
|
||||
return starlark.None, decorateError(thread, err)
|
||||
}
|
||||
}
|
||||
for _, kv := range kwargs {
|
||||
var err error
|
||||
switch kv[0].(starlark.String) {
|
||||
@ -477,6 +483,8 @@ func (env *Env) starlarkPredeclare() starlark.StringDict {
|
||||
err = unmarshalStarlarkValue(kv[1], &rpcArgs.Scope, "Scope")
|
||||
case "Loc":
|
||||
err = unmarshalStarlarkValue(kv[1], &rpcArgs.Loc, "Loc")
|
||||
case "IncludeNonExecutableLines":
|
||||
err = unmarshalStarlarkValue(kv[1], &rpcArgs.IncludeNonExecutableLines, "IncludeNonExecutableLines")
|
||||
default:
|
||||
err = fmt.Errorf("unknown argument %q", kv[0])
|
||||
}
|
||||
|
@ -119,7 +119,8 @@ type Client interface {
|
||||
// * <line> returns a location for a line in the current file
|
||||
// * *<address> returns the location corresponding to the specified address
|
||||
// NOTE: this function does not actually set breakpoints.
|
||||
FindLocation(scope api.EvalScope, loc string) ([]api.Location, error)
|
||||
// If findInstruction is true FindLocation will only return locations that correspond to instructions.
|
||||
FindLocation(scope api.EvalScope, loc string, findInstruction bool) ([]api.Location, error)
|
||||
|
||||
// Disassemble code between startPC and endPC
|
||||
DisassembleRange(scope api.EvalScope, startPC, endPC uint64, flavour api.AssemblyFlavour) (api.AsmInstructions, error)
|
||||
|
@ -1145,7 +1145,7 @@ func (d *Debugger) convertDefers(defers []*proc.Defer) []api.Defer {
|
||||
}
|
||||
|
||||
// FindLocation will find the location specified by 'locStr'.
|
||||
func (d *Debugger) FindLocation(scope api.EvalScope, locStr string) ([]api.Location, error) {
|
||||
func (d *Debugger) FindLocation(scope api.EvalScope, locStr string, includeNonExecutableLines bool) ([]api.Location, error) {
|
||||
d.processMutex.Lock()
|
||||
defer d.processMutex.Unlock()
|
||||
|
||||
@ -1160,8 +1160,11 @@ func (d *Debugger) FindLocation(scope api.EvalScope, locStr string) ([]api.Locat
|
||||
|
||||
s, _ := proc.ConvertEvalScope(d.target, scope.GoroutineID, scope.Frame, scope.DeferredCall)
|
||||
|
||||
locs, err := loc.Find(d, s, locStr)
|
||||
locs, err := loc.Find(d, s, locStr, includeNonExecutableLines)
|
||||
for i := range locs {
|
||||
if locs[i].PC == 0 {
|
||||
continue
|
||||
}
|
||||
file, line, fn := d.target.BinInfo().PCToLine(locs[i].PC)
|
||||
locs[i].File = file
|
||||
locs[i].Line = line
|
||||
|
@ -17,7 +17,7 @@ import (
|
||||
const maxFindLocationCandidates = 5
|
||||
|
||||
type LocationSpec interface {
|
||||
Find(d *Debugger, scope *proc.EvalScope, locStr string) ([]api.Location, error)
|
||||
Find(d *Debugger, scope *proc.EvalScope, locStr string, includeNonExecutableLines bool) ([]api.Location, error)
|
||||
}
|
||||
|
||||
type NormalLocationSpec struct {
|
||||
@ -242,7 +242,7 @@ func (spec *FuncLocationSpec) Match(sym proc.Function) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (loc *RegexLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr string) ([]api.Location, error) {
|
||||
func (loc *RegexLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr string, includeNonExecutableLines bool) ([]api.Location, error) {
|
||||
funcs := d.target.BinInfo().Functions
|
||||
matches, err := regexFilterFuncs(loc.FuncRegex, funcs)
|
||||
if err != nil {
|
||||
@ -258,7 +258,7 @@ func (loc *RegexLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr st
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (loc *AddrLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr string) ([]api.Location, error) {
|
||||
func (loc *AddrLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr string, includeNonExecutableLines bool) ([]api.Location, error) {
|
||||
if scope == nil {
|
||||
addr, err := strconv.ParseInt(loc.AddrExpr, 0, 64)
|
||||
if err != nil {
|
||||
@ -330,7 +330,7 @@ func (ale AmbiguousLocationError) Error() string {
|
||||
return fmt.Sprintf("Location \"%s\" ambiguous: %s…", ale.Location, strings.Join(candidates, ", "))
|
||||
}
|
||||
|
||||
func (loc *NormalLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr string) ([]api.Location, error) {
|
||||
func (loc *NormalLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr string, includeNonExecutableLines bool) ([]api.Location, error) {
|
||||
limit := maxFindLocationCandidates
|
||||
var candidateFiles []string
|
||||
for _, file := range d.target.BinInfo().Sources {
|
||||
@ -367,7 +367,7 @@ func (loc *NormalLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr s
|
||||
// expression that the user forgot to prefix with '*', try treating it as
|
||||
// such.
|
||||
addrSpec := &AddrLocationSpec{locStr}
|
||||
locs, err := addrSpec.Find(d, scope, locStr)
|
||||
locs, err := addrSpec.Find(d, scope, locStr, includeNonExecutableLines)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Location \"%s\" not found", locStr)
|
||||
}
|
||||
@ -384,6 +384,11 @@ func (loc *NormalLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr s
|
||||
return nil, fmt.Errorf("Malformed breakpoint location, no line offset specified")
|
||||
}
|
||||
addr, err = proc.FindFileLocation(d.target, candidateFiles[0], loc.LineOffset)
|
||||
if includeNonExecutableLines {
|
||||
if _, isCouldNotFindLine := err.(*proc.ErrCouldNotFindLine); isCouldNotFindLine {
|
||||
return []api.Location{{File: candidateFiles[0], Line: loc.LineOffset}}, nil
|
||||
}
|
||||
}
|
||||
} else { // len(candidateFUncs) == 1
|
||||
addr, err = proc.FindFunctionLocation(d.target, candidateFuncs[0], loc.LineOffset)
|
||||
}
|
||||
@ -394,7 +399,7 @@ func (loc *NormalLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr s
|
||||
return []api.Location{{PC: addr}}, nil
|
||||
}
|
||||
|
||||
func (loc *OffsetLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr string) ([]api.Location, error) {
|
||||
func (loc *OffsetLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr string, includeNonExecutableLines bool) ([]api.Location, error) {
|
||||
if scope == nil {
|
||||
return nil, fmt.Errorf("could not determine current location (scope is nil)")
|
||||
}
|
||||
@ -406,10 +411,15 @@ func (loc *OffsetLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr s
|
||||
return nil, fmt.Errorf("could not determine current location")
|
||||
}
|
||||
addr, err := proc.FindFileLocation(d.target, file, line+loc.Offset)
|
||||
if includeNonExecutableLines {
|
||||
if _, isCouldNotFindLine := err.(*proc.ErrCouldNotFindLine); isCouldNotFindLine {
|
||||
return []api.Location{{File: file, Line: line + loc.Offset}}, nil
|
||||
}
|
||||
}
|
||||
return []api.Location{{PC: addr}}, err
|
||||
}
|
||||
|
||||
func (loc *LineLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr string) ([]api.Location, error) {
|
||||
func (loc *LineLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr string, includeNonExecutableLines bool) ([]api.Location, error) {
|
||||
if scope == nil {
|
||||
return nil, fmt.Errorf("could not determine current location (scope is nil)")
|
||||
}
|
||||
@ -418,5 +428,10 @@ func (loc *LineLocationSpec) Find(d *Debugger, scope *proc.EvalScope, locStr str
|
||||
return nil, fmt.Errorf("could not determine current location")
|
||||
}
|
||||
addr, err := proc.FindFileLocation(d.target, file, loc.Line)
|
||||
if includeNonExecutableLines {
|
||||
if _, isCouldNotFindLine := err.(*proc.ErrCouldNotFindLine); isCouldNotFindLine {
|
||||
return []api.Location{{File: file, Line: loc.Line}}, nil
|
||||
}
|
||||
}
|
||||
return []api.Location{{PC: addr}}, err
|
||||
}
|
||||
|
@ -305,7 +305,7 @@ type FindLocationArgs struct {
|
||||
|
||||
func (c *RPCServer) FindLocation(args FindLocationArgs, answer *[]api.Location) error {
|
||||
var err error
|
||||
*answer, err = c.debugger.FindLocation(args.Scope, args.Loc)
|
||||
*answer, err = c.debugger.FindLocation(args.Scope, args.Loc, false)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -328,9 +328,9 @@ func (c *RPCClient) AttachedToExistingProcess() bool {
|
||||
return out.Answer
|
||||
}
|
||||
|
||||
func (c *RPCClient) FindLocation(scope api.EvalScope, loc string) ([]api.Location, error) {
|
||||
func (c *RPCClient) FindLocation(scope api.EvalScope, loc string, findInstructions bool) ([]api.Location, error) {
|
||||
var out FindLocationOut
|
||||
err := c.call("FindLocation", FindLocationIn{scope, loc}, &out)
|
||||
err := c.call("FindLocation", FindLocationIn{scope, loc, !findInstructions}, &out)
|
||||
return out.Locations, err
|
||||
}
|
||||
|
||||
|
@ -568,8 +568,9 @@ func (c *RPCServer) AttachedToExistingProcess(arg AttachedToExistingProcessIn, o
|
||||
}
|
||||
|
||||
type FindLocationIn struct {
|
||||
Scope api.EvalScope
|
||||
Loc string
|
||||
Scope api.EvalScope
|
||||
Loc string
|
||||
IncludeNonExecutableLines bool
|
||||
}
|
||||
|
||||
type FindLocationOut struct {
|
||||
@ -591,7 +592,7 @@ type FindLocationOut struct {
|
||||
// NOTE: this function does not actually set breakpoints.
|
||||
func (c *RPCServer) FindLocation(arg FindLocationIn, out *FindLocationOut) error {
|
||||
var err error
|
||||
out.Locations, err = c.debugger.FindLocation(arg.Scope, arg.Loc)
|
||||
out.Locations, err = c.debugger.FindLocation(arg.Scope, arg.Loc, arg.IncludeNonExecutableLines)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -75,12 +75,27 @@ func countBreakpoints(t *testing.T, c BreakpointLister) int {
|
||||
return bpcount
|
||||
}
|
||||
|
||||
type LocationFinder interface {
|
||||
type locationFinder1 interface {
|
||||
FindLocation(api.EvalScope, string) ([]api.Location, error)
|
||||
}
|
||||
|
||||
func findLocationHelper(t *testing.T, c LocationFinder, loc string, shouldErr bool, count int, checkAddr uint64) []uint64 {
|
||||
locs, err := c.FindLocation(api.EvalScope{-1, 0, 0}, loc)
|
||||
type locationFinder2 interface {
|
||||
FindLocation(api.EvalScope, string, bool) ([]api.Location, error)
|
||||
}
|
||||
|
||||
func findLocationHelper(t *testing.T, c interface{}, loc string, shouldErr bool, count int, checkAddr uint64) []uint64 {
|
||||
var locs []api.Location
|
||||
var err error
|
||||
|
||||
switch c := c.(type) {
|
||||
case locationFinder1:
|
||||
locs, err = c.FindLocation(api.EvalScope{-1, 0, 0}, loc)
|
||||
case locationFinder2:
|
||||
locs, err = c.FindLocation(api.EvalScope{-1, 0, 0}, loc, false)
|
||||
default:
|
||||
t.Errorf("unexpected type %T passed to findLocationHelper", c)
|
||||
}
|
||||
|
||||
t.Logf("FindLocation(\"%s\") → %v\n", loc, locs)
|
||||
|
||||
if shouldErr {
|
||||
|
@ -924,7 +924,7 @@ func TestIssue355(t *testing.T) {
|
||||
assertError(err, t, "ListGoroutines()")
|
||||
_, err = c.Stacktrace(gid, 10, 0, &normalLoadConfig)
|
||||
assertError(err, t, "Stacktrace()")
|
||||
_, err = c.FindLocation(api.EvalScope{gid, 0, 0}, "+1")
|
||||
_, err = c.FindLocation(api.EvalScope{gid, 0, 0}, "+1", false)
|
||||
assertError(err, t, "FindLocation()")
|
||||
_, err = c.DisassemblePC(api.EvalScope{-1, 0, 0}, 0x40100, api.IntelFlavour)
|
||||
assertError(err, t, "DisassemblePC()")
|
||||
@ -941,7 +941,7 @@ func TestDisasm(t *testing.T) {
|
||||
state := <-ch
|
||||
assertNoError(state.Err, t, "Continue()")
|
||||
|
||||
locs, err := c.FindLocation(api.EvalScope{-1, 0, 0}, "main.main")
|
||||
locs, err := c.FindLocation(api.EvalScope{-1, 0, 0}, "main.main", false)
|
||||
assertNoError(err, t, "FindLocation()")
|
||||
if len(locs) != 1 {
|
||||
t.Fatalf("wrong number of locations for main.main: %d", len(locs))
|
||||
@ -1192,7 +1192,7 @@ func TestTypesCommand(t *testing.T) {
|
||||
func TestIssue406(t *testing.T) {
|
||||
protest.AllowRecording(t)
|
||||
withTestClient2("issue406", t, func(c service.Client) {
|
||||
locs, err := c.FindLocation(api.EvalScope{-1, 0, 0}, "issue406.go:146")
|
||||
locs, err := c.FindLocation(api.EvalScope{-1, 0, 0}, "issue406.go:146", false)
|
||||
assertNoError(err, t, "FindLocation()")
|
||||
_, err = c.CreateBreakpoint(&api.Breakpoint{Addr: locs[0].PC})
|
||||
assertNoError(err, t, "CreateBreakpoint()")
|
||||
@ -1545,7 +1545,7 @@ func TestAcceptMulticlient(t *testing.T) {
|
||||
}
|
||||
|
||||
func mustHaveDebugCalls(t *testing.T, c service.Client) {
|
||||
locs, err := c.FindLocation(api.EvalScope{-1, 0, 0}, "runtime.debugCallV1")
|
||||
locs, err := c.FindLocation(api.EvalScope{-1, 0, 0}, "runtime.debugCallV1", false)
|
||||
if len(locs) == 0 || err != nil {
|
||||
t.Skip("function calls not supported on this version of go")
|
||||
}
|
||||
@ -1589,7 +1589,7 @@ func TestClientServerFunctionCallBadPos(t *testing.T) {
|
||||
}
|
||||
withTestClient2("fncall", t, func(c service.Client) {
|
||||
mustHaveDebugCalls(t, c)
|
||||
loc, err := c.FindLocation(api.EvalScope{-1, 0, 0}, "fmt/print.go:649")
|
||||
loc, err := c.FindLocation(api.EvalScope{-1, 0, 0}, "fmt/print.go:649", false)
|
||||
assertNoError(err, t, "could not find location")
|
||||
|
||||
_, err = c.CreateBreakpoint(&api.Breakpoint{File: loc[0].File, Line: loc[0].Line})
|
||||
@ -1723,7 +1723,7 @@ func TestUnknownMethodCall(t *testing.T) {
|
||||
func TestIssue1703(t *testing.T) {
|
||||
// Calling Disassemble when there is no current goroutine should work.
|
||||
withTestClient2("testnextprog", t, func(c service.Client) {
|
||||
locs, err := c.FindLocation(api.EvalScope{GoroutineID: -1}, "main.main")
|
||||
locs, err := c.FindLocation(api.EvalScope{GoroutineID: -1}, "main.main", true)
|
||||
assertNoError(err, t, "FindLocation")
|
||||
t.Logf("FindLocation: %#v", locs)
|
||||
text, err := c.DisassemblePC(api.EvalScope{GoroutineID: -1}, locs[0].PC, api.IntelFlavour)
|
||||
|
Loading…
Reference in New Issue
Block a user