如何解释堆栈跟踪中的负行号

huangapple go评论128阅读模式
英文:

How to interpret negative line number in stack trace

问题

panic: 运行时错误:无效的内存地址或空指针解引用
[信号 0xb 代码=0x1 地址=0x1 pc=0x80501f2]

goroutine 1 [运行中]:
server.init() // vv-------------RIGHT HERE
/home/.../debugComponent.go:-1218 +0x282
_/home/.../possessions.init()
/home/.../possessions.go:29 +0x42
_/home/.../pageWrap.init()
/home/.../pageWrap.go:112 +0x47

main.init()
/home/.../main.go:0 +0x3c

goroutine 2 [系统调用]:

goroutine 3 [可运行]:

附带的 debugComponent.go 文件目前并不重要,所以我将其删除以查看会发生什么,然后文件名会被替换为另一个文件名,并且会出现不同的负数。

在开发此应用程序时,我已经找到了很多错误,但是这个错误让我感到困惑。


如果有帮助的话,这里有 main.go,然后还有几个包在起作用。上面列出的三个文件都是不同的包,这似乎是在导入期间发生的。


希望你已经读到这里了,因为这是最奇怪的部分。如果我在 main.go 中添加这个声明,错误就会消失!

var test = func() int { return 1 }() // 现在一切都好了!

非常令人困惑!如果我做 var test = "foobar",它不会修复。它必须是被调用的 func


任何见解都会受到赞赏,但我最想知道的是追踪中的 -1218


更新

我正在尝试将此问题简化为一个能够重现问题的小示例。在处理完它后,我恢复了原始代码,并重新启动了机器。

第一次尝试构建和运行时,堆栈跟踪的顶部添加了两个新条目。但只有第一次。

goroutine 1 [系统调用]:
syscall.Syscall()
/usr/local/go/src/pkg/syscall/asm_linux_386.s:14 +0x5
syscall.Mkdir(0x83a2f18, 0x2, 0x2, 0x806255e, 0x83a2f1c, ...)
/usr/local/go/src/pkg/syscall/zerrors_linux_386.go:2225 +0x80
server.init()

所以这与我关于解释堆栈跟踪的主要问题一致。-1218 仍然存在,但现在还有这些。

asm_linux_386.s 在第 14 行有以下内容:

MOVL    4(SP), AX       // syscall entry

我也找到了 zerrors_linux_386.go,但是没有第 2225 行。该文件在那一行之前就停止了。

英文:

I made some changes to a fairly large project of mine today, and now I'm getting some odd behavior. Because I'm a knucklehead, I can't go back and figure out what I did.

But the main thrust of my question is how I should understand the negative line number in the stack trace that is printed. The -1218 below is the one that I mean.

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x1 pc=0x80501f2]

goroutine 1 [running]:
server.init()              //     vv-------------RIGHT HERE
    /home/.../debugComponent.go:-1218 +0x282
_/home/.../possessions.init()
    /home/.../possessions.go:29 +0x42
_/home/.../pageWrap.init()
    /home/.../pageWrap.go:112 +0x47

main.init()
    /home/.../main.go:0 +0x3c

goroutine 2 [syscall]:

goroutine 3 [runnable]:

The associated debugComponent.go file is pretty non-essential right now, so I removed it to see what would happen, and the file name just gets replaced with a different one, and a different negative number.

I've had to find plenty of bugs while developing this app, but this one has got me stumped.


If it helps, there's the main.go and then several packages in play. The three files listed above are all different packages, and this seems to be happening during the imports.


I hope you've read this far, because here's the strangest part. If I add this declaration to main.go, the error goes away!

var test = func() int { return 1 }() // Everything is fine now!

Very confusing! It doesn't fix it if I do var test = "foobar". It has to be the invoked func.


Any insight is appreciated, but mostly I'm curious about the -1218 in the trace.


Update

I'm trying to get this down to a small example that reproduces the issue. After working on it I reverted back to my original code, and restarted the machine.

The first time I tried to build and run, two new entries were added to the top of the stack trace. But only the first time.

goroutine 1 [syscall]:
syscall.Syscall()
	/usr/local/go/src/pkg/syscall/asm_linux_386.s:14 +0x5
syscall.Mkdir(0x83a2f18, 0x2, 0x2, 0x806255e, 0x83a2f1c, ...)
	/usr/local/go/src/pkg/syscall/zerrors_linux_386.go:2225 +0x80
server.init()

So this would be in line with my main question about interpreting stack trace. The -1218 is still there, but now there are these.

The asm_linux_386.s has this at line 14:

MOVL    4(SP), AX       // syscall entry

I found the zerrors_linux_386.go too, but there's no line 2225. The file stops long before that line.

答案1

得分: 2

已经报告并接受为问题5243

英文:

It's already reported and accepted as Issue 5243.

答案2

得分: 0

当程序开始执行时,它会初始化包变量并执行init函数。添加包变量会改变初始化过程。看起来在debugComponent.go中的初始化失败与server.init()有关。负的行号可能是一个错误。

没有源代码,很难说更多。

英文:

> Program execution
>
> A package with no imports is initialized by assigning initial values
> to all its package-level variables and then calling any package-level
> function with the name and signature of
>
> func init()
>
> defined in its source. A package-scope or file-scope identifier with
> name init may only be declared to be a function with this signature.
> Multiple such functions may be defined, even within a single source
> file; they execute in unspecified order.
>
> Within a package, package-level variables are initialized, and
> constant values are determined, according to order of reference: if
> the initializer of A depends on B, A will be set after B. Dependency
> analysis does not depend on the actual values of the items being
> initialized, only on their appearance in the source. A depends on B if
> the value of A contains a mention of B, contains a value whose
> initializer mentions B, or mentions a function that mentions B,
> recursively. It is an error if such dependencies form a cycle. If two
> items are not interdependent, they will be initialized in the order
> they appear in the source, possibly in multiple files, as presented to
> the compiler. Since the dependency analysis is done per package, it
> can produce unspecified results if A's initializer calls a function
> defined in another package that refers to B.
>
> An init function cannot be referred to from anywhere in a program. In
> particular, init cannot be called explicitly, nor can a pointer to
> init be assigned to a function variable.
>
> If a package has imports, the imported packages are initialized before
> initializing the package itself. If multiple packages import a package
> P, P will be initialized only once.
>
> The importing of packages, by construction, guarantees that there can
> be no cyclic dependencies in initialization.
>
> A complete program is created by linking a single, unimported package
> called the main package with all the packages it imports,
> transitively. The main package must have package name main and declare
> a function main that takes no arguments and returns no value.
>
> func main() { … }
>
> Program execution begins by initializing the main package and then
> invoking the function main. When the function main returns, the
> program exits. It does not wait for other (non-main) goroutines to
> complete.
>
> Package initialization—variable initialization and the invocation of
> init functions—happens in a single goroutine, sequentially, one
> package at a time. An init function may launch other goroutines, which
> can run concurrently with the initialization code. However,
> initialization always sequences the init functions: it will not start
> the next init until the previous one has returned.

As your program begins execution, it initializes package variables and executes init functions. Adding package variables is going to change the initialization. It looks like the initialization failed in debugComponent.go on something related to server.init(). The negative line number is probably a bug.

Without the source code, it's hard to say more.

huangapple
  • 本文由 发表于 2013年5月31日 09:09:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/16848303.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定