2011-02-17 57 views
11

我開始學會了WinDbg中,我發現這個好職位 How to use WinDbg to analyze the crash dump for VC++ application?如何編寫將會崩潰並生成轉儲文件的示例代碼?

現在我想按照指示做一步一步來。問題在於:我需要編寫一些可立即崩潰的示例代碼,並創建一些windbg可以使用的轉儲文件。

如何編寫這樣的代碼?

void Example4() 
{ 
    int* i = NULL; 
    *i = 80; 
} 

上面的代碼會立即崩潰;但是,我不知道在哪裏可以找到轉儲文件?

謝謝

+13

你可以借用一些我的代碼;-) – Jimmy 2011-02-17 12:17:17

+0

看看這個也是:http://www.debuginfo.com/articles/effminidumps.html我發現它非常有用。它還包含一些示例代碼。 – Naveen 2011-02-17 12:18:16

回答

23
#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; 
} 
-3

試試這個:

int main() 
{ 
    int v[5]; 

    printf("%d", v[10]); 
    return 0; 
} 

或訪問一個隨機的內存位置。

+5

這可能不會崩潰 - v [10]中的堆棧內存可能實際上已分配,printf將僅打印出垃圾。 – 2011-02-17 12:19:51

1

如果你想看到崩潰轉儲,你需要創建一個。見Heisenbug: WinApi program crashes on some computers。儘管您可能能夠在不通過WinQual的情況下獲得旨在發送WER的故障轉儲,但它有點混亂(基本上可以在臨時位置將其複製之前將其複製,具體細節取決於您的操作系統) ,我會建議使用Win API MiniDump提供的功能創建您自己的crashdump。所有需要的代碼可以在The CodeProject page mentioned in the linked answer找到。

1

自動微型轉儲的生成是由驗屍調試器完成的,所以你需要從那裏開始。最重要的是,它由調試器完成。所以如果你只是想生成一個小型轉儲,你可以使用你的典型調試器(可能是visual studio或windbg)。即使任務管理器也能創建轉儲文件。

指定的驗屍調試器的註冊表設置爲HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug

看那Debugger字符串,你會用自己的方式找到您的小型轉儲。

1

轉儲文件可以創建programmaticaly或程序錯誤調試工具。在第一種情況下,你可以使用MiniDumpWriteDump功能,並在第二個您可以使用的Dr. Watson(對於XP:看看這個description這很描述video;爲Vista,看看here

0

我使用的代碼以前在測試WinDbg的時候。

  • 以下作品的代碼,並生成崩潰轉儲
  • 有兩個功能,使你可以看到一個堆棧跟蹤與功能的明顯鏈。
  • 要查找故障轉儲,請在C:\ Users中搜索* .dmp或* .mdmp
  • 可能最好讓操作系統爲您生成轉儲。這可能是您看到的大多數實際崩潰轉儲將會生成的原因。
  • 該代碼的工作原理是首先分配1 KiB的內存,然後將它和下面的1 KiB寫入一個可識別的十六進制值。這通常會將由OS標記的內存頁面命中爲不可寫入的頁面,這將觸發崩潰。

#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; 
} 
0

要創建崩潰轉儲,我會寫未處理的異常處理程序有以下原因提出@Abyx:

一)在一些緩衝區溢出的情況下,或堆棧溢出,處理未處理的異常的代碼可能已損壞。如果發生OutOfMemoryException,如何加載另一個庫,如DbgHelp.dll?

b)你寫的代碼可能是越野車。該代碼是否在寫入轉儲之前檢查可用磁盤空間?你如何測試代碼來編寫崩潰轉儲?你有單元測試嗎?你的單元測試如何檢查轉儲是否正確?

c)爲什麼如果Windows可以爲你寫代碼呢?

MSDN在Collecting user mode dumps上有一篇文章。基本上,您可以創建一些註冊表設置。優點是:Windows將通過操作系統創建崩潰轉儲,而不是由您自己的應用程序中的某些損壞的代碼創建。

0

大多數情況下,您可以在C:\ windows \ minidumps中找到所有應用程序轉儲。

要生成你可以使用一個簡單的解決方案轉儲文件:

  1. 打開WinDbg的
  2. 文件 - >打開可執行
  3. 您運行的應用程序,會崩潰
  4. 斷點將觸發
  5. 現在你可以在windbg中使用.dump創建一個dmp文件

  1. 運行程序,等待崩潰
  2. 開放的WinDbg和附加到進程(文件 - >附加到進程)
  3. 運行使用.dump

這樣,你就可以隨時分析崩潰:)