C++随机崩溃捕捉处理

1. 会引起异常的几个原因(主要记录目前遇到过的几个问题)

  • 程序读取了无效的内存地址
  • 堆栈的溢出,比如无限循环导致那段内存溢出,比如把size为20的缓存拷贝到size为10的缓存块等
  • 无法申请到有效的内存
  • 多次删除同一块内存

2. 异常处理

2.1 SEH(Structured Exception Handling)

SEH是C语言的异常处理方法,主要使用如下方法处理异常,这个一般用于主动防御性代码中

try
{
    throw 20;
}
catch (int e)
{
    cout << "An exception occurred. Exception Nr. " << e << endl;
}

工作中我们应该会经常遇到随机,未知的异常崩溃,所以SEH提供了另一种方法处理异常

LONG WINAPI MyUnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionPtrs)
{
  // Do something, for example generate error report

  //..

  // Execute default exception handler next
  return EXCEPTION_EXECUTE_HANDLER; 
}

void main()
{ 
  SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);  //< 一定要main程序开始后就注册异常处理函数

  // .. some unsafe code here 
}

2.2 CRT Error Handling(运行时异常)

运行时发生异常时,C++会调用terminate(),所以我们可以使用set_terminate捕获异常然后进行处理

void my_terminate_handler()
{
  // Abnormal program termination (terminate() function was called)

  // Do something here

  // Finally, terminate program
  exit(1); 
}

void main()
{
  set_terminate(my_terminate_handler); //< 一定要main程序开始后就注册异常处理函数

  terminate();
}

set_terminate类似的还有set_unexpected_set_purecall_handlerSetUnhandledExceptionFilter用法和上面一样,只是针对的是各自不同的异常

2.3 通过信号量来捕捉程序的异常

void sigabrt_handler(int)
{
        // Caught SIGABRT C++ signal

        // Terminate program
        exit(1);
}

int main()
{
    signal(SIGABRT, sigabrt_handler);
}

SIGABRT是一种异常类型,总共有以下7种:

  1. SIGINT 2. SIGILL 3. SIGFPE 4. SIGSEGV 5. SIGTERM 6. SIGBREAK 7. SIGABRT

3.最后推荐一个dump日志生成库 -- google breakpad

google breakpad 是一款开源的跨平台dump日志生成库,具体使用方法请自行查阅官网说明

  • 注: 以上记录仅限于windows单线程,如果是多线程请查看各自msdn说明,其它平台紧供参考