“构建Go项目时出现“nosplit堆栈溢出”错误?”

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

"nosplit stack overflow" when building Go project?

问题

我通过将代码拆分为更多的Go包来进行了一次春季清理,主要是为了提高可重用性(每个“构建块”都在自己的包中)。

在修复导入错误后,我发现我的程序突然无法构建。运行“go build”会返回一个nosplit stack overflow错误。

># robot main.init: nosplit stack overflow
> 120 在main.init中的分割检查后保证
> 112 进入robot/web.init时
> 104 进入robot/controller.init时
> 96 进入robot/slam.init时
> 88 进入robot/slam/hector.init时
> 80 进入hectormapping/map/mapimages.init时
> 72 进入hectormapping/map/maprep.init时
> 64 进入hectormapping/map/mapproccontainer.init时
> 56 进入hectormapping/scanmatcher.init时
> 48 进入hectormapping/map/gridmap/occbase.init时
> 40 进入hectormapping/map/gridmap/base.init时
> 32 进入hectormapping/map/gridmap.init时
> 24 进入github.com/skelterjohn/go%2ematrix.init时
> 16 进入math.init时
> 8 进入math.init┬À1时
> 0 进入runtime.panicindex时
> -8 进入runtime.morestack00时
> # runtime.main: nosplit stack overflow
> 120 在runtime.main中的分割检查后保证
> 128 在runtime.main使用-8后
> 120 进入main.init时
> 112 进入robot/web.init时
> 104 进入robot/controller.init时
> 96 进入robot/slam.init时
> 88 进入robot/slam/hector.init时
> 80 进入hectormapping/map/mapimages.init时
> 72 进入hectormapping/map/maprep.init时
> 64 进入hectormapping/map/mapproccontainer.init时
> 56 进入hectormapping/scanmatcher.init时
> 48 进入hectormapping/map/gridmap/occbase.init时
> 40 进入hectormapping/map/gridmap/base.init时
> 32 进入hectormapping/map/gridmap.init时
> 24 进入github.com/skelterjohn/go%2ematrix.init时
> 16 进入math.init时
> 8 进入math.init┬À1时
> 0 进入runtime.panicindex时
> -8 进入runtime.morestack00时

有人知道这是怎么回事吗?我找不到太多关于可能引起这个问题的文档,除了某些情况下这是一个据说已经修复的错误

一些代码被拆分到“src”文件夹中的一个新文件夹中,所以现在的文件结构是:

src/robot/main.go(main()在这里)
src/robot/(...)(应用程序特定的包)
src/hectormapping/(...)(在“robot”中使用的独立包)

我在Windows 7(x64)上使用Go 1.0.3。

英文:

I did a spring cleaning in my code by splitting it up in more Go packages, mainly to help reusability (each "building block" in its own package).

After fixing the import errors, I discovered that my program suddenly won't build. Running "go build" returns a nosplit stack overflow error.

># robot main.init: nosplit stack overflow
> 120 guaranteed after split check in main.init
> 112 on entry to robot/web.init
> 104 on entry to robot/controller.init
> 96 on entry to robot/slam.init
> 88 on entry to robot/slam/hector.init
> 80 on entry to hectormapping/map/mapimages.init
> 72 on entry to hectormapping/map/maprep.init
> 64 on entry to hectormapping/map/mapproccontainer.init
> 56 on entry to hectormapping/scanmatcher.init
> 48 on entry to hectormapping/map/gridmap/occbase.init
> 40 on entry to hectormapping/map/gridmap/base.init
> 32 on entry to hectormapping/map/gridmap.init
> 24 on entry to github.com/skelterjohn/go%2ematrix.init
> 16 on entry to math.init
> 8 on entry to math.init┬À1
> 0 on entry to runtime.panicindex
> -8 on entry to runtime.morestack00
> # runtime.main: nosplit stack overflow
> 120 guaranteed after split check in runtime.main
> 128 after runtime.main uses -8
> 120 on entry to main.init
> 112 on entry to robot/web.init
> 104 on entry to robot/controller.init
> 96 on entry to robot/slam.init
> 88 on entry to robot/slam/hector.init
> 80 on entry to hectormapping/map/mapimages.init
> 72 on entry to hectormapping/map/maprep.init
> 64 on entry to hectormapping/map/mapproccontainer.init
> 56 on entry to hectormapping/scanmatcher.init
> 48 on entry to hectormapping/map/gridmap/occbase.init
> 40 on entry to hectormapping/map/gridmap/base.init
> 32 on entry to hectormapping/map/gridmap.init
> 24 on entry to github.com/skelterjohn/go%2ematrix.init
> 16 on entry to math.init
> 8 on entry to math.init┬À1
> 0 on entry to runtime.panicindex
> -8 on entry to runtime.morestack00

Does anyone know what this is about? I can't find much documentation as to what might be causing it, except that for some cases this is a bug that supposedly is fixed.

Some of the code was split into a new folder in the "src" folder, so that the file structure is now:

src/robot/main.go (main() lives here)
src/robot/(...) (application-specific packages)
src/hectormapping/(...) (stand-alone package used in "robot")

I am using Go 1.0.3 on Windows 7 (x64).

答案1

得分: 6

这似乎与这里描述的情况相同,据说已在tip中修复。相应的修复可以在这里进行审查。

总结一下我所看到的问题:
使用分割堆栈来扩展堆栈,而不是传统的固定内存区域。这样做的好处是可以生成更多的线程,因为只有实际保留所需的堆栈内存。问题似乎在于链接器错误地将不使用分割堆栈上的内存的函数标记为“nosplit”,因为它找不到分割堆栈的前导部分。这导致链接器计算出错误的堆栈限制,进而让链接器认为没有空间,并向您抛出错误消息。

不幸的是,获取tip版本的唯一方法是自己编译它。正如Nick Craig-Wood已经提到的,您可以在这里找到说明。如果您真的无法升级,可以尝试通过在init函数中分配一些任意的局部变量来解决此问题。但这当然非常混乱。

英文:

This seems to be the same as described here which was said to be fixed in tip. The corresponding fix can be reviewed here.

To summarize the problem as I am seeing it:
Split stacking is used for growing stacks instead of the conventional fixed memory area. This has the benefit that more threads can be spawned, as only the needed stack memory is actually reserved. The problem here seems to be that the linker marks functions that don't use memory on the split stack accidentally as 'nosplit' because it doesn't find the split stack prologue. This leads to the linker calculating a wrong stack limit, which in turn lets the linker think there's no space and throws the error message at you.

Sadly, the only way of getting the tip version is to compile it by yourself. As Nick Craig-Wood already mentioned, you can find the instructions here. If you really really can't upgrade, you could try to work around this by allocation some arbitrary local variable in your init functions. But this is very messy of course.

huangapple
  • 本文由 发表于 2013年3月21日 18:12:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/15544601.html
匿名

发表评论

匿名网友

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

确定