dump文件,windbg

2023-05-16

dump文件,在VC中的调试还是非常非常非常有用的,因为我们也不会经每一行代码都加上日志,当然如果你愿意,也可以每一行都加上日志;

在Windows上,添加dump文件有两种方法:

方法一:一个是在程序中添加代码;

方法二:修改注册表(参考后面的bat文件写法,在win7上用管理员程序运行);建议用这个方法,方便实用;(http://blog.csdn.net/hgy413/article/details/7586957#)

 

方法三: Google breakpad;

https://chromium.googlesource.com/breakpad/breakpad/

git clone https://chromium.googlesource.com/breakpad/breakpad

编译方法1:MSYS configure, make 编译; //说明,没有全部编译完成 windows 需要的lib;

编译方法2:gyp 编译;  

2.1:需要安装 vs2015 (或者 vs2017 , 目前编译脚本需要 vs2015);

2.2: 安装 python 2.7;

2.3:下载 gyp 工具  https://github.com/svn2github/gyp ,然后解压到 C 盘 gyp 目录; 可以设置系统环境变量;如果不设置,每次要设置命令提示行环境变量;

3.3:在开始菜单中 打开: VS2015 开发人员命令提示   工具;不是 cmd ;

3.4: cd  /d   C:\gyp 

3.5: setup.py install

3.6:  C:\gyp>gyp.bat --no-circular-check  D:\opensrc\src\third_party\breakpadtest\breakpad\src\client\windows\breakpad_client.gyp

3.7:然后可以打开 sln 编译了;

参考:https://blog.csdn.net/u013394556/article/details/52303218

 

 

from:

http://blog.csdn.net/byxdaz/article/details/25872151

http://blog.csdn.net/starlee/article/details/6630816

 

如果是 chromium 默认编译的, 编译的静态库是 breakpad_handler.lib; msvs 不可以用;可以在 ninja 中用;或 clang 者包装为 DLL 再用;

 

 

 

在Windows平台下用C++开发应用程序,最不想见到的情况恐怕就是程序崩溃,而要想解决引起问题的bug,最困难的应该就是调试release版本了。因为release版本来就少了很多调试信息,更何况一般都是发布出去由用户使用,crash的现场很难保留和重现。目前有一些方法可以解决:崩溃地址 + MAP文件;MAP文件;SetUnhandledExceptionFilter + Minidump。本文重点解决Minidump方式。

一、Minidump文件生成

  1、Minidump概念

    minidump(小存储器转储)可以理解为一个dump文件,里面记录了能够帮助调试crash的最小有用信息。实际上,如果你在系统属性 -> 高级 -> 启动和故障恢复 -> 设置 -> 写入调试信息中选择“小内存转储(64 KB)”的话,当系统意外停止时都会在C:\Windows\Minidump\路径下生成一个.dmp后缀的文件,这个文件就是minidump文件,只不过这个是内核态的minidump。

   我们要生成的是用户态的minidump,文件中包含了程序运行的模块信息、线程信息、堆栈调用信息等。而且为了符合其mini的特性,dump文件是压缩过的。

2、生成minidump文件

通过drwtsn32、NTSD、CDB等调试工具生成Dump文件, drwtsn32存在的缺点虽然NTSD、CDB可以完全解决,但并不是所有的操作系统中都安装了NTSD、CDB等调试工具。根据MiniDumpWriteDump接口,完全可以程序自动生成Dump文件。

 

3、  自动生成Minidump文件

当程序遇到未处理异常(主要指非指针造成)导致程序崩溃死,如果在异常发生之前调用了SetUnhandledExceptionFilter()函数,异常交给函数处理。MSDN中描述为:

Issuing SetUnhandledExceptionFilter replaces the existing top-level exception filter for all existing and all future threads in the calling process.

 因而,在程序开始处增加SetUnhandledExceptionFilter()函数,并在函数中利用适当的方法生成Dump文件,即可实现需要的功能。

生成dump文件类(minidump.h)

[cpp] view plaincopy

  1. #pragma once  
  2.   
  3.    
  4.   
  5. #include <windows.h>  
  6.   
  7. #include <imagehlp.h>  
  8.   
  9. #include <stdlib.h>  
  10.   
  11. #pragma comment(lib, "dbghelp.lib")  
  12.   
  13.    
  14.   
  15. inline BOOL IsDataSectionNeeded(const WCHAR* pModuleName)  
  16.   
  17. {  
  18.   
  19.     if(pModuleName == 0)  
  20.   
  21.     {  
  22.   
  23.        return FALSE;  
  24.   
  25.     }  
  26.   
  27.    
  28.   
  29.     WCHAR szFileName[_MAX_FNAME] = L"";  
  30.   
  31.     _wsplitpath(pModuleName, NULL, NULL, szFileName, NULL);  
  32.   
  33.     if(wcsicmp(szFileName, L"ntdll") == 0)  
  34.   
  35.        return TRUE;  
  36.   
  37.    
  38.   
  39.     return FALSE;   
  40.   
  41. }  
  42.   
  43.    
  44.   
  45. inline BOOL CALLBACK MiniDumpCallback(PVOID                            pParam,   
  46.   
  47.                                   const PMINIDUMP_CALLBACK_INPUT   pInput,   
  48.   
  49.                                   PMINIDUMP_CALLBACK_OUTPUT        pOutput)  
  50.   
  51. {  
  52.   
  53.     if(pInput == 0 || pOutput == 0)  
  54.   
  55.        return FALSE;  
  56.   
  57.    
  58.   
  59.     switch(pInput->CallbackType)  
  60.   
  61.     {  
  62.   
  63.     case ModuleCallback:   
  64.   
  65.        if(pOutput->ModuleWriteFlags & ModuleWriteDataSeg)   
  66.   
  67.    
  68.   
  69.            if(!IsDataSectionNeeded(pInput->Module.FullPath))   
  70.   
  71.    
  72.   
  73.               pOutput->ModuleWriteFlags &= (~ModuleWriteDataSeg);   
  74.   
  75.    
  76.   
  77.     case IncludeModuleCallback:  
  78.   
  79.     case IncludeThreadCallback:  
  80.   
  81.     case ThreadCallback:  
  82.   
  83.     case ThreadExCallback:  
  84.   
  85.        return TRUE;  
  86.   
  87.    
  88.   
  89.     default:;  
  90.   
  91.     }  
  92.   
  93.    
  94.   
  95.     return FALSE;  
  96.   
  97. }  
  98.   
  99.    
  100.   
  101. //创建Dump文件  
  102.   
  103. inline void CreateMiniDump(EXCEPTION_POINTERS* pep, LPCTSTR strFileName)  
  104.   
  105. {  
  106.   
  107.     HANDLE hFile = CreateFile(strFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);  
  108.   
  109.     if((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE))  
  110.   
  111.     {  
  112.   
  113.        MINIDUMP_EXCEPTION_INFORMATION mdei;  
  114.   
  115.        mdei.ThreadId           = GetCurrentThreadId();  
  116.   
  117.        mdei.ExceptionPointers  = pep;  
  118.   
  119.        mdei.ClientPointers     = FALSE;  
  120.   
  121.        MINIDUMP_CALLBACK_INFORMATION mci;  
  122.   
  123.        mci.CallbackRoutine     = (MINIDUMP_CALLBACK_ROUTINE)MiniDumpCallback;  
  124.   
  125.        mci.CallbackParam       = 0;  
  126.   
  127.        MINIDUMP_TYPE mdt       = (MINIDUMP_TYPE)0x0000ffff;  
  128.   
  129.        MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &mdei, NULL, &mci);  
  130.   
  131.    
  132.   
  133.        CloseHandle(hFile);   
  134.   
  135.     }  
  136.   
  137. }  
  138.   
  139.    
  140.   
  141. LPTOP_LEVEL_EXCEPTION_FILTER WINAPI MyDummySetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter)  
  142.   
  143. {  
  144.   
  145.     return NULL;  
  146.   
  147. }  
  148.   
  149.    
  150.   
  151. BOOL PreventSetUnhandledExceptionFilter()  
  152.   
  153. {  
  154.   
  155.     HMODULE hKernel32 = LoadLibrary(_T("kernel32.dll"));  
  156.   
  157.     if (hKernel32 ==   NULL)  
  158.   
  159.        return FALSE;  
  160.   
  161.    
  162.   
  163.    
  164.   
  165.     void *pOrgEntry = GetProcAddress(hKernel32, "SetUnhandledExceptionFilter");  
  166.   
  167.     if(pOrgEntry == NULL)  
  168.   
  169.        return FALSE;  
  170.   
  171.    
  172.   
  173.    
  174.   
  175.     unsigned char newJump[ 100 ];  
  176.   
  177.     DWORD dwOrgEntryAddr = (DWORD) pOrgEntry;  
  178.   
  179.     dwOrgEntryAddr += 5; // add 5 for 5 op-codes for jmp far  
  180.   
  181.    
  182.   
  183.    
  184.   
  185.     void *pNewFunc = &MyDummySetUnhandledExceptionFilter;  
  186.   
  187.     DWORD dwNewEntryAddr = (DWORD) pNewFunc;  
  188.   
  189.     DWORD dwRelativeAddr = dwNewEntryAddr -  dwOrgEntryAddr;  
  190.   
  191.    
  192.   
  193.    
  194.   
  195.     newJump[ 0 ] = 0xE9;  // JMP absolute  
  196.   
  197.     memcpy(&newJump[ 1 ], &dwRelativeAddr, sizeof(pNewFunc));  
  198.   
  199.     SIZE_T bytesWritten;  
  200.   
  201.     BOOL bRet = WriteProcessMemory(GetCurrentProcess(),    pOrgEntry, newJump, sizeof(pNewFunc) + 1, &bytesWritten);  
  202.   
  203.     return bRet;  
  204.   
  205. }  
  206.   
  207.    
  208.   
  209.    
  210.   
  211. LONG WINAPI UnhandledExceptionFilterEx(struct _EXCEPTION_POINTERS *pException)  
  212.   
  213. {  
  214.   
  215.     TCHAR szMbsFile[MAX_PATH] = { 0 };  
  216.   
  217.     ::GetModuleFileName(NULL, szMbsFile, MAX_PATH);  
  218.   
  219.     TCHAR* pFind = _tcsrchr(szMbsFile, '\\');  
  220.   
  221.     if(pFind)  
  222.   
  223.     {  
  224.   
  225.        *(pFind+1) = 0;  
  226.   
  227.        _tcscat(szMbsFile, _T("CreateMiniDump.dmp"));  
  228.   
  229.        CreateMiniDump(pException,szMbsFile);  
  230.   
  231.     }  
  232.   
  233.    
  234.   
  235.    
  236.   
  237.     // TODO: MiniDumpWriteDump  
  238.   
  239.     FatalAppExit(-1,  _T("Fatal Error"));  
  240.   
  241.     return EXCEPTION_CONTINUE_SEARCH;  
  242.   
  243. }  
  244.   
  245.    
  246.   
  247. //运行异常处理  
  248.   
  249. void RunCrashHandler()  
  250.   
  251. {  
  252.   
  253.     SetUnhandledExceptionFilter(UnhandledExceptionFilterEx);  
  254.   
  255.     PreventSetUnhandledExceptionFilter();  
  256.   
  257. }  


 

