中国能源建设集团招聘网站c 网站开发 视频教程
中国能源建设集团招聘网站,c 网站开发 视频教程,wordpress秀恩爱主题,重庆阳光投诉平台2019独角兽企业重金招聘Python工程师标准 背景是在写个日志库#xff0c;日志库有个很重要的功能就是要打印出调用栈#xff0c;知道具体是哪个文件#xff0c;哪个函数调用的Info 等。 然后在测试中发现了一种写法#xff0c;我自己本机测试一直ok#xff… 2019独角兽企业重金招聘Python工程师标准 背景是在写个日志库日志库有个很重要的功能就是要打印出调用栈知道具体是哪个文件哪个函数调用的Info 等。 然后在测试中发现了一种写法我自己本机测试一直ok 但是业务使用的时候调用栈始终不对打的调用栈少了一层。莫名其妙的后来对比发现我们就是go version 不一样。 go version : go version go1.9.2 darwin/amd64 go env: GOARCHamd64
GOBIN
GOEXE
GOHOSTARCHamd64
GOHOSTOSdarwin
GOOSdarwin
GOPATH/Users/didi/Desktop/didi
GORACE
GOROOT/usr/local/go1.9.2
GOTOOLDIR/usr/local/go1.9.2/pkg/tool/darwin_amd64
GCCGOgccgo
CCclang
GOGCCFLAGS-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length0 -fdebug-prefix-map/var/folders/2w/tt1p_4td3yq9xlbl7c2t4jn00000gn/T/go-build427754844/tmp/go-build -gno-record-gcc-switches -fno-common
CXXclang
CGO_ENABLED1
CGO_CFLAGS-g -O2
CGO_CPPFLAGS
CGO_CXXFLAGS-g -O2
CGO_FFLAGS-g -O2
CGO_LDFLAGS-g -O2
PKG_CONFIGpkg-config 我的示例代码是这样的 package mainimport (fmtruntime
)var i []bytetype AAA struct {
}func (a *AAA) test1() *AAA {buf : make([]byte, 120)runtime.Stack(buf, true)fmt.Printf(\n%s, buf)return a
}func (a *AAA) test2() *AAA {i append(i, test2...)return a
}func test() {a : AAA{}a.test1().test2()
}func main() {test()
}然后呢我期望的结果 goroutine 1 [running]:
main.(*AAA).test1(0xc420045f60, 0x1003a4c)/Users/didi/Desktop/didi/src/test/testCall/main.go:15 0x87
main.test()/Users/didi/Desktop/didi/src/test/testCall/main.go:27 0x2f
main.main()/Users/didi/Desktop/didi/src/test/testCall/main.go:31 0x20 但是真实结果是这样的 goroutine 1 [running]:
main.(*AAA).test1(0xc42003df48, 0xc42003df70)/Users/didi/Desktop/didi/src/test/testCall/main.go:15 0x87
main.(*AAA).test2(...)/Users/didi/Desktop/didi/src/test/testCall/main.go:27
main.test()/Users/didi/Desktop/didi/src/test/testCall/main.go:27 0x2f
main.main()/Users/didi/Desktop/didi/src/test/testCall/main.go:31 0x20 问题来了我日志库封装要是有这种类似逻辑那打印的日志全都是有问题的怎么可能是test2调用test1 莫名其妙的。。。 初步怀疑是内联引起的问题这里现象看着很像。编译加上不允许内联后问题解决, 解决方式蛮简单的函数前加个 // go:noinline。 为什么会出现这种让人困惑的现象通过查看go 官方issue 和 release note 发现下面解释 Users of runtime.Callers should avoid directly inspecting the resulting PC slice and instead use runtime.CallersFrames to get a complete view of the call stack, or runtime.Caller to get information about a single caller. This is because an individual element of the PC slice cannot account for inlined frames or other nuances of the call stack.
// 使用runtime.Caller 不能显示内联的细微区别。Specifically, code that directly iterates over the PC slice and uses functions such as runtime.FuncForPC to resolve each PC individually will miss inlined frames. To get a complete view of the stack, such code should instead use CallersFrames. Likewise, code should not assume that the length returned by Callers is any indication of the call depth. It should instead count the number of frames returned by CallersFrames.Code that queries a single caller at a specific depth should use Caller rather than passing a slice of length 1 to Callers.runtime.CallersFrames has been available since Go 1.7, so code can be updated prior to upgrading to Go 1.9. 然后官方有人提了这个issue https://github.com/golang/go/issues/22916。总结就是官方在1.9 的时候觉得1.8及以前版本的不对Caller 应该将内联栈也算进去。然后后来大家觉得这种使用不符合习惯在1.10 又改回去了。我个人试了下1.10.x, 1.11.x 都是正常的。 这种问题大多数人应该遇不上一个是要求链式调用的写法第二个得关心调用栈才会遇到这种奇怪现象。 转载于:https://my.oschina.net/u/2950272/blog/2995702
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/88104.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!