首页
社区
课程
招聘
[原创]在程序崩溃后用于打印出错环境的一个C++类
发表于: 2009-2-24 14:23 5965

[原创]在程序崩溃后用于打印出错环境的一个C++类

2009-2-24 14:23
5965

在程序崩溃后用于打印出错环境的一个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同目录下就可以。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 7
支持
分享
最新回复 (2)
雪    币: 437
活跃值: (273)
能力值: ( LV12,RANK:240 )
在线值:
发帖
回帖
粉丝
2
delphi 有这个 http://www.2ccc.com/article.asp?articleid=4648  

MadCollection,是一款集成在 Delphi (D5, D6, D7, D8, D9, BDS2006, D2007) IDE 下的辅助工具,能快速生成带 Error Report 功能的应用程序。能将错误报告发送到指定邮箱、服务器、记录在本地文件中等。其报告可具体指出出错的代码行,以及机器当前信息、寄存器信息等诸多重要诊断信息。还可以完全自定义出错后的界面。
2009-2-24 15:08
0
雪    币: 241
活跃值: (21)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
我用过EurekaLog
类似功能。
因为某些原因,我做的东西不能用这些。
所以就自己写了。
再考虑到用Borland Debug Hook库的代码网上很少,就帖了出来。
2009-2-24 16:29
0
游客
登录 | 注册 方可回帖
返回
//