Go で Goroutine スタックトレースをダンプする
Jay Singh
2022年8月23日
奇妙な状況に対処するための慣用的なアプローチは、Go プログラムでエラーを使用することです。エラーは、ソフトウェアで発生する異常なケースの大部分を引き起こします。
ただし、まれに、異常な状態のためにソフトウェアを実行し続けることができない場合があります。この状況では、panic
がプログラムを早期に終了する可能性があります。
関数が panic
に遭遇すると、関数の実行は停止し、遅延した関数は実行され、制御は関数の呼び出し元に戻ります。
この手順は、現在のゴルーチンのすべての関数が戻るまで続きます。戻ると、プログラムは panic
メッセージを出力し、次にスタックトレースを出力してから終了します。
サンプルプログラムを作成すると、これがより明確になります。
Go で panic
を使用して Goroutine スタックトレースをダンプする
この簡単なスクリプトは、人のフルネームを出力します。fullName
関数は、個人の完全な名前を返します。
このメソッドは、firstName
および lastName
ポインターの nil
値をチェックします。nil
の場合、関数はメッセージとともに panic
シグナルを送信します。
プログラムが終了すると、このメッセージが出力されます。
package main
import (
"fmt"
)
func fullName(firstName *string, lastName *string) {
if firstName == nil {
panic("runtime error: first name cannot be nil")
}
if lastName == nil {
panic("runtime error: last name cannot be nil")
}
fmt.Printf("%s %s\n", *firstName, *lastName)
fmt.Println("returned normally from fullName")
}
func main() {
firstName := "Jay"
fullName(&firstName, nil)
fmt.Println("returned normally from main")
}
出力:
panic: runtime error: last name cannot be nil
goroutine 1 [running]:
main.fullName(0x405058?, 0xc000070f70?)
/tmp/sandbox885911142/prog.go:12 +0x114
main.main()
/tmp/sandbox885911142/prog.go:20 +0x35
次に、以下の例では、組み込みの len
によって提供される長さを使用してスライスの最後の要素にアクセスしようとする一般的な間違いを犯しています。
これが panic
を引き起こす理由を示すために、次のコードを実行します。
package main
import (
"fmt"
)
func main() {
names := []string{
"Iron Man",
"Thor",
}
fmt.Println("My favorite superhero is:", names[len(names)])
}
出力:
panic: runtime error: index out of range [2] with length 2
goroutine 1 [running]:
main.main()
/tmp/sandbox2746930010/prog.go:12 +0x1b