// FprintStack prints the stack trace of a machine from its exception // and registers. func FprintStack(w io.Writer, m *Machine, excep *CoreExcep) error { sec := debugSection(m.Sections) if sec == nil { return errors.New("debug section not found") } t, err := debug8.UnmarshalTable(sec.Bytes) if err != nil { return err } funcs := sortTable(t) core := byte(excep.Core) regs := m.DumpRegs(core) pc := regs[PC] sp := regs[SP] ret := regs[RET] level := 0 for { level++ name, f := findFunc(funcs, pc, t) if f == nil { if level == 1 { _, err := fmt.Fprintf(w, "? pc=%08x\n", pc) return err } return nil } _, err := fmt.Fprintln(w, f.String(name)) if err != nil { return err } if f.Size <= 4 || f.Frame == 0 { // cannot be a normal function if level != 1 { // calling in a non-normal function return nil } // use ret as pc pc = ret continue } retAddr, err := m.ReadWord(core, sp+f.Frame-4) if err != nil { _, err := fmt.Fprintf(w, "! unable to recover: %s\n", err) return err } pc = retAddr sp = sp + f.Frame } }
func main() { flag.Parse() args := flag.Args() if len(args) != 1 { log.Fatal("need exactly one input file\n") } fname := args[0] if *doDasm { f, err := os.Open(fname) defer f.Close() err = dasm8.DumpImage(f, os.Stdout) if err != nil { log.Fatal(err) } } else if *printDebug { f, err := os.Open(fname) defer f.Close() secs, err := e8.Read(f) if err != nil { log.Fatal(err) } for _, sec := range secs { if sec.Type != e8.Debug { continue } tab, err := debug8.UnmarshalTable(sec.Bytes) if err != nil { log.Fatal(err) } tab.PrintTo(os.Stdout) } } else { bs, err := ioutil.ReadFile(fname) if err != nil { log.Fatal(err) } n, e := run(bs) fmt.Printf("(%d cycles)\n", n) if e != nil { if !arch8.IsHalt(e) { fmt.Println(e) } } else { fmt.Println("(end of time)") } } }
func printStackTrace(m *arch8.Machine, exp error, sec *e8.Section) { if sec == nil { return } coreExp, ok := exp.(*arch8.CoreExcep) if !ok { return } tab, err := debug8.UnmarshalTable(sec.Bytes) if err != nil { log.Println(err) return } debug8.FprintStack(os.Stdout, m, byte(coreExp.Core), tab) }