我开始学习windbg并找到了这篇好文章 How to use WinDbg to analyze the crash dump for VC++ application?
现在我想按照说明一步一步地做。问题在于:我需要编写一些可以立即崩溃的示例代码,并创建一些可以由windbg使用的转储文件。
如何编写此类代码?
void Example4()
{
int* i = NULL;
*i = 80;
}
以上代码会立即崩溃;但是,我不知道在哪里可以找到转储文件?
谢谢
答案 0 :(得分:29)
#include <Windows.h>
#include <Dbghelp.h>
void make_minidump(EXCEPTION_POINTERS* e)
{
auto hDbgHelp = LoadLibraryA("dbghelp");
if(hDbgHelp == nullptr)
return;
auto pMiniDumpWriteDump = (decltype(&MiniDumpWriteDump))GetProcAddress(hDbgHelp, "MiniDumpWriteDump");
if(pMiniDumpWriteDump == nullptr)
return;
char name[MAX_PATH];
{
auto nameEnd = name + GetModuleFileNameA(GetModuleHandleA(0), name, MAX_PATH);
SYSTEMTIME t;
GetSystemTime(&t);
wsprintfA(nameEnd - strlen(".exe"),
"_%4d%02d%02d_%02d%02d%02d.dmp",
t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond);
}
auto hFile = CreateFileA(name, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if(hFile == INVALID_HANDLE_VALUE)
return;
MINIDUMP_EXCEPTION_INFORMATION exceptionInfo;
exceptionInfo.ThreadId = GetCurrentThreadId();
exceptionInfo.ExceptionPointers = e;
exceptionInfo.ClientPointers = FALSE;
auto dumped = pMiniDumpWriteDump(
GetCurrentProcess(),
GetCurrentProcessId(),
hFile,
MINIDUMP_TYPE(MiniDumpWithIndirectlyReferencedMemory | MiniDumpScanMemory),
e ? &exceptionInfo : nullptr,
nullptr,
nullptr);
CloseHandle(hFile);
return;
}
LONG CALLBACK unhandled_handler(EXCEPTION_POINTERS* e)
{
make_minidump(e);
return EXCEPTION_CONTINUE_SEARCH;
}
int main()
{
SetUnhandledExceptionFilter(unhandled_handler);
return *(int*)0;
}
答案 1 :(得分:4)
这将产生一个空指针解除引用异常:
*((int*) 0) = 0;
这将产生整数除零:
int a = 0; int b = 5 / a;
编辑:Post-Mortem Debugging Your Application with Minidumps and Visual Studio .NET包含大量使用小型转储的示例代码和理论。
答案 2 :(得分:1)
如果要查看崩溃转储,则需要创建一个。见Heisenbug: WinApi program crashes on some computers。虽然您可以在不通过WinQual的情况下获得故意发送给WER的故障转储,但它有点混乱(基本上您可以在它被发送之前从临时位置复制它,具体细节取决于您的操作系统) ,我建议使用Win API MiniDump提供的函数创建自己的crashdump。可以在The CodeProject page mentioned in the linked answer找到所需的所有代码。
答案 3 :(得分:1)
自动小型转储生成由事后调试器完成,因此您需要从那里开始。最重要的是,它由调试器完成。因此,如果您只想生成一个minidump,您可以使用典型的调试器(可能是visual studio或windbg)。甚至任务管理器也可以创建转储文件。
指定事后调试器的注册表设置为HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug
查看Debugger
字符串,您就可以找到您的小型转发了。
答案 4 :(得分:1)
转储文件可以通过programmaticaly或程序错误调试工具创建。在第一种情况下,你可以使用MiniDumpWriteDump功能,在第二种情况下,你可以使用Dr. Watson(对于XP:看看这个description和这个非常具有描述性的video;对于Vista,有看看here)
答案 5 :(得分:1)
要创建崩溃转储,我会不编写@Abyx建议的未处理异常处理程序,原因如下:
a)在某些缓冲区溢出或堆栈溢出的情况下,处理未处理异常的代码可能已损坏。如果出现OutOfMemoryException,如何加载像DbgHelp.dll这样的其他库?
b)你写的代码可能有问题。该代码是否在写入转储之前检查可用磁盘空间?你如何测试代码来编写崩溃转储?你有单元测试吗?您的单元如何检查转储是否正确?c)如果Windows可以为你做代码,为什么要编写代码呢?
MSDN上有一篇关于Collecting user mode dumps的文章。基本上,您可以进行一些注册表设置。优点是:Windows将通过操作系统创建崩溃转储,而不是由您自己的应用程序中的某些损坏的代码创建。答案 6 :(得分:0)
我在前一段时间测试WinDbg时使用了以下代码。
#include "stdafx.h"
#include "stdio.h"
#include "malloc.h"
void Function2(int * ptr2)
{
for(int i=0; i < (2 * 1024); i++)
{
*ptr2++ = 0xCAFECAFE;
}
}
void Function1()
{
int * ptr1 = (int *)malloc(1024 * sizeof(int));
Function2(ptr1);
}
int _tmain(int argc, _TCHAR* argv[])
{
printf("Press enter to allocate and corrupt.\r\n");
getc(stdin);
printf("Allocating and corrupting...\r\n");
Function1();
printf("Done. Press enter to exit process.\r\n");
getc(stdin);
return 0;
}
答案 7 :(得分:0)
大多数情况下,您会在C:\ windows \ minidumps中找到所有应用程序转储。
要生成转储文件,您可以使用简单的解决方案:
或
通过这种方式,您可以随时分析崩溃:)
答案 8 :(得分:-3)
试试这个:
int main()
{
int v[5];
printf("%d", v[10]);
return 0;
}
或访问随机内存位置。