github.com/icexin/eggos@v0.4.2-0.20220216025428-78b167e4f349/kernel/panic.go (about)

     1  package kernel
     2  
     3  import (
     4  	"unsafe"
     5  
     6  	"github.com/icexin/eggos/drivers/qemu"
     7  	"github.com/icexin/eggos/drivers/uart"
     8  	"github.com/icexin/eggos/kernel/sys"
     9  	"github.com/icexin/eggos/log"
    10  )
    11  
    12  var (
    13  	panicPcs [32]uintptr
    14  )
    15  
    16  //go:nosplit
    17  func throw(msg string) {
    18  	sys.Cli()
    19  	tf := Mythread().tf
    20  	throwtf(tf, msg)
    21  }
    22  
    23  //go:nosplit
    24  func throwtf(tf *trapFrame, msg string) {
    25  	sys.Cli()
    26  	n := callers(tf, panicPcs[:])
    27  	uart.WriteString(msg)
    28  	uart.WriteByte('\n')
    29  
    30  	log.PrintStr("0x")
    31  	log.PrintHex(tf.IP)
    32  	log.PrintStr("\n")
    33  	for i := 0; i < n; i++ {
    34  		log.PrintStr("0x")
    35  		log.PrintHex(panicPcs[i])
    36  		log.PrintStr("\n")
    37  	}
    38  
    39  	qemu.Exit(0xff)
    40  	for {
    41  	}
    42  }
    43  
    44  //go:nosplit
    45  func callers(tf *trapFrame, pcs []uintptr) int {
    46  	fp := tf.BP
    47  	var i int
    48  	for i = 0; i < len(pcs); i++ {
    49  		pc := deref(fp + 8)
    50  		pcs[i] = pc
    51  		fp = deref(fp)
    52  		if fp == 0 {
    53  			break
    54  		}
    55  	}
    56  	return i
    57  }
    58  
    59  //go:nosplit
    60  func deref(addr uintptr) uintptr {
    61  	return *(*uintptr)(unsafe.Pointer(addr))
    62  }