//测试实现文件

// 一个有函数调用的类

//

class CrashTest

{

public:

    void Test()

    {

       Crash();

    }

 

private:

    void Crash()

    {

           strcpy(NULL,"adfadfg");

    }

};

 

int _tmain(int argc_TCHARargv[])

{

    //设置异常处理函数

    RunCrashHandler();

 

    CrashTest test;

    test.Test();

    getchar();

    return 0;

}

 

注意事项

1、需要配置debug选项,在C/C++选项à常规à调试信息格式(设置为程序数据库(/Zi));在连接器选项—>调试à生成调试信息(设置为是);C/C++选项à优化à禁用。(参见下图)

2、  可执行文件(exe)必须找到dbghelp.dll,才能生成Dump文件。这个DLL可以从调试工具包中找到。

3、*.exe、*.pdb、*.dump、dbghelp.dll 这四个文件需要放在同一目录下才好调试,双击dump文件时,就可以自动关联到出错代码位置。

4、为了获取更多更深入的调试信息,需要把程序优化开关设置成禁用。

5、 当异常代码定位成功以后,如果无法阻止异常的产生,可以用 __try 结构包装异常代码,__try 和 try 不同,前者可以捕获非法指针产生的异常。

__try {

// 会异常的函数

}

__except( EXCEPTION_EXECUTE_HANDLER ){

// 异常处理

}

