• 写一个Windows上的守护进程(7)捕获异常并生成dump


    写一个Windows上的守护进程(7)捕获异常并生成dump

    谁都不能保证自己的代码不出bug。一旦出了bug,最好是崩溃掉,这样很快就能被发现,若是不崩溃,只是业务处理错了,就麻烦了,可能很长时间之后才能被发现。

    那么如果崩溃掉,怎么查错呢?

    写过Windows驱动的同学应该知道,一旦崩溃,系统会生成dump文件,然后就可以根据dump文件、pdb文件、源码用windbg分析了。应用层的程序同样可以在崩溃的时候生成dump文件,只是没人帮你完成这个步骤,得自己动手。

    1. API

    这里涉及到的主要API就一个:MiniDumpWriteDump——生成dump文件,我说再多也没有官方权威,所以要看详情,还是请移步MSDN。其它辅助API就是设置异常处理器的函数,此处不介绍。

    2. 异常类型

    读过《Windows核心编程》的同学应该知道SEH——Windows结构化异常处理,当时我读了之后,就以为所有的异常都是在SEH体系内的,还接着“以为”了很多年。后来发现并不是:因为我写的捕获异常并生成dump文件的库并没有发挥应有的作用,该崩溃的地方还是崩溃了并且没有生成dump文件!

    google后发现了这么一篇文章:http://www.codeproject.com/Articles/207464/Exception-Handling-in-Visual-Cplusplus

    我总结一下:Windows下并非所有的异常都走SEH体系,还有CRT错误处理体系;也并不是只有异常才会导致程序退出,接收到Windows支持的几个信号也会导致程序退出,比如SIGABRT等等;有的“异常”处理器不是针对进程的,而只对当前线程有效,必须每个线程都设置处理器。

    所以,要想捕获所有的“异常”,就得:

    l 调用SetUnhandledExceptionFilter设置SEH异常处理函数

    l 调用_set_purecall_handler设置处理纯虚函数调用导致的错误的处理函数

    l 调用_set_new_handler设置new失败导致的错误的处理函数

    l 调用_set_invalid_parameter_handler设置无效参数导致的错误的处理函数

    l 调用signal设置信号SIGABRT、SIGINT、SIGTERM的处理函数

    l 调用set_terminate设置terminate处理函数。这个只对当前线程有效

    l 调用set_unexpected设置unexpected处理函数。这个也是只对当前线程有效

    l 调用signal设置信号SIGFPE、SIGILL、SIGSEGV的处理函数。这个也是对当前线程有效

    3. 异常信息获取

    MiniDumpWriteDump 的ExceptionParam需要填充上异常信息,那么如何填充呢?

    上面那篇文章已经指出了方法:用vc源码文件invarg.c中函数_invoke_watson的代码。

    他代码中用的是vc8.0的源码,我是用vc2008编译的,所以就取的vc2008的源码,但是好像不用在意取哪个vc版本的源码。

    4. 调试dump文件

    我把生成的dump文件放在了应用程序所在目录,这样一眼就可以看出程序有没有崩溃过。一旦生成了dump文件,我们只要把二进制、pdb文件、dump文件放在一起,然后用vs打开dump文件,直接运行就可以调试了。(所以我们提交二进制的时候要把pdb也一同提交。)

    我修改了下上面文章中的源码,封装成了两个函数,把我用它的测试代码测试的结果写在了代码中。

    我的使用:main函数起来后,设置所有处理函数;在每个任务线程设置线程相关的处理函数。

    源码:https://git.oschina.net/mkdym/DaemonSvc.git (主)&& https://github.com/mkdym/DaemonSvc.git (提升逼格用的)。

    2015年11月10日星期二

  • 相关阅读:
    sql对日期操作
    computeroperationcommand
    Convert函数对日期的应用
    编写快速、高效的JavaScript代码
    vim常用操作技巧与配置
    PureFTPd安装配置
    关于PHP代码加密和文本加密
    父页面调用iframe里的js函数相关例程,Iframe之间通讯研究
    常用JavaScript语法100讲
    计算机端口
  • 原文地址:https://www.cnblogs.com/mkdym/p/4953603.html
Copyright © 2020-2023  润新知