非托管堆栈溢出:IP地址:0x26eb76,故障地址:0xbf808ffc。

9
我的Mono应用在Mac上崩溃,出现以下错误信息(完整日志请参见此处:Full log):

My Mono application


$ mono --debug bin/Debug/SparkleShare.app/Contents/MonoBundle/SparkleShare.exe
[...]
Stack overflow in unmanaged: IP: 0x26eb76, fault addr: 0xbf808ffc
[...]

“在未经管理的”意味着堆栈溢出不在我的代码中(我只有托管代码),而是在我嵌入的库(SQLite,DotCmis,NewtonSoft.Json)或Mono的代码中。即使我以调试模式编译和运行,我得到的只有这两个十六进制数。问题是:如何调查此堆栈溢出?有什么技巧吗?注意:相同的库(几乎相同的代码)在Linux和Windows上运行良好。
1个回答

5
处理堆栈溢出对于Mono来说非常棘手,因此很可能实际上是您的堆栈溢出。问题在于找出堆栈跟踪。
我通常使用gdb运行:
gdb --args mono --debug bin/Debug/SparkleShare.app/Contents/MonoBundle/SparkleShare.exe

然后在堆栈开始增长但尚未实际溢出时尝试按Ctrl + C,(gdb在堆栈溢出时会变得非常混乱,当这种情况发生时,通常必须退出gdb,因此您需要在操作中捕获溢出)。

按下Ctrl + C后,执行thread apply all backtrace,您将知道是否即将发生堆栈溢出(一个线程将具有数千个帧)。

一旦您在gdb中拥有了巨大的堆栈跟踪,您需要确定循环。通常只需查看堆栈跟踪的地址即可轻松完成此操作。一旦您拥有了这些数据,就可以像这样获取托管帧:

(gdb) p mono_pmip (0xdeaddead)
$1 = 0x0000dead  "Managed frame information shows up here"

然后,对于您找到的循环中的所有帧,都执行相同的操作。

在此处有关使用gdb调试mono的更多提示


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接