二、调试Minidump文件

  1. 双击minidump文件(*.dmp)。默认会启动vs2008。
  2. 菜单Tools/Options, Debugging/Symbols,增加PDB文件路径。注:如果minidump文件与pdb文件在同一目录,就不用设置这个了。
  3. 若调试的程序需要微软基础库的PDB信息,可以增加一个路径为:
  4. http://msdl.microsoft.com/download/symbols
  5. 在界面下方Cache Symbol From symbol…选择本地存储这些Symbols的路径。 注:如果本地已存储过微软基础库的pdb,就直接按照此步操作设置本地路径,不必执行上一步操作了。
  6. 设置代码路径:

 

设置代码路径:

刚打开的dmp工程,进入解决方案的属性。在这里输入源程序的代码路径。注:一定是sln所在的路径,而不是vcproj的路径!

 

 

按F5,debug吧。

demo代码下载:http://download.csdn.net/detail/byxdaz/7349325

 

 

 

//-

 

 

 

#pragma once






#include <windows.h>


#include <imagehlp.h>


#include <stdlib.h>


#pragma comment(lib, "dbghelp.lib")






inline BOOL IsDataSectionNeeded(const WCHAR* pModuleName)


{


if(pModuleName == 0)


{


return FALSE;


}






WCHAR szFileName[_MAX_FNAME] = L"";


_wsplitpath(pModuleName, NULL, NULL, szFileName, NULL);


if(wcsicmp(szFileName, L"ntdll") == 0)


return TRUE;






return FALSE; 


}






inline BOOL CALLBACK MiniDumpCallback(PVOID                            pParam, 


const PMINIDUMP_CALLBACK_INPUT   pInput, 


PMINIDUMP_CALLBACK_OUTPUT        pOutput)


{


if(pInput == 0 || pOutput == 0)


return FALSE;






switch(pInput->CallbackType)


{


case ModuleCallback: 


if(pOutput->ModuleWriteFlags & ModuleWriteDataSeg) 






if(!IsDataSectionNeeded(pInput->Module.FullPath)) 






pOutput->ModuleWriteFlags &= (~ModuleWriteDataSeg); 






case IncludeModuleCallback:


case IncludeThreadCallback:


case ThreadCallback:


case ThreadExCallback:


return TRUE;






default:;


}






return FALSE;


}






//创建Dump文件


inline void CreateMiniDump(EXCEPTION_POINTERS* pep, LPCTSTR strFileName)


{


HANDLE hFile = CreateFile(strFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);


if((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE))


{


MINIDUMP_EXCEPTION_INFORMATION mdei;


mdei.ThreadId           = GetCurrentThreadId();


mdei.ExceptionPointers  = pep;


mdei.ClientPointers     = FALSE;


MINIDUMP_CALLBACK_INFORMATION mci;


mci.CallbackRoutine     = (MINIDUMP_CALLBACK_ROUTINE)MiniDumpCallback;


mci.CallbackParam       = 0;


MINIDUMP_TYPE mdt       = (MINIDUMP_TYPE)0x0000ffff;


MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &mdei, NULL, &mci);






CloseHandle(hFile); 


}


}






LPTOP_LEVEL_EXCEPTION_FILTER WINAPI MyDummySetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter)


{


return NULL;


}






BOOL PreventSetUnhandledExceptionFilter()


{


HMODULE hKernel32 = LoadLibrary(_T("kernel32.dll"));


if (hKernel32 ==   NULL)


return FALSE;










void *pOrgEntry = GetProcAddress(hKernel32, "SetUnhandledExceptionFilter");


if(pOrgEntry == NULL)


return FALSE;










unsigned char newJump[ 100 ];


DWORD dwOrgEntryAddr = (DWORD) pOrgEntry;


dwOrgEntryAddr += 5; // add 5 for 5 op-codes for jmp far










void *pNewFunc = &MyDummySetUnhandledExceptionFilter;


DWORD dwNewEntryAddr = (DWORD) pNewFunc;


DWORD dwRelativeAddr = dwNewEntryAddr -  dwOrgEntryAddr;










newJump[ 0 ] = 0xE9;  // JMP absolute


memcpy(&newJump[ 1 ], &dwRelativeAddr, sizeof(pNewFunc));


SIZE_T bytesWritten;


BOOL bRet = WriteProcessMemory(GetCurrentProcess(),    pOrgEntry, newJump, sizeof(pNewFunc) + 1, &bytesWritten);


return bRet;


}










LONG WINAPI UnhandledExceptionFilterEx(struct _EXCEPTION_POINTERS *pException)


