func PrintStack(fr *interp.Frame, count int) { if fr == nil { return } for i := 0; fr != nil && i < count; fr = fr.Caller(0) { pointer := " " if fr == curFrame { pointer = "=> " } Msg("%s#%d %s", pointer, i, fr.FnAndParamString()) Msg("\t%s", fr.PositionRange()) i++ } }
func printLocInfo(fr *interp.Frame, inst *ssa2.Instruction, event ssa2.TraceEvent) { defer func() { if x := recover(); x != nil { Errmsg("Internal error in getting location info") debug.PrintStack() } }() s := Event2Icon[event] + " " fn := fr.Fn() sig := fn.Signature name := fn.Name() if fn.Signature.Recv() != nil { if len(fn.Params) == 0 { panic("Receiver method " + name + " should have at least 1 param. Has 0.") } s += fmt.Sprintf("(%s).%s()", fn.Params[0].Type(), name) } else { s += fmt.Sprintf("%s.%s", fn.Pkg.Object.Path(), name) if len(name) > 0 { s += "()" } } if *terse && (event != ssa2.STEP_INSTRUCTION) { Msg(s) } else { Msg("%s block %d insn %d", s, fr.Block().Index, fr.PC()) } var syntax ast.Node = nil switch event { case ssa2.CALL_RETURN: if sig.Results() == nil { Msg("return void") } else { Msg("return type: %s", sig.Results()) Msg("return value: %s", Deref2Str(fr.Result(), nil)) } case ssa2.CALL_ENTER: syntax = fn.Syntax() for _, p := range fn.Params { if val := fr.Env()[p]; val != nil { ssaVal := ssa2.Value(p) Msg("%s %s", p, Deref2Str(val, &ssaVal)) } else { Msg("%s nil", p) } } case ssa2.PANIC: // fmt.Printf("panic arg: %s\n", fr.Get(instr.X)) } Msg(fr.PositionRange()) if Instr != nil { switch s := (*Instr).(type) { case *ssa2.Trace: syntax = s.Syntax() } if syntax != nil { PrintSyntaxFirstLine(syntax, fn.Prog.Fset) } } }