9

Mac でMono アプリケーションがクラッシュし、次のメッセージが表示されます ( Full log ):

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

「管理されていない」とは、スタック オーバーフローが私のコード (私は管理されたコードしか持っていない) ではなく、埋め込んだライブラリ ( SQLite、DotCmis、NewtonSoft.Json ) または Mono のコードにあることを意味します。

デバッグ モードでコンパイルして実行しても、得られるのはこれら 2 つの 16 進数だけです。

質問:このスタック オーバーフローを調査するにはどうすればよいですか? 何かトリック?

注: 同じライブラリ (ほぼ同じコード) は、Linux と Windows で正常に動作します。

4

1 に答える 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と、スタック オーバーフローが発生しようとしているかどうかがわかります (1 つのスレッドには数千のフレームがあります)。

gdb で大量のスタック トレースを取得したら、サイクルを特定する必要があります。これは通常、スタック トレースのアドレスを見るだけで非常に簡単です。このデータを取得したら、次のようにマネージド フレームを取得できます。

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

次に、見つけたサイクルのすべてのフレームに対して同じことを行います。

gdb を使用して mono をデバッグするためのその他のヒントは、こちら にあります

于 2012-12-03T13:09:05.480 に答える