{


TCHAR szMbsFile[MAX_PATH] = { 0 };


::GetModuleFileName(NULL, szMbsFile, MAX_PATH);


TCHAR* pFind = _tcsrchr(szMbsFile, '\\');


if(pFind)


{


*(pFind+1) = 0;


_tcscat(szMbsFile, _T("CreateMiniDump.dmp"));


CreateMiniDump(pException,szMbsFile);


}










// TODO: MiniDumpWriteDump


FatalAppExit(-1,  _T("Fatal Error"));


return EXCEPTION_CONTINUE_SEARCH;


}






//运行异常处理


void RunCrashHandler()


{


SetUnhandledExceptionFilter(UnhandledExceptionFilterEx);


PreventSetUnhandledExceptionFilter();


}

 

调试方法不用上述那么麻烦,直接在Debug目录下 或者 Release目录下 exe + pdb + dmp 在同一目录,然后双击dmp文件VC2010就可以打开,然后点击右上角的调试按钮就可以直接定位到崩溃的代码了;

参考这里: http://blog.csdn.net/starlee/article/details/6630816

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

别人机器上的dump调试:

http://blog.csdn.net/xhk456/article/details/7523150

 

 

这段时间突然发现,要一下做一个金刚不坏之身的程序是不太可能滴,至于对我来说吧。
这个程序也要经过千锤百炼才能够练就一个强大的自信心。

 

我现在做系统就不考虑一下把程序做的足够强壮了,因为我也做不到,现在做系统时,总考虑的一个问题:

当系统异常的时候怎么去处理?

 

我不怕系统程序出现异常,甚至直接Over,只要能在异常时处理异常后继续运作,在崩溃重启后能够继续把没

干的活给干了,那么这个在我能够承受的范围内,也在大多数客户的承受范围内,因为这样就是我们所说的将

损失减小到最低,其实是不是最低只有自己能够知道。

 

当然了,我更希望能够做出一个健壮无比的牛逼程序,所以我想知道程序是在什么情况下崩溃的,可是有些问题

你懂的,老在客户机器上或者生产环境下出现,却在自己的机器上和测试环境就他妈的不出现,遇见这种情况我是

跳楼或者杀人的心情都有了,偶尔我也犯过情绪,想提出辞职申请,换个行业去,告别这苦逼的程序员生涯,

可总不知道是什么力量支持着我,让我坚强依旧滴做着程序员,过着狗日的日子。

 

后来,不经意间,一位同事给我说了一个种在系统中异常或者崩溃的时候,来生成dump文件,然后用调试器来调试。

这样就可以在生产环境中的dmp文件,拷贝到自己的开发机器上,调试就可以找到错误的位置,配合程序调试符号pdb文件,

直接可以定位到源代码中位置,真是太他妈的神奇了,虽然Release版本下的很多变量的值是不对滴,但并不影响我这个

这么有执着心的coder来找bug。

 

同事给了我他写的示例,往空指针拷贝数据,在非调试下运行后,果然的崩了,果断滴生成了一个扩展名为dmp的文件,

然后他用vs2010打开那个dmp文件,vs2010很果断滴定位到了那个往空指针拷贝数据那里。

看他那娴熟的操作,顿时感觉到了他的强大和微软的牛逼。

 

后来我就学他,在程序中加入程序异常时产生dump文件的功能,待系统发布后,在一次不经意间一个程序挂掉了。

在客户的谩骂中,我面带笑容说:这个问题很好解决。我满怀信心滴从服务器上拷贝了程序崩溃产生dump文件,

然后学着那个同事用vs2010打开,我了个去,咋没有定位到源代码中内,只定位到了可执行文件的一个地址,这让哥

情何以堪呐!

 

 

还好,我对pdb了解还比较熟悉,想来应该是符号文件的问题,于是就开始摸索的,不经意见的在

堆栈处右击了下,发现菜单里竟然有“加载符号”,而且还有“符号路径”,我想这大概就是让我来选择

对应的pdb文件吧,顿时感觉曙光就在前面。

 

点击了“符号路径”后如下图:

 

才发现了,它并不是来选择符号文件,而是选择对应的可执行程序的路径,选择了后果断滴定位到了源代码的位置,

才发现一个很简单很美丽的bug,修改后,在测试后重现发布,系统的健壮性又提高了一个台阶。

 

回头想了想,我同事给我演示的时候,他程序运行的目录和就是他直接用vs2010生成的目录,所以此种情况下

用vs2010打开dmp文件即可定位到源代码文件。而发布后的程序,一般情况下你根本不知道别人放在什么地方去执行的,

因此调试时还并必须选相同版本的可执行文件,然后pdb文件才会好好工作,要不没可执行文件,咋个调试嘛。

 

哎,这同事,居然还留了一手,坑爹啊。

 

不过还是要感谢他滴,我又掌握了一些东西,又增强了我这个苦逼程序员写好程序的信心。

 

在写这个之前看了相关文章,感觉比较好的推荐一哈:

http://www.cppblog.com/woaidongmao/archive/2011/05/10/146086.html

 

 

 

 

到这里,你就可以在你的工程中通过代码的方式添加,在程序崩溃的时候回创建dump文件了;

 

 

 

 

 

 

 

 

 

.dump

 

.dump 命令创建一个用户模式或内核模式崩溃转储文件。分析工具:https://msdn.microsoft.com/en-us/library/windows/desktop/ee416349(v=vs.85).aspx#writing_a_minidump

程序崩溃(crash)的时候, 为了以后能够调试分析问题, 可以使用WinDBG要把当时程序内存空间数据都保存下来,生成的文件称为dump 文件。 步骤:

1) 打开WinDBG并将之Attach 到crash的程序进程

2) 输入产生dump 文件的命令

直接用.dump -?可以看到它的简单说明:

