有人可以提出一个很好的免费工具来分析除Adplus/windbg/sos之外的.Net内存转储吗?
我正在寻找一个跨平台的崩溃处理程序.谷歌Breakpad看起来很有前途,但它非常缺乏任何文档,并且需要合理数量的摆弄实际开始.
什么是更好的选择?
我所需要的只是能够在崩溃时可靠地记录故障转储,堆栈跟踪和CPU信息.或者,使用Google Breakpad的体验是什么?它是伟大的还是可怕的?
当在安装时在.NET托管应用程序上执行ngen,并从应用程序的Windows错误报告中检索崩溃转储时,如何使用它来查看堆栈跟踪,变量等?
以下是与该问题相关的一些背景知识:我们有一个.NET应用程序,可以在安装时使用.当由于未处理的.NET异常而崩溃时,崩溃将在Windows错误报告中进行存储,从中我可以从winqual.microsoft.com下载minidump.mdmp文件.
我将minidump.mdmp放在一个包含.dbg文件的文件夹中,用于构建崩溃的应用程序,然后双击minidump.mdmp在VS2008 SP1的新实例中打开它.我的堆栈跟踪如下所示:
kernel32.dll!RaiseException()+ 0x3d bytes
mscorwks.dll!RaiseTheExceptionInternalOnly()+ 0x295 bytes
mscorwks.dll!JIT_Throw()+ 0x130 bytes
MyApp.ni.exe!000007feee74c84c()
[下面的框架可能不正确和/或缺失,没有为MyApp.ni.exe加载的符号]
0000000070000d5e()
MyApp.ni.exe!000007feee611000()
000000000300bf78()
000000000300bf60()
模块窗口指示为OS和.NET DLL加载符号,但对于应用程序模块,我得到:
MyApp.exe - >符号文件中没有本机符号.
MyApp.ni.exe - >找不到匹配的二进制文件.
MyAppsLibrary.ni.dll - >找不到匹配的二进制文件.
我有一个.Net应用程序转储捕获异常,我正在使用windbg进行分析,并对其中一个方法的String参数值感兴趣.我已经隔离了String对象.我的windbg工作是:
0:000> .loadby sos mscorwks
0:000> !dso
OS Thread Id: 0x16f0 (0)
RSP/REG Object Name
00000000001fe908 000000000f011440 System.AppDomainSetup
00000000001fe918 000000000f0335f8 System.ArgumentException
00000000001fe920 000000000f011b60 System.String
0:000> !do 000000000f011b60
Name: System.String
MethodTable: 000007feef477a80
EEClass: 000007feef07e530
Size: 538(0x21a) bytes
(C:\Windows\assembly\GAC_64\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
String: C:\Windows\Installer\MSI2D87.tmp
Fields:
MT Field Offset Type VT Attr Value Name
000007feef47ecf0 4000096 8 System.Int32 1 instance 257 m_arrayLength
000007feef47ecf0 4000097 c System.Int32 1 instance 179 m_stringLength
000007feef4794c8 4000098 10 System.Char 1 instance 43 m_firstChar
000007feef477a80 4000099 20 System.String 0 shared static Empty …Run Code Online (Sandbox Code Playgroud) 你怎么经常解决这个问题?想象一下,线程在Computer1上的libc代码(这是一个系统共享库)内崩溃,然后生成一个coredump.但是,将分析此coredump的Computer2可能具有不同版本的libc.
所以:
在远程计算机上拥有相同的共享库有多重要?gdb会在Conputer2上没有完全相同版本的libc的情况下正确重建stacktrace吗?
为libc提供正确的调试符号有多重要?gdb会在Computer2上没有完全相同的调试符号的情况下正确地重建堆栈跟踪吗?
什么是避免共享系统库的调试符号不匹配问题的"正确"方法?对我来说,似乎没有单一的解决方案以优雅的方式解决这个问题?也许有人可以分享他的经历?
是否有可能在vsjitdebugger显示的调试器列表中包含WinDbg,当后者被配置为HKLM中的默认debuuger时......\AeDebug?
理想情况下,我希望能够在vsjitdebugger中的选项列表中包含更多命令行,这些命令行在进程遇到未处理的异常时可用:使用DrWatson或使用WinDbg保存minidump以供以后检查.
请注意,我不想用我的问题解决任何问题 - 我正在考虑事情发生的可能性,因此想知道一些事情:
如果你删除对象并使用gcc作为编译器会发生什么?
上周我正在调查一次撞车事故,其中一场竞赛条件导致双重删除一个物体.
调用对象的虚析构函数时发生崩溃,因为已经覆盖了指向虚函数表的指针.
虚拟函数指针是否被第一次删除覆盖?
如果没有,那么第二次删除是否安全,只要在此期间没有进行新的内存分配?
我想知道为什么我之前没有识别出的问题,唯一的例外是虚拟功能表在第一次删除时立即被覆盖,或者第二次删除不会崩溃.
(第一个意味着如果发生"竞赛",崩溃总是发生在同一个位置 - 第二个,通常在竞赛发生时没有发生 - 并且只有在第三个线程覆盖删除对象的同时才会出现问题. )
编辑/更新:
我做了一个测试,下面的代码崩溃了一个segfault(gcc 4.4,i686和amd64):
class M
{
private:
int* ptr;
public:
M() {
ptr = new int[1];
}
virtual ~M() {delete ptr;}
};
int main(int argc, char** argv)
{
M* ptr = new M();
delete ptr;
delete ptr;
}
Run Code Online (Sandbox Code Playgroud)
如果我从dtor中删除'virtual',程序将被glibc中止,因为它检测到双重释放.使用'virtual'时,在对析构函数执行间接函数调用时会发生崩溃,因为指向虚函数表的指针无效.
在amd64和i686上,指针指向一个有效的内存区域(堆),但是那里的值是无效的(一个计数器?它非常低,例如0x11或0x21)所以'call'(或编译时为'jmp')做了返回优化)跳转到无效区域.
程序收到信号SIGSEGV,
分段故障.0x0000000000000021
在??? ()(gdb)
#0 0x0000000000000021?()
#main()中的1 0x000000000040083e
因此,在上述条件下,指向虚函数表的指针总是被第一次删除覆盖,因此如果该类具有虚拟析构函数,则下一次删除将跳转到必杀技.
我间歇性地在转储文件中收到一个浏览器因此错误而挂起。
使用!analyze -v3次崩溃后,我收到此错误和堆栈
GetUrlPageData2 (WinHttp) failed: 12007.
Run Code Online (Sandbox Code Playgroud)
但是,我永远无法在失败的转储文件中找到该URL。有人可以帮忙吗?
STACK_TEXT:
0029e8fc 5ffce1fd 74ce1450 00000000 00000000 user32!NtUserWaitMessage+0x15
0029e960 5ffd5f2c 00000001 0070fab0 00000000 ieframe!CBrowserFrame::FrameMessagePump+0x52e
0029e9a8 5ffd64e4 00000000 74ce1450 00708618 ieframe!BrowserThreadProc+0xf8
0029e9c8 5ffd6441 00708618 00000000 00708618 ieframe!BrowserNewThreadProc+0x88
0029fa38 5ffd62b2 00708618 00000000 76655528 ieframe!SHOpenFolderWindow+0x109
0029fa5c 5ffd61b1 006e4188 00000001 00000000 ieframe!IEWinMainEx+0x204
0029fa78 5ffd6120 006e4188 00000001 00000000 ieframe!IEWinMain+0x77
0029fab0 00c32fdb 006e4188 00000001 01000000 ieframe!LCIEStartAsFrame+0x265
0029fc04 00c312a2 00c30000 00000000 006a21cc iexplore!wWinMain+0x3b2
0029fc98 74ce33aa 7efde000 0029fce4 77159ef2 iexplore!_initterm_e+0x1b1
0029fca4 77159ef2 7efde000 77f3a412 00000000 kernel32!BaseThreadInitThunk+0xe
0029fce4 77159ec5 00c31b0a …Run Code Online (Sandbox Code Playgroud) windows debugging windbg postmortem-debugging internet-explorer-8
我有一个auto_ptr<IFoo>,IFoo只有纯虚方法的接口.
我现在在分段错误之后也有一个核心文件,我真的想知道这个auto_ptr背后的具体子类是什么.作为dynamic_cast项目中的工作,我认为RTTI必须以某种方式提供,但我不知道如何通过这些信息访问gdb?
我得到的输出如下:
(gdb) print this->obj._M_ptr
$22 = (class martin::IFoo *) 0x7418
Run Code Online (Sandbox Code Playgroud)
我真的很想知道,如果指针属于一个IBar或一个IBaz.
谢谢你的帮助!
我正在对崩溃的程序进行事后分析。我在 Linux (Ubuntu 12.04, x86) 上,代码是用 C++ 编写的。本程序正在使用一些可能包含有价值信息的单例。如果像这样创建,是否可以找到指向单例实例的指针:
SingletonType& SingletonType::getInstance(){
static SingletonType* instance = new SingletonType();
return *instance;
}
Run Code Online (Sandbox Code Playgroud)
如果可能的话,它是如何在 GDB 中完成的?
c++ ×4
debugging ×3
gdb ×3
.net ×2
windbg ×2
windows ×2
crash ×1
crash-dumps ×1
gcc ×1
linux ×1
memory-dump ×1
minidump ×1
ngen ×1
probability ×1