この方法だと、panic が起らない場合もゼロバイトのファイルが作成されてしまう。
panic が起きてから、"runtime/debug".Stack()
で、スタックトレースを得るという方法もある。 この方法は Go 1.20 でも使えるというメリットもある。
nyagos で使用している関数を抜粋する。
import ( "bytes" "fmt" "io" "os" "runtime/debug" ) func main() { defer PanicHandler() // 以下略 } func PanicHandler() { err := recover() if err == nil { return } var dump bytes.Buffer w := io.MultiWriter(os.Stderr, &dump) fmt.Fprintln(w, "************ Panic Occurred. ***********") fmt.Fprintln(w, "** err **") fmt.Fprintln(w, err) fmt.Fprintln(w, "** debug.Stack **") w.Write(debug.Stack()) fmt.Fprintln(w, "*** Please copy these error message ***") fmt.Fprintln(w, "*** And hit ENTER key to quit. ***") os.WriteFile("nyagos.dump", dump.Bytes(), 0666) var dummy [1]byte os.Stdin.Read(dummy[:]) }
わざと panic を起こすと次のような内容のファイル: nyagos.dump が作成される
************ Panic Occurred. *********** ** err ** panic test ** debug.Stack ** goroutine 1 [running]: runtime/debug.Stack() C:/Users/hymko/sdk/go1.20.14/src/runtime/debug/stack.go:24 +0x65 github.com/nyaosorg/nyagos/internal/frame.PanicHandler() C:/Users/hymko/src/nyagos/internal/frame/main.go:67 +0x3ef panic({0x7bcce0, 0x8a0f30}) C:/Users/hymko/sdk/go1.20.14/src/runtime/panic.go:884 +0x213 github.com/nyaosorg/nyagos/internal/commands.cmdPanic({0xc002506390, 0xc002506a00}, {0xc0002f6390, 0x2}) C:/Users/hymko/src/nyagos/internal/commands/table_windows.go:77 +0x27 github.com/nyaosorg/nyagos/internal/commands.Exec({0x8a3cb8, 0xc00017b0e0}, {0x8a5fa0, 0xc0003240f0}) C:/Users/hymko/src/nyagos/internal/commands/commands.go:71 +0x18c github.com/nyaosorg/nyagos/internal/frame.Setup.func1({0x8a3cb8?, 0xc00017b0e0?}, 0xc0002f6390?) C:/Users/hymko/src/nyagos/internal/frame/main.go:33 +0x2d github.com/nyaosorg/nyagos/internal/alias.hook({0x8a3cb8, 0xc00017b0e0}, 0xc0003240f0) C:/Users/hymko/src/nyagos/internal/alias/alias.go:58 +0x16b github.com/nyaosorg/nyagos/internal/shell.New.func1({0x8a3cb8?, 0xc00017b0e0?}, 0x674ee0?) C:/Users/hymko/src/nyagos/internal/shell/interpreter.go:206 +0x2f github.com/nyaosorg/nyagos/internal/shell.(*Cmd).spawnvpSilent(0xc0003240f0, {0x8a3cb8, 0xc00017b0e0}) C:/Users/hymko/src/nyagos/internal/shell/interpreter.go:340 +0x2d8 github.com/nyaosorg/nyagos/internal/shell.(*Cmd).Spawnvp(0xc0003240f0, {0x8a3c10, 0xc00031e280}) C:/Users/hymko/src/nyagos/internal/shell/interpreter.go:443 +0xec github.com/nyaosorg/nyagos/internal/shell.(*Shell).Interpret(0xc000027e00, {0x8a3c10, 0xc00031e280}, {0xc0002f6350?, 0xc000075be8?}) C:/Users/hymko/src/nyagos/internal/shell/interpreter.go:595 +0xabe github.com/nyaosorg/nyagos/internal/shell.(*Shell).Loop(0xc000027e00, {0x8a3cb8, 0xc00038e780}, {0x8a2d10?, 0xc000008960?}) C:/Users/hymko/src/nyagos/internal/shell/loop.go:131 +0x2ae github.com/nyaosorg/nyagos/internal/shell.(*Shell).ForEver(...) C:/Users/hymko/src/nyagos/internal/shell/loop.go:157 github.com/nyaosorg/nyagos/internal/mains.Run({0x8a1d20, 0xad4308}) C:/Users/hymko/src/nyagos/internal/mains/nyagos.go:209 +0xb7b main.run() C:/Users/hymko/src/nyagos/main.go:27 +0x71 main.main() C:/Users/hymko/src/nyagos/main.go:31 +0x1d *** Please copy these error message *** *** And hit ENTER key to quit. ***