[cpp] view plaincopy

  1. 0:000> .dump -?  
  2. Usage: .dump [options] filename  
  3. Options are:  
  4.   /a - Create dumps for all processes (requires -u)  
  5.   /b[a] - Package dump in a CAB and delete dump  
  6.   /c <comment> - Add a comment (not supported in all formats)  
  7.   /j <addr> - Provide a JIT_DEBUG_INFO address  
  8.   /f - Create a legacy style full dump  
  9.   /m[acdfFhiprRtuw] - Create a minidump (default)  
  10.   /o - Overwrite any existing file  
  11.   /u - Append unique identifier to dump name  

 

/o :覆盖具有相同名字的dump文件。如果没有使用该选项又存在一个相同名字的文件,则dump文件不会被写入:比如我的C盘原有一个myapp.dmp文件:

[cpp] view plaincopy

  1. 0:000> .dump c:/myapp.dmp  
  2. Unable to create file 'c:/myapp.dmp' - Win32 error 0n80  
  3.     "文件存在。"  
  4. 0:000> .dump /o c:/myapp.dmp  
  5. Creating c:/myapp.dmp - mini user dump  
  6. Dump successfully written  

/f (用户模式:) 创建一个完整用户模式dump,这里要注意不要字面理解,

完整用户模式dump是基本的用户模式dump文件。这种dump文件包含进程的完整内存空间、程序本身的可执行映像、句柄表和其他对调试器有用的信息

注意 和名字无关,最大的"minidump"文件实际上可以提供比完整用户模式dump更多的信息。例如,.dump /mf.dump /ma将创建比.dump /f更大更完整的文件。

用户模式下,使用.dump /m[MiniOptions] 是最好的选择。通过这个开关创建的dump文件可以很小也可以很大。通过指定合适的MiniOptions 可以控制究竟需要包含哪些信息。

 

[cpp] view plaincopy

  1. 0:000> .dump /o/f c:/myapp.dmp  
  2. *****************************************************************************  
  3. * .dump /ma is the recommend method of creating a complete memory dump      *  
  4. * of a user mode process.                                                   *  
  5. *****************************************************************************  
  6. Creating c:/myapp.dmp - user full dump  
  7. Dump successfully written  


我们看到了,系统给出了提示:.dump /ma是创建完整dump的推荐方式(用户模式下)

/m[MiniOptions] 创建一个小内存dump(内核模式)或者 minidump (用户模式)。如果没有指定 /f /m ,/m 是默认选项。

用户模式下,/m 后面可以跟附加的MiniOptions 用来指定dump文件中包含的数据。如果没有使用MiniOptions ,dump文件包含模块、线程和调用堆栈信息,但是没有其他附加信息

MiniOption作用
a创建一个包含所有附加选项的minidump。/ma选项相当于/mfFhut —它会在minidump中添加完整的内存数据、句柄数据、已卸载模块信息、基本内存信息和线程时间信息。
f在minidump中包含完整内存数据。目标程序拥有的所有 可访问的已交付的页面(committed pages)都会包含进去。
F在minidump中添加所有基本内存信息。这会将一个流加入到包含完整基本内存信息的minidump中,而不单是可使用的内存。这样可以使得调试器能够重建minidump生成时进程的完整虚拟内存布局。
h在minidump中包含和目标进程相关的句柄信息。
u在minidump中包含已卸载模块信息。仅在Windows Server 2003和之后版本的Windows中可用。
t在minidump中包含附加的线程信息。包括可以在调试minidump时使用!runaway扩展命令或.ttime (Display Thread Times)命令进行显示的线程时间。
i在minidump中包含次级内存(secondary memory)。次级内存是由堆栈中的指针或备份存储(backing store)中引用到的任何内存,加上该地址周围的一小段区域。
p在minidump中包含进程环境块(PEB)和线程环境块(TEB)。这在想访问程序的进程和线程相关的Windows系统信息时很有用。
w将所有已交付的可读写的私有页面包含进minidump。
d在minidump中包含可执行映像中所有可读写的数据段。
c加入映像中的代码段。
r从minidump中去掉对重建调用堆栈无用的堆栈和存储内存部分。局部变量和其他数据类型值也被删除。这个选项不会使得minidump变小(因为这些内存节仅仅是变成0),但是当想保护其他程序中的机密信息时有用。
R在minidump中去掉完整的模块路径。仅包含模块名。如果想保护用户的目录结构时该选项有用。

选项(1): /m

命令行示例:.dump /m C:/dumps/myapp.dmp

注解: 缺省选项,生成标准的minidump, 转储文件通常较小,便于在网络上通过邮件或其他方式传输。 这种文件的信息量较少,只包含系统信息、加载的模块(DLL)信息、 进程信息和线程信息。

选项(2): /ma

命令行示例:.dump /ma C:/dumps/myapp.dmp

注解: 带有尽量多选项的minidump(包括完整的内存内容、句柄、未加载的模块,等等),文件很大,如果条件允许(本机调试,局域网环境), 推荐使用这中dump。

选项(3):/mFhutwd

命令行示例:.dump /mFhutwd C:/dumps/myapp.dmp

注解:带有数据段、非共享的读/写内存页和其他有用的信息的minidump。包含了通过minidump能够得到的最多的信息。是一种折中方案。

Fhutwd按字母对应上面的MiniOptions表示

 

//-xp自动生成dump-----------------------------------------------------------------------------------------------------------------------------------------------------------------

那怎么自动生成dump文件呢,比如对方的电脑没有windbg,这里用到一个window XP系统自带工具,Dr.Watson

运行方式很简单:

直接run-输入drwtsn32 -i就可以了,会提示这样的:

 

这个命令真难记,实话,记华生医生吧,福尔摩斯中的

如果有程序崩溃,会自动生成dump,这时再输入drwtsn32就会运行这个程序:

 

