非托管堆栈溢出:IP:0x26eb76,错误地址:0xbf808ffc

Nic*_*oul 9 stack-overflow mono unmanaged monodevelop monomac

我的Mono应用程序在Mac上崩溃并显示此消息(完整日志):

$ mono --debug bin/Debug/SparkleShare.app/Contents/MonoBundle/SparkleShare.exe
[...]
Stack overflow in unmanaged: IP: 0x26eb76, fault addr: 0xbf808ffc
[...]
Run Code Online (Sandbox Code Playgroud)

"in unmanaged"意味着堆栈溢出不在我的代码中(我只有托管代码),而是在我嵌入的库(SQLite,DotCmis,NewtonSoft.Json)或Mono的代码中.

即使我在调试模式下编译并运行,我得到的只是这两个十六进制.

问题:如何调查此堆栈溢出?任何诡计?

注意:相同的库(具有几乎相同的代码)在Linux和Windows上运行良好.

Rol*_*nge 5

处理堆栈溢出非常棘手(对于单声道),所以很可能堆栈溢出实际上是你的.问题在于找出堆栈跟踪.

我通常用gdb运行:

gdb --args mono --debug bin/Debug/SparkleShare.app/Contents/MonoBundle/SparkleShare.exe
Run Code Online (Sandbox Code Playgroud)

然后尝试在堆栈开始增长之后按Ctrl + C,但在它实际溢出之前(gdb与堆栈溢出严重混淆,并且当发生这种情况时你通常必须退出gdb,这就是为什么你会需要抓住溢出的动作).

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

一旦你在gdb中有一个巨大的堆栈跟踪,你需要识别循环.通过查看堆栈跟踪的地址,这通常很容易.获得此数据后,您可以获得如下管理框架:

(gdb) p mono_pmip (0xdeaddead)
$1 = 0x0000dead  "Managed frame information shows up here"
Run Code Online (Sandbox Code Playgroud)

然后对你找到的周期中的所有帧执行相同的操作.

有两种使用gdb调试单更多的技巧在这里.