我有一个用 C# 编写并使用 Mono 在 Linux 系统上运行的大型程序,它偶尔会崩溃并导致mono.bin
进程转储核心。
我运行gdb
了一些核心转储文件,但它不是很有用,因为回溯中没有 C# 函数的名称。根据这个讨论,我发现:
它行不通。构建托管堆栈跟踪所需的信息包含在运行时数据结构中,并且仅在程序运行时可用。您可以 AOT 您的应用程序,然后您将拥有更多可用的堆栈跟踪。
所以我做了。我 AOT 编译了我所有的 C# DLL 和 EXE 文件。使用--aot=write-symbols
选项。对于我的程序的测试版本,它故意崩溃,所以我可以检查这是否使回溯更有用。到目前为止,还没有。主线程的回溯如下所示:
#0 0xb7fc8402 in __kernel_vsyscall ()
#1 0x00556df0 in raise () from /lib/libc.so.6
#2 0x00558701 in abort () from /lib/libc.so.6
#3 0x080e59b5 in ?? ()
另一个线程有:
#0 0xb7fc8402 in __kernel_vsyscall ()
#1 0x005f6753 in poll () from /lib/libc.so.6
#2 0xb6f735a7 in Mono_Unix_UnixSignal_WaitAny ()
from /opt/novell/mono/lib/libMonoPosixHelper.so
#3 0xb5416578 in ?? ()
其他线程似乎一直处于空闲状态(在nanosleep
、pthread_cond_timedwait
、pthread_cond_wait
、sem_timedwait
或中sem_wait
)。但所有回溯的共同点是,它们都以令人讨厌的 . 结尾in ?? ()
,并且从不列出“我的”代码中的任何函数名称。
我认为这与gdb
它启动时打印的一些消息有关;例如,
Reading symbols from /xyz/mono/log4net.dll.so...(no debugging symbols found)...done.
Loaded symbols for /xyz/mono/log4net.dll.so
Reading symbols from /xyz/mono/Contoso.Util.dll.so...(no debugging symbols found)...done.
Loaded symbols for /xyz/mono/Contoso.Util.dll.so
Reading symbols from /xyz/mono/Contoso.Printing.dll.so...(no debugging symbols found)...done.
Loaded symbols for /xyz/mono/Contoso.Printing.dll.so
Reading symbols from /xyz/mono/Contoso.LegacyDataConverter.dll.so...(no debugging symbols found)...done.
Loaded symbols for /xyz/mono/Contoso.LegacyDataConverter.dll.so
为什么所有*.dll.so
文件都“找不到调试符号”?DLL 本身是否需要以“调试”模式或其他方式构建?
更一般地说,有没有办法从 Mono 核心转储中获取托管堆栈跟踪?(不使用mono_pmip
,因为它仅在进程运行时可用。)