找到对应路径的DMP文件就行了,一般放在如下路径:
C:\Documents and Settings\All Users\Application Data\Microsoft\Dr Watson

 

 //-win7自动生成dump-----------------------------------------------------------------------------------------------------------------------------------------------------------------

win7下需打开regedit--> 找到:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting]

在它下面加一项LocalDumps,并做如下项配置:

 

Value描述Type默认值
DumpFolder文件保存路径REG_EXPAND_SZ%LOCALAPPDATA%CrashDumps
DumpCountdump文件的最大数目REG_DWORD10
DumpType指定生成的dump类型:
0:Custom dump
1:Mini dump
2:Full dump
REG_DWORD1
CustomDumpFlags仅在DumpType为0时使用
为MINIDUMP_TYPE的组合
REG_DWORD
MiniDumpWithDataSegs|
MiniDumpWithUnloadedModules|
MiniDumpWithProcessThreadData



 

 

 

 

 

 

 

 

可以写成.bat:

 

[cpp] view plaincopy

  1. @echo off  
  2. echo 设置Dump...  
  3. reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps"  
  4. reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpFolder /t REG_EXPAND_SZ /d "C:\MyDump" /f  
  5. reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpType /t REG_DWORD /d 2 /f  
  6. reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpCount /t REG_DWORD /d 10 /f  
  7. echo Dump已经设置  
  8. pause  
  9. @echo on  

[cpp] view plaincopy

  1. @echo off  
  2. echo 正在取消设置Dump...  
  3. reg delete "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /f  
  4. echo Dump已经取消设置  
  5. pause  
  6. @echo on  

 

LocalDumps是全局的,如果想针对指定进程单独设置,如test1.exe,则在/LocalDumps下新建子项test1.exe,同时在test1目录下复制上表的选项,这样,系统就会先读全局设置,再读子项test1.exe的设置

简单测试:

void CtMFC5Dlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
char * pstr = NULL;

int n = strlen( pstr );

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

在Windows 7上可以由多个方法产生dump文件:

转一篇文章:

Windows调试 - 如何使用dump文件

 

 

如何使用dump文件

我最近在开发一个windows下的程序(win7/win8),有一些case下会crash,如果在自己开发机器上调试比较简单:运行程序,然后vs attach到进程上即可,但是在每台QA的机器上安装vs时不现实的,因此我们要用到dump文件。

微软网站有一篇文章讲述如何创建dump文件:

http://support.microsoft.com/kb/931673

第一种: 通过任务管理器:这种适用在程序挂了(crash)的时候进程还未退出,比如我运行程序,出现了下面的错:

此时打开任务管理器,右击相应进程,点击"Create Dump File“:

一会创建完成:

然后把这个DMP文件拷到开发机器上,用VS打开: 会出现下面的界面,要想知道发生错误时候的调用栈,需要设置symbol的路径,点击”Set Symbol Paths“:

注意这个pdb要对应于crash的exe,否则调用栈没法显示:

设置完成后,点击”Debug with Native Only“ 你就可以看到调用栈了。

 

第二种: 改注册表

如果程序crash的时候没有框蹦出来,可以通过改注册表的设置让操作系统在程序crash的时候自动生成dump,并放到特定的目录下

 

[plain] view plaincopy

  1. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps  
  2. Value Name = DumpType  
  3. Data type: REG_DWORD  
  4. Value Data = 1  


其中Value Data=1代表的含义是:

 

 

[plain] view plaincopy

  1. 0 = Create a custom dump  
  2. 1 = Mini dump  
  3. 2 = Full dump  


设置完成后,crash发生时,操作系统生成dump,路径在%LOCALAPPDATA%\CrashDumps下,详细可以参考:

 

http://msdn.microsoft.com/en-us/library/bb787181%28v=VS.85%29.aspx

(完)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

这里再介绍一个dump工具:

procdump.exe / procdump64.exe; 

通过命令行执行,这里简化,写到bat文件中;

 

procdump.exe -l -ma -b -e -t -n 1 36280 -o ./testtestdump.dump

36280 :指的是 进程的PID,可以从人物管理器获取;

更多参数,可以直接cmd运行procdump.exe查看;

 

这里要说明一个问题,这个产生的dmp文件,在VS2017中调试的时候,定位不准确,但是我已经将pdb文件路径设置了;

不过用windbg.exe,可以很好的定位;

 

 

 

 

《windgb的简单应用》  定位,和信息更清楚;

简单说明:

1:设置pdb文件路径:File -》 Symbol file path...

2:File -》Open Crash Dump

3:等待加载完成后,执行命令:

      !analyze -v // 详细显示当前异常信息

4:查看输出信息;

5:View -》 Call Stack

6:双击可以直接定位源代码文件,所以,前面不需要设置源文件路径;

 

windgb命令:

!analyze -v // 详细显示当前异常信息

!peb // 格式化输出PEB信息(process's environment block)

!gle  // 打印当前线程最近的错误信息

!gle -all  // 打印所有线程的最近的错误信息

!error  897// 显示错误码为897的详细描述信息

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

