Go的调试信息


当golang程序出现panic的时候会输出一段堆栈调试信息,开发人员可以通过这些调试信息快速地定位问题。

1. 举个栗子

我们通过下面这段程序,直接让程序panic

package main

func main() {
    slice := make([]string, 2, 4)
    Example(slice, "hello", 10)
}

func Example(slice []string, str string, i int) {
    panic("stack trace")
}

运行后输出的调试信息如下

panic: stack trace

goroutine 1 [running]:
main.Example(0xc42003ff30, 0x2, 0x4, 0x106b75a, 0x5, 0xa)
    /Users/maniafish/Myworkspace/go_project/src/test/test_panic.go:9 +0x39
main.main()
    /Users/maniafish/Myworkspace/go_project/src/test/test_panic.go:5 +0x76
exit status 2
  • 第一行是panic信息: stack trace
  • 第二行是发生panic的goroutine及其运行状态(running)
  • 接下来就是发生panic的function调用情况了。我们通常会关注显示的文件和行号,可以快速定位到是哪一行代码抛出的异常
  • 除此之外我们还可以从中看到发生panic的function的输入参数,如main.Example(0xc42003ff30, 0x2, 0x4, 0x106b75a, 0x5, 0xa)对应func Example(slice []string, str string, i int)的三个输入参数:

    • slice: 0xc42003ff30(slice指针地址), 0x2(slice的长度), 0x4(slice的容量)
    • str: 0x106b75a(str字符串头指针地址), 0x5(str字符串长度)
    • i: 0xa(i = 10)

2. 空指针错误

package main

import "fmt"

type S struct {
    Msg string
}

func (s *S) f(a int) {
    fmt.Printf("%v: %d\n", s.Msg, a)
}

func main() {
    Example(nil)
}

func Example(s *S) {
    s.f(1)
}

以上这段程序运行结果如下:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x1095257]

goroutine 1 [running]:
main.(*S).f(0x0, 0x1)
    /Users/maniafish/Myworkspace/go_project/src/test/test_panic.go:10 +0x57
main.Example(0x0)
    /Users/maniafish/Myworkspace/go_project/src/test/test_panic.go:18 +0x34
main.main()
    /Users/maniafish/Myworkspace/go_project/src/test/test_panic.go:14 +0x2a
exit status 2
  1. panic信息(invalid memory address or nil pointer dereference)告诉我们是无效的地址调用
  2. 我们通过main.(*S).f(0x0, 0x1)的第一个参数,可以知道这个指针*S的方法f()调用时使用的是空指针
  3. 然后通过main.Example(0x0),知道这个空指针是通过Example()方法传进来的,定位到了问题所在。

参考链接:

results matching ""

    No results matching ""