zoukankan      html  css  js  c++  java
  • C++记录程序崩溃时的dumpfile

       最近一段时间,新上线的软件在外场偶尔会出现异常崩溃的情况。由于试用范围比较分散,很难一一前往现场定位问题。而传统的log日志方法,在崩溃的情况下,并不能比较准确的表示出问题位置,这使得软件调试进程缓慢。

       后在公司前辈的指点下,我们想到了使用window自带的dumpfile来记录崩溃时刻的堆栈信息,这样配合log日志记录,能够快速的定位出问题点。大大提高了系统调试效率。

       经过一段时间的调试,现在项目已相对稳定了。想记录下此方法,以待后续类似情况下使用。

    1. //使所有版本都可以捕获到异常 
    2. void DisableSetUnhandledExceptionFilter() 
    3.     void *addr = (void*)GetProcAddress(LoadLibrary(_T("kernel32.dll")), "SetUnhandledExceptionFilter"); 
    4.  
    5.     if (addr)  
    6.     { 
    7.         unsigned char code[16]; 
    8.         int size = 0; 
    9.         code[size++] = 0x33; 
    10.         code[size++] = 0xC0; 
    11.         code[size++] = 0xC2; 
    12.         code[size++] = 0x04; 
    13.         code[size++] = 0x00; 
    14.  
    15.         DWORD dwOldFlag, dwTempFlag; 
    16.         VirtualProtect(addr, size, PAGE_READWRITE, &dwOldFlag); 
    17.         WriteProcessMemory(GetCurrentProcess(), addr, code, size, NULL); 
    18.         VirtualProtect(addr, size, dwOldFlag, &dwTempFlag); 
    19.     } 
    20.  
    21. //程序未捕获的异常处理函数 
    22. LONG WINAPI ExceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo) 
    23.     ::AfxMessageBox("ExceptionFilter"); 
    24.  
    25.     HANDLE hFile = ::CreateFile( _T("C:\dumpfile.dmp"), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 
    26.     if( hFile != INVALID_HANDLE_VALUE) 
    27.     { 
    28.         MINIDUMP_EXCEPTION_INFORMATION einfo; 
    29.         einfo.ThreadId = ::GetCurrentThreadId(); 
    30.         einfo.ExceptionPointers = ExceptionInfo; 
    31.         einfo.ClientPointers = FALSE; 
    32.  
    33.         ::MiniDumpWriteDump(::GetCurrentProcess(), ::GetCurrentProcessId(), hFile, MiniDumpWithFullMemory, &einfo, NULL, NULL); 
    34.         ::CloseHandle(hFile); 
    35.     } 
    36.  
    37.     return 0; 
    38.  
    39. //把当前时刻的线程栈记录到DUMP文件中 
    40. int RecordCurStack() 
    41.     HANDLE hFile = ::CreateFile( _T("C:\dumpfile.dmp"), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 
    42.     if( hFile != INVALID_HANDLE_VALUE) 
    43.     { 
    44.         ::MiniDumpWriteDump(::GetCurrentProcess(), ::GetCurrentProcessId(), hFile, MiniDumpWithFullMemory  ,NULL, NULL, NULL); 
    45.  
    46.         ::CloseHandle(hFile); 
    47.         return 1; 
    48.     } 
    49.  
    50.     return 0; 
    51.  
    52.  
    53. bool bCreateDumpThrd = true; 
    54. //循环检测线程 
    55. //查看到有ADTV2_TEMP.TXT文件,则记录下当前时刻的堆栈 
    56. void CreateDumpThrd(void* pv) 
    57.     HANDLE hFile;  
    58.     string strPath = FileAssist::GetExePath() + "\ADTV2_TEMP.TXT"; 
    59.     while(bCreateDumpThrd) 
    60.     { 
    61.         //每5秒检测一次 
    62.         Sleep(5000); 
    63.         hFile = CreateFileA(strPath.c_str(),    // file to open 
    64.             GENERIC_READ,          // open for reading 
    65.             FILE_SHARE_READ,       // share for reading 
    66.             NULL,                  // default security 
    67.             OPEN_EXISTING,         // existing file only 
    68.             FILE_ATTRIBUTE_NORMAL, // normal file 
    69.             NULL);                 // no attr. template 
    70.  
    71.         if (hFile != INVALID_HANDLE_VALUE)  
    72.         {  
    73.             //防止多次记录当前堆栈信息,删除文件 
    74.             ::CloseHandle(hFile); 
    75.             ::DeleteFile(strPath.c_str()); 
    76.             RecordCurStack(); 
    77.         } 
    78.     } 

    然后在程序入口将异常处理接口声明即可。

    1. //调试信息 
    2. ::SetUnhandledExceptionFilter(ExceptionFilter); //设置异常处理函数 
    3. DisableSetUnhandledExceptionFilter();           //获取未处理的异常 

    这样,在程序异常时,就可以在C盘根目录下记录一个dumpfile.dmp的文件。这个文件会比较大,一般有100多M,其中信息比log形式的日志丰富很多,包括了异常时的堆栈调用关系以及各对象的值。,在VS中可以直接打开。如果保留了和当时编译软件一致的代码备份的话,可以直接使用VS的debug功能定位到问题代码行,否则,debug定位是到汇编代码行,看起来比较麻烦。

  • 相关阅读:
    基础数据补充
    购物车
    小数据池、深浅拷贝和集合
    列表、元组和range
    小数据池、深浅拷贝和集合练习
    字典
    字符串练习
    列表练习
    练习
    字典练习
  • 原文地址:https://www.cnblogs.com/xiangcunjiaoshi/p/12560253.html
Copyright © 2011-2022 走看看