dump文件,windbg 的相关文章

  • Debugdiag 显示“Microsoft VC 运行时堆”使用超过 1GB

    您好 我的 WPF 应用程序存在泄漏 我正在尝试使用内存转储文件来查找问题所在 使用 WinDbg 和 SOS 我找不到任何可疑的东西 然后我尝试了 DebugDiag 我得到了Microsoft VC 运行时堆 私有 有 1 42 GB
  • !address -summary 和 !heap -s 在内存泄漏问题上存在分歧?

    我有一个 32 GB 的转储文件 address summary显示堆使用量为 32 033 Gb 但是 heap s将所有堆显示为小堆 2MB 或更小 关于下面显示的两个命令之间的差异有什么想法吗 附 Windbg版本6 3 9600 1
  • Windbg内存映射?

    如何在 Windbg 中获得类似于 Ollydbg 内存映射功能的内存映射 我想查看按顺序显示加载到每个范围的内容的地址空间列表 最好带有指示的内存保护 这是 Ollydbg 内存映射的屏幕截图 address准确显示此信息 它可以在用户模
  • 从 DB2 转储 SQL

    我正在尝试将一台 IBM DB2 UDB 服务器中特定模式的内容转储到 sql 文本文件中 很像 mysql 的 mysqldump 功能 我遇到了 db2look 但它只转储模式的结构 只有 ddl 没有 dml 那么我怎样才能完成我的事
  • 在windbg中调试.Net字符串值

    我有一个 Net 应用程序转储 它捕获了一个异常 我正在使用 Windbg 进行分析 并对其中一种方法的 String 参数的值感兴趣 我已经隔离了 String 对象 我的windbg工作是 0 000 gt loadby sos msc
  • 如何调试在客户计算机上崩溃的 Windows 应用商店应用程序?

    我收到一位客户的支持电子邮件 说他的应用程序在启动时崩溃 他收到的只是一条类似以下的消息 应用程序名称 遇到问题您可以向 Microsoft 发送有关以下内容的信息 出了什么问题来帮助改进这个应用程序 将发送给 Microsoft 的文件
  • 您最喜欢的 Windbg 提示/技巧是什么? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 从 sql 文件恢复单个表转储

    我有 sql 文件的完整转储 例如dump full sql尺寸的1 3GB 它有一些像这样的表 dancing core spice dancing sea beast forde clear one forde super now 现在
  • WinDbg——TraceListener 和饱和线程池

    我有一个多线程 NET Windows 服务 它间歇性地挂起 可能每两周 24 7 运行一次 当发生挂起时 线程池完全饱和 因为对我们的自定义跟踪侦听器的调用由于某种原因开始阻塞 根据 Windbg 的说法 有问题的代码中没有任何锁 也没有
  • Windbg lm:“延迟”是什么意思?

    我正在 WinDbg 中调试 NET 2 0 程序集的故障转储文件 当我在 WinDbg 中输入 lm 时 我会得到一长串已加载的模块 如下所示 723c0000 72950000 mscorwks deferred 这里的 延期 是什么意
  • 没有 JDK 的 JRE 6 (Windows) 上的堆转储

    有没有办法在没有安装 JDK 的远程计算机上创建堆转储 我无法更改安装 设置 并且它在 Windows 上运行 所以我可以随时访问命令行工具 问题是远程计算机上的 Java 应用程序冻结 没有内存不足异常 因此 XX HeapDumpOnO
  • Windbg !address 输出中的 是什么意思

    Example 0 074 gt address summary Usage Summary RgnCount Total Size ofBusy ofTotal Free 90919 7ec 34659000 7 923 Tb 99 03
  • 什么是“异步固定句柄”?

    我正在尝试调查一个非常严重的软件崩溃 这可能与托管堆损坏有关 因为它发生在垃圾收集期间 将 WinDbg 与 SOS gchandles 命令一起使用 我得到类似的信息 0 000 gt gchandles GC Handle Statis
  • mongodump 失败'locale::facet::_S_create_c_locale 名称无效'

    当我尝试使用以下命令创建 mongodb 转储时 mongodump d mydb it fails terminate called after throwing an instance of std runtime error what
  • WinDbg:APPLICATION_HANG_WRONG_SYMBOLS

    我对 WinDbg 还很陌生 我正在尝试找到一个导致我的应用程序无缘无故挂起的错误 我不确定我做的事情是否正确 但我知道我需要系统 dll 以及我正在调试的 exe 的符号 因此 我这样设置符号路径 srv c websymbols htt
  • 什么是 ntdll.dll!RcConsolidateFrames?

    我的转储文件中有一个如下所示的调用堆栈 我想在调用堆栈中找到我的代码 但找不到 分析我的转储的起点是什么 我的程序的链接选项是release Od msvcr120 dll abort msvcr120 dll terminate msvc
  • 分析 Windbg 中的故障转储

    我正在使用第三方闭源 API 它会抛出一个异常 指出 所有命名管道都忙 我想进一步调试 而不是单步调试 这样我就可以真正了解幕后发生的事情 我使用 WinDbg 转储了这个过程 我现在应该使用什么命令来分析此转储 Thanks 您可以开始执
  • 分析 Windbg 中 !threadpool 和 !threads 的输出

    我已经在四台服务器上生成了转储 并正在分析 threadpool 和 threads 的输出 我注意到以下输出大致一致 0 024 gt threadpool CPU utilization 0 Worker Thread Total 2
  • 使用 Windbg 进行关键部分挂起分析

    最近 当我的应用程序一段时间没有响应时 我通过 procdump 生成了一个转储文件 当我在转储文件上运行 locks 时 我得到一个单独的条目 如下所示 0 000 gt locks CritSec 123456 at 00123456
  • 生成转储并导致非托管代码崩溃?

    当我的应用程序突然崩溃时 有没有办法获得完整的故障转储 问题是 我怀疑这是由于非托管代码杀死了 net 框架本身 因此 除非在崩溃时应用程序附加了调试器 否则应用程序甚至没有机会处理崩溃 我无法附加调试器并等待 因为崩溃是随机发生的 而且我

