いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-552 (パニック時の出力をヒューマンフレンドリーにしてくれるライブラリ)(maruel/panicparse)

関連記事

GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ

概要

以下、自分用のメモです。

パニック時のスタックトレースの出力を見やすくしてくれるライブラリを知ったので、メモメモ。。。

github.com

以下の記事を読んでいたときに、このライブラリの存在を知りました。感謝。

michael.stapelberg.ch

試してみた

main.go

2秒したらパニックするプログラムを用意。

/*
maruel/panicparse の動作確認用のプログラム

2秒するとパニックします。
*/
package main

import (
    "fmt"
    "sync"
    "time"
)

func main() {
    if err := run(); err != nil {
        panic(err)
    }
}

func run() error {
    ch := make(chan int)
    wg := sync.WaitGroup{}

    wg.Add(3)

    go func(ch chan<- int) {
        defer wg.Done()
        for i := range 100 {
            ch <- i
            time.Sleep(500 * time.Millisecond)
        }
    }(ch)
    go func(ch <-chan int) {
        defer wg.Done()
        for i := range ch {
            fmt.Println(i)
        }
    }(ch)
    go func(ch chan<- int) {
        defer wg.Done()
        defer close(ch)
        time.Sleep(2 * time.Second)
    }(ch)

    wg.Wait()

    return nil
}

Taskfile.yml

# https://taskfile.dev

version: '3'

tasks:
  default:
    cmds:
      - task: clean
      - task: build
      - task: run
  build:
    cmds:
      - go build -o app main.go
  run:
    cmds:
      - cmd: ./app
        ignore_error: true
      - cmd: ./app |& pp
        ignore_error: true
    env:
      GOTRACEBACK: all
  clean:
    cmds:
      - rm -f ./app

shell

実行すると以下のように出力されます。最初の実行はデフォルトの出力で、2回目の実行が panicparse をパイプで繋いで出力してもらってるものです。

$ task
task: [clean] rm -f ./app
task: [build] go build -o app main.go
task: [run] ./app
0
1
2
3
panic: send on closed channel

goroutine 6 [running]:
main.run.func1(0xc000096070)
        /workspace/try-golang-extlib/examples/singleapp/panicparse/main.go:29 +0x5f
created by main.run in goroutine 1
        /workspace/try-golang-extlib/examples/singleapp/panicparse/main.go:26 +0xd1

goroutine 1 [runnable]:
sync.runtime_SemacquireWaitGroup(0xc00000e0f0?)
        /home/gitpod/go/src/runtime/sema.go:110 +0x25
sync.(*WaitGroup).Wait(0x0?)
        /home/gitpod/go/src/sync/waitgroup.go:118 +0x48
main.run()
        /workspace/try-golang-extlib/examples/singleapp/panicparse/main.go:45 +0x1f1
main.main()
        /workspace/try-golang-extlib/examples/singleapp/panicparse/main.go:15 +0x13

task: [run] ./app |& pp
0
1
2
3
panic: send on closed channel

1: running [Created by main.run in goroutine 1 @ main.go:26]
    main main.go:29       run.func1(0xc000096070)
1: runnable
    sync sema.go:110      runtime_SemacquireWaitGroup(*uint32(#1))
    sync waitgroup.go:118 (*WaitGroup).Wait(*WaitGroup(0x0))
    main main.go:45       run()
    main main.go:15       main()

とても見やすい。

参考情報

github.com

Goのおすすめ書籍


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。