在程序崩溃后用于打印出错环境的一个C++类,使用它在程序出错后更快得找出出错的位置和原因。
打印内容的一个例子
----------------------------------------------------------------------------
System details:
-----------
Operating System:      Microsoft Windows XP Professional (Version 5.1, Build 2600)
CPU Information: Type: Intel Pentium compatible, Number Of Processors: 2, Architecture: Intel, Level: Unknown 15, Stepping: 10-25
Memory Information:    Memory Used 72%, Total Physical Memory 1048048KB, Physical Memory Available 286664KB, Total Virtual Memory 2097024KB, Available Virtual Memory 2054620KB, Working Set Min: 200KB Max: 1380KB .

Process details:
-----------
线程数:1, 句柄数:22
内存使用(K):3540, 内存使用峰值(K):3540, 页面缓冲池(K):20, 页面缓冲池峰值(K):20, 非页面缓冲池(K):2
非页面缓冲池峰值(K):2, 虚拟内存(K):3052, 虚拟内存峰值(K):3052, 页面错误:883

Exception details:
-----------
FirstChance:00000001, ExceptionCode:C0000005, ExceptionFlags:00000000, ExceptionAddress:004014B9
ExceptRem: STATUS_ACCESS_VIOLATION
Module: G:\testdump1.exe, Section: 01, Offset: 000004B9

Context details:
-----------
EFlags:00010206
EIP:004014B9
Ebp:0012FEF4
Esp:0012FEDC
Edi:00000000
Esi:0041A028
Ebx:7FFDE000
Edx:00000000
Ecx:00000009
Eax:00000009

Call stack:
-----------
Address   Frame     Function   SourceFile
004014B9  0012FEF4  testexp1+49  testdump1.cpp line 37
  Parameter struct TestClass* _pclass = {struct TestBaseClass = {char Memchar = 52, }, int Mem1 = 2, int Mem2 = 8, struct TestClass* Mem3 = [0x00000000], }
  Parameter int* _pint = [0x00000000]
  Parameter int _int = 79
  Local double t_double = 79.000000
  Local char* t_pchar = "787878789"
  Local int** t_ppint = [0x0012FF00]
  Local enum TEnum t_Enum = 2
  Local int t_Tmpint2 = 9

00401516  0012FF8C  main+56  testdump1.cpp line 53
  Parameter int argc = 1
  Parameter char** argv = [0x00F4A680]
  Local int t_int = 78
  Local int* t_pint = [0x00000000]
  Local struct TestClass t_class = {struct TestBaseClass = {char Memchar = 52, }, int Mem1 = 2, int Mem2 = 8, struct TestClass* Mem3 = [0x00000000], }
  Local char[60] command = ""

00414D83  0012FFB8  __startup+16F

Assembler Information:
-----------
testdump1.cpp
-------Line 25---------
00401470  push    ebp
00401471  mov     ebp, esp
00401473  add     esp, -18
-------Line 27---------
00401476  mov     dword ptr [ebp-4], 2
-------Line 29---------
0040147D  mov     eax, [ebp+8]
00401480  mov     edx, [ebp-4]
00401483  mov     [eax+4], edx
-------Line 31---------
00401486  lea     ecx, [ebp+C]
00401489  mov     [ebp-8], ecx
-------Line 32---------
0040148C  mov     dword ptr [ebp-C], 41A0C0
-------Line 33---------
00401493  fild    dword ptr [41A0B8]
00401499  fstp    qword ptr [ebp-14]
-------Line 34---------
0040149C  fld     qword ptr [ebp-14]
0040149F  call    00411FD0
004014A4  mov     [ebp+10], eax
-------Line 36---------
004014A7  push    dword ptr [ebp-C]
004014AA  call    0040C740
004014AF  pop     ecx
004014B0  mov     [ebp-18], eax
-------Line 37---------
004014B3  mov     edx, [ebp+C]
004014B6  mov     ecx, [ebp-18]
004014B9  mov     [edx], ecx  ; <-- EXCEPTION
-------Line 39---------
004014BB  mov     esp, ebp
004014BD  pop     ebp
004014BE  retn
------------------------用来产生异常的代码-----------------------------
int g_int = 0;
struct TestBaseClass
{
public:
  char Memchar;
};
struct TestClass: public TestBaseClass
{
public:
    int Mem1;
    int Mem2;
  TestClass* Mem3;
};
enum TEnum
{
  EnumIdx1 = 1,
  EnumIdx2 = 2,
};
void testexp1(TestClass* _pclass, int* _pint, int _int)
{
  TEnum t_Enum = EnumIdx2;
  {
    _pclass->Mem1 = t_Enum;
  }
  int** t_ppint = &_pint;
  char* t_pchar = "787878789";
  double t_double = g_int;
  _int = t_double;
  {
    int t_Tmpint2 = strlen(t_pchar);
    *_pint = t_Tmpint2;
  }
}
int _tmain(int argc, _TCHAR* argv[])
{
    char command[60];
    gets(command);
    TestClass t_class;
    t_class.Mem1 = 7;
    t_class.Mem2 = 8;
    t_class.Mem3 = NULL;
    int* t_pint = NULL;
    int t_int = 78;
  g_int = 79;
    __try
    {
        testexp1(&t_class, t_pint, t_int);
    }
    __except(1)
    {
        t_int++;
    }
    return 0;
}
----------------------------------------------------------------------------------------
主要用到的库有MS的DBGHELP库,Borland的Borland Debug Hook库.
前者网上的资料不少,但是后者网上基本找不到范例。
反汇编用的是OD主页上提供的反汇编引擎。

使用方法:需要在程序里自己写代码SetUnhandledExceptionFilter。然后使用这个类。
支持MS的PDB符号表和Borland的TDS符号表。把符号表文件放在EXE同目录下就可以。

上传的附件 Minidump.rar