LoginSignup
5
5

More than 5 years have passed since last update.

GOTRACEBACKのメモ

Posted at

182b65b9 539c 4d24 9b1f ee4a1a8756f1

GOTRACEBACKという環境変数があり、それを設定することによって、go runしたときのプログラムのトレースバックが変わるようです。

The GOTRACEBACK variable controls the amount of output generated when a Go program fails due to an unrecovered panic or an unexpected runtime condition. By default, a failure prints a stack trace for every extant goroutine, eliding functions internal to the run-time system, and then exits with exit code 2. If GOTRACEBACK=0, the per-goroutine stack traces are omitted entirely. If GOTRACEBACK=1, the default behavior is used. If GOTRACEBACK=2, the per-goroutine stack traces include run-time functions. If GOTRACEBACK=crash, the per-goroutine stack traces include run-time functions, and if possible the program crashes in an operating-specific manner instead of exiting. For example, on Unix systems, the program raises SIGABRT to trigger a core dump.

Google先生で翻訳したところ、

GOTRACEBACK = 0は、単位のゴルーチンスタックトレースが完全に省略している場合は終了コード2で終了します。

GOTRACEBACK = 1の場合、デフォルトの動作が使用されます。

GOTRACEBACK = 2場合は、単位のゴルーチンスタックトレースは、実行時の機能が含まれます。

以下のサンプルコードで試してみました。


package main


import (
        "log"
        "runtime"
)

func main(){
        log.Println(runtime.NumGoroutine()) //動いているゴルーチンの数
        select{}
}

GOTRACEBACK=0


[root@localhost vagrant]# GOTRACEBACK=0 go run sample.go
2015/02/12 13:39:00 4
fatal error: all goroutines are asleep - deadlock!
exit status 2

終了ステータスコードとエラーメッセージが出力されます。

GOTRACEBACK=1


[root@localhost vagrant]# GOTRACEBACK=1 go run sample.go
2015/02/12 13:40:02 4
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [select (no cases)]:
main.main()
    /vagrant/sample.go:11 +0xd5
exit status 2

終了ステータスコードとどの行でエラーになったか出力されます。

GOTRACEBACK=2


[root@localhost vagrant]# GOTRACEBACK=2 go run sample.go
2015/02/12 13:40:17 4
fatal error: all goroutines are asleep - deadlock!

runtime stack:
runtime.throw(0x54f7e3)
    /usr/local/go/src/runtime/panic.go:491 +0xad fp=0x7fff416d3b58 sp=0x7fff416d3b28
checkdead()
    /usr/local/go/src/runtime/proc.c:2854 +0x1f8 fp=0x7fff416d3ba8 sp=0x7fff416d3b58
mput(0x551e40)
    /usr/local/go/src/runtime/proc.c:3175 +0x47 fp=0x7fff416d3bb0 sp=0x7fff416d3ba8
stopm()
    /usr/local/go/src/runtime/proc.c:1176 +0xea fp=0x7fff416d3bd0 sp=0x7fff416d3bb0
findrunnable(0xc208012000)
    /usr/local/go/src/runtime/proc.c:1487 +0x562 fp=0x7fff416d3c08 sp=0x7fff416d3bd0
schedule()
    /usr/local/go/src/runtime/proc.c:1575 +0x151 fp=0x7fff416d3c38 sp=0x7fff416d3c08
runtime.park_m(0xc2080006c0)
    /usr/local/go/src/runtime/proc.c:1654 +0x113 fp=0x7fff416d3c60 sp=0x7fff416d3c38
runtime.mcall(0x42d204)
    /usr/local/go/src/runtime/asm_amd64.s:186 +0x5a fp=0x7fff416d3c70 sp=0x7fff416d3c60

goroutine 1 [select (no cases)]:
runtime.gopark(0x0, 0x0, 0x4ef830, 0x11)
    /usr/local/go/src/runtime/proc.go:130 +0x105 fp=0xc20802df08 sp=0xc20802ded8
runtime.block()
    /usr/local/go/src/runtime/select.go:176 +0x46 fp=0xc20802df30 sp=0xc20802df08
main.main()
    /vagrant/sample.go:11 +0xd5 fp=0xc20802df98 sp=0xc20802df30
runtime.main()
    /usr/local/go/src/runtime/proc.go:63 +0xf3 fp=0xc20802dfe0 sp=0xc20802df98
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:2232 +0x1 fp=0xc20802dfe8 sp=0xc20802dfe0

goroutine 2 [force gc (idle)]:
runtime.gopark(0x42edb0, 0x5516e0, 0x4e49d0, 0xf)
    /usr/local/go/src/runtime/proc.go:130 +0x105 fp=0xc20801a798 sp=0xc20801a768
runtime.goparkunlock(0x5516e0, 0x4e49d0, 0xf)
    /usr/local/go/src/runtime/proc.go:136 +0x48 fp=0xc20801a7c0 sp=0xc20801a798
runtime.forcegchelper()
    /usr/local/go/src/runtime/proc.go:99 +0xce fp=0xc20801a7e0 sp=0xc20801a7c0
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:2232 +0x1 fp=0xc20801a7e8 sp=0xc20801a7e0
created by runtime.init·4
    /usr/local/go/src/runtime/proc.go:87 +0x25

goroutine 3 [GC sweep wait]:
runtime.gopark(0x42edb0, 0x558978, 0x4e21f0, 0xd)
    /usr/local/go/src/runtime/proc.go:130 +0x105 fp=0xc20801df98 sp=0xc20801df68
runtime.goparkunlock(0x558978, 0x4e21f0, 0xd)
    /usr/local/go/src/runtime/proc.go:136 +0x48 fp=0xc20801dfc0 sp=0xc20801df98
runtime.bgsweep()
    /usr/local/go/src/runtime/mgc0.go:98 +0xbc fp=0xc20801dfe0 sp=0xc20801dfc0
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:2232 +0x1 fp=0xc20801dfe8 sp=0xc20801dfe0
created by gc
    /usr/local/go/src/runtime/mgc0.c:1383

goroutine 4 [finalizer wait]:
runtime.gopark(0x42edb0, 0x558970, 0x4e4550, 0xe)
    /usr/local/go/src/runtime/proc.go:130 +0x105 fp=0xc208019730 sp=0xc208019700
runtime.goparkunlock(0x558970, 0x4e4550, 0xe)
    /usr/local/go/src/runtime/proc.go:136 +0x48 fp=0xc208019758 sp=0xc208019730
runtime.runfinq()
    /usr/local/go/src/runtime/malloc.go:727 +0xba fp=0xc2080197e0 sp=0xc208019758
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:2232 +0x1 fp=0xc2080197e8 sp=0xc2080197e0
created by runtime.createfing
    /usr/local/go/src/runtime/malloc.go:707 +0x5e
exit status 2

長いです。終了ステータスコードと他に動いてるゴルーチンが出力されます。

こう思った

GOTRACEBACK=2で他のゴルーチンがわかるのは便利かも。
なぜall goroutines are asleep - deadlock!となるのかは謎。。。

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5