2012-12-03 32 views
8

My Mono application崩潰在Mac上使用此消息(Full log):堆棧溢出的非託管:IP:0x26eb76,故障地址:0xbf808ffc

$ 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上運行良好。

回答

4

處理堆棧溢出非常棘手(對於單聲道),所以很可能堆棧溢出實際上是你自己的。問題在於找出堆棧跟蹤。

我通常使用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 here調試mono的提示。