随机推荐

  • 聚合类新闻客户端的改进

    zaker和鲜果是最早的聚合类新闻产品 xff0c 前几年发展很快 xff0c 迅速占领了市场 xff0c 但近两年发展变得缓慢 xff0c 而今日头条自发布以来才两年 xff0c 用户量就迅速超过了zaker和鲜果 xff0c 使用起来非
  • 单例模式优缺点

    主要优点 xff1a 1 提供了对唯一实例的受控访问 2 由于在系统内存中只存在一个对象 xff0c 因此可以节约系统资源 xff0c 对于一些需要频繁创建和销毁的对象单例模式无疑可以提高系统的性能 3 允许可变数目的实例 主要缺点 xff
  • 适配器模式优缺点

    优点 xff1a 1 将目标类和适配者类解耦 2 增加了类的透明性和复用性 xff0c 将具体的实现封装在适配者类中 xff0c 对于客户端类来说是透明的 xff0c 而且提高了适配者的复用性 3 灵活性和扩展性都非常好 xff0c 符合开
  • Oracle 的 Round函数

    Round函数用法 xff1a 截取数字 格式如下 xff1a ROUND xff08 number decimals xff09 其中 xff1a number 待做截取处理的数值 decimals 指明需保留小数点后面的位数 可选项 x
  • eclipse报错:Failed to load the JNI shared library

    电脑自装系统以来 xff0c 好久没有写java代码了 xff0c 所以一直也没用 eclipse IDE xff0c 今天将eclipse打开 xff0c 报了个问题 xff0c Failed to load the JNI shared
  • 10串口通信

    51单片机学习记录10 通信通信的的基本概念串口参数及时序图常用通信接口比较 51单片机串口介绍串口通信简介串口内部结构串口通信相关寄存器 串口通信实验串口向计算机发送数据计算机通过串口控制LED 通信 通信的的基本概念 通信的方式 通信方
  • 【已解决】zookeeper配置出现问题合集

    已解决 zookeeper配置出现问题合集 1 问题诊断 日志2 问题解决合集2 1zookeeper集群搭建报错 拒绝连接 2 2zookeeper集群搭建报错 没有找到主机路由 1 问题诊断 日志 1 进入文件查看日志 xff1a zo
  • noVNC 安装、配置与使用

    最近项目中使用到了远程终端操控 xff0c 从各方找到了noVNC这个神奇的家伙 xff0c 废话不多说 xff0c 开始介绍它的安装配置与使用 1 下载noNVC 好多渠道可以下载到noVNC xff0c 可以直接访问noVNC的官方网页
  • 360极速浏览器网页保护色

    方法一 xff1a 360浏览器的 扩展中心 有一个 绿色眼睛 的插件 xff1b 但是感觉一般 xff0c 不够彻底 xff1b 方法二 xff1a 360急速浏览器是基于开源Chrome浏览器修改的 xff0c 所以可以直接用Chrom
  • STM32基于FreeRTOS的多任务程序案例

    STM32基于FreeRTOS的多任务程序案例 一 初步了解FreeRTOS二 实验要求三 基于FreeRTOS的多任务程序案例四 参考链接 使用工具 野火stm32mini开发板 Keil uVision5 野火多功能调试助手 一 初步了
  • 【TcaplusDB知识库】TcaplusDB刷新tbus通道介绍

    命令 xff1a RefreshBusCfg 其中 xff0c 指进程的进程id xff0c 比如1 2 2 2 1 2 1 2等 xff0c 也支持简单的正则表达式 xff0c 比如RefreshBusCfg 1 2 2 那么只要匹配到1
  • Python中下划线的5种含义

    作者 xff1a 地球的外星人君 链接 xff1a https zhuanlan zhihu com p 36173202 来源 xff1a 知乎 著作权归作者所有 商业转载请联系作者获得授权 xff0c 非商业转载请注明出处 分享一篇文章
  • ubuntu下 安装PX4编译环境

    最近博主的ubuntu虚拟机再次崩溃 xff0c 狠下决心将4G内存升级为12G 这样就可以给虚拟机多分配些内存了 鉴于前两次安装PX4环境出现了很多错误 xff0c 走了很多弯路 xff0c 没有一一记录下来 xff0c 所获甚少 故而借
  • PX4原生固件,position_estimator_inav解读

    INAV integrated navigation组合导航 对于多旋翼的位置姿态估计系统 xff1a PX4原生固件如今已经默认使用EKF2了 xff0c 另一种情况是 使用local position estimator attitud
  • FusionCharts Free (FCF) 版本 v3.0 更新细节

    版本 v3 0 更新细节 1 新的图表类型 滚动图 柱二维 xff0c 二维和区系的二维 xff0c 堆栈柱二维 xff0c 二维结合 xff0c 结合二维 xff08 双 Y 轴 xff09 样图 样条区域图 对数坐标图 二维多图单 组合
  • dwm-1000 测距总是出现 #define SYS_STATUS_RXPTO 0x00200000UL /* Preamble detection timeout */

    ex 05b ds twr resp 程序 总是出现 致使官方的代码 无法实现通讯 define SYS STATUS RXPTO 0x00200000UL Preamble detection timeout 需要着重修改参数
  • VNC远程桌面到linux,提示connection refused(10061)解决办法

    确认server端的VNC服务开启 xff0c service vncserver start xff0c 检测状态时ok的 ps ef grep vnc xff0c 来查看不是已经开启多个vnc连接 如果有多个vnc连接 xff0c 使用
  • uio驱动框架

    核心 xff0c 利用mmap进行映射 参考资料 uio 编写实例 1 https blog csdn net wujiangguizhen article details 12453253 uio编写实例 2 https blog csd
  • enum类型被intent所携带时需要注意的地方

    一般我们在Activity之间传递对象时多用Parcelable 比如写一个class xff0c 在这个class上标明implements Parcelable并实现接口就可以用Intent putExtra String Parcel
  • dump文件,windbg

    dump文件 xff0c 在VC中的调试还是非常非常非常有用的 xff0c 因为我们也不会经每一行代码都加上日志 xff0c 当然如果你愿意 xff0c 也可以每一行都加上日志 xff1b 在Windows上 xff0c 添加dump文件有