恐慌堆栈跟踪中的未知字段 [英] Unknown field in panic stack trace

查看:124
本文介绍了恐慌堆栈跟踪中的未知字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  package main $ b $在试图学习如何从恐慌中调试堆栈跟踪时,我遇到了一些困惑。 b 
func F(a int){
panic(nil)
}

func main(){
F(1)
}

在附加的播放链接上运行时输出以下内容:

  panic:nil 

goroutine 1 [running]:
main.F(0x1,0x10436000)
/tmp/sandbox090887108/main.go:4 + 0×20
main.main()
/tmp/sandbox090887108/main.go:8 + 0×20

我无法破译第二个数字的含义(main.F(0x1,0x10436000)中的0x10436000)。它不会出现,如果有第二个int参数,或者如果有其他东西作为第一个参数传入(可以在第二个播放链接中看到)。



一个arg: https://play.golang.org/p/3iV48xlNFR



两个ARGS: https://play.golang.org/p/4jA7ueI86K

解决方案

打印在堆栈跟踪中的数据是参数,但值不直接对应于传入的参数,它是以指针大小的值打印的原始数据(尽管通常与原始字大小相同)。这个游乐场有点独特,它是一个带有32位指针的64位字体系结构( GOARCH = amd64p32 )。

traceback.go 你可以看到,通过基于指针大小的参数逐步打印值;

  for i:= uintptr(0);我< frame.arglen / sys.PtrSize; i ++ {

因为字大小是操场上指针大小的两倍,所以始终在帧参数中打印偶数个值。

数据如何呈现的另一个例子可以通过在函数参数中使用更小的类型在操场中看到: https://play.golang.org/p/vHZDEHQZLh

 < code $ func F(a uint8){
panic(nil)
}

// F(1)
// main.F(0x97301 ,0x10436000)

只使用64位字的前8位,即 0x97301& 0x0f ,或简单地 1 。来自第一个值和整个 0x10436000 的额外 0x97300 仅仅是第一个64位字的剩余部分,功能。

通过使用更多参数,您可以在 amd64 系统上看到相同的行为。这个签名例如;

  func F(a,b,c uint32)

当通过 F(1,1,1)调用时,它会打印一个堆栈跟踪:

  main.F(0x100000001,0xc400000001)

,因为3个32位值需要2个字

最后一组要注意的值是返回值,它们也被分配在堆栈上。以下函数签名:

  func F(a int64)(int,int)
amd64上的 $ b>

会显示堆栈框架参数:

  main.F(0xa,0x1054d60,0xc420078058)

$ c> a ,还有两个用于(int,int)返回值。然而,返回值并没有被初始化,所以除了理解为什么这些值在那里,我在这里获得的并不多。

In trying to learn how to debug stack traces from panics, I came across something confusing.

package main

func F(a int) {
    panic(nil)
}

func main() {
    F(1)
}

outputs the following when I run it on the attached play link:

panic: nil

goroutine 1 [running]:
main.F(0x1, 0x10436000)
    /tmp/sandbox090887108/main.go:4 +0x20
main.main()
    /tmp/sandbox090887108/main.go:8 +0x20

I can't decipher what the second number means (the 0x10436000 in main.F(0x1, 0x10436000)). It doesn't appear if there's a second int argument, or if anything else if passed in as the first argument (can be seen in the second play link).

One arg: https://play.golang.org/p/3iV48xlNFR

Two args: https://play.golang.org/p/4jA7ueI86K

解决方案

The data printed in the stack trace is the arguments, but the values don't correspond directly to the arguments passed in, it's the raw data printed in pointer-sized values (though usually this is the same as the native word size). The playground is slightly unique, in that it's a 64bit word architecture with 32bit pointers(GOARCH=amd64p32).

In traceback.go you can see that the values are printed by stepping through the arguments based on pointer size;

for i := uintptr(0); i < frame.arglen/sys.PtrSize; i++ {

So because the word size is twice as big as the pointer size in the playground, you will always have an even number of values printed in the frame arguments.

Another example of how the data is presented can be seen in the playground by using smaller types in the function arguments: https://play.golang.org/p/vHZDEHQZLh

func F(a uint8) {
    panic(nil)
}

// F(1)
// main.F(0x97301, 0x10436000)

Only the first 8 bits of the 64bit word are used, which is 0x97301 & 0x0f, or simply 1. The extra 0x97300 from the first value and the entire 0x10436000 are just the remainder of that first 64bit word which is unused by the function.

You can see the same behavior on amd64 systems by using more arguments. This signature for example;

func F(a, b, c uint32)

when called via F(1, 1, 1), it will print a stack trace like:

main.F(0x100000001, 0xc400000001)

because the 3 32bit values take 2 words

The final set of values to note are return values, which are also allocated on the stack. The following function signature:

func F(a int64) (int, int)

on amd64, would show the stack frame arguments like:

main.F(0xa, 0x1054d60, 0xc420078058)

With one word for a, and two more for the (int, int) return values. The return values are not initialized however, so there's not much to me gained here other than to understand why these values are there.

这篇关于恐慌堆栈跟踪中的未知字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