GOLANG空指针崩溃时堆栈消失和解决方案

原文:https://gocn.io/article/351

错误处理这个文章中,tkk提出了空指针时堆栈消失的问题,看下面的例子

package main

func main() {
    run() // line 4
}
func run() {
    causedPanic()
}
func causedPanic() {
    //defer func() {}() // line 10
    //panic("Panic from user") // line 11
    var p *byte
    *p = 0 // line 13
}

这个程序崩溃时,打印的竟然是:

panic: runtime error: invalid memory address or nil pointer dereference

goroutine 1 [running]:
main.main()
    /tmp/sandbox277759147/main.go:4 +0x4

神奇的是,把第10行的defer打开,变成这样

func causedPanic() {
    defer func() {}() // line 10
    //panic("Panic from user") // line 11
    var p *byte
    *p = 0 // line 13
}

堆栈神奇的回来了:

panic: runtime error: invalid memory address or nil pointer dereference

goroutine 1 [running]:
main.causedPanic()
    /tmp/sandbox416089181/main.go:13 +0x48
main.run()
    /tmp/sandbox416089181/main.go:7 +0x20
main.main()
    /tmp/sandbox416089181/main.go:4 +0x20

而主动调用panic堆栈也是没有问题的,可以把第10行注释掉,同时打开第11行。这个问题确实很诡异,在go-nuts中发了一篇文章问,strange stack trace when panic,马上就有神回复了:

On Wednesday, June 7, 2017 at 4:25:35 PM UTC+8, Dave Cheney wrote:

Try building your program with -gcflags="-l" to disable inlining. 
If that restores the stacktrace, then it's inlining. 
The good news is this should be fixed with Go 1.9

果然,运行时加上这个参数(编译时加上也是可以的),禁用内联编译后,堆栈就回来了:

go run -gcflags="-l" t.go

难怪了,主动调用panic时,内联编译不会把函数怼一坨去,如果没有defer和panic这种函数,就可能把函数怼一坨,看起来像是一个函数,堆栈消失了,这样在空指针时就找不到堆栈信息。

解决方案:

  1. 编译时加参数-gcflags="-l"
  2. 可能在GO1.9会解决这个问题。

结贴。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

winlinvip

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值