Example #1
0
// 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
	}
}
Example #2
0
File: main.go Project: Xslxy/e8vm
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)")
		}
	}
}
Example #3
0
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)
}