博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

软件崩溃后相关信息保存

Posted on 2011-05-26 17:52  浪端之渡鸟  阅读(495)  评论(1编辑  收藏  举报

软件崩溃后相关信息保存 
简介: 

现在我们的服务端程序在崩溃后,虽然记录了相关的堆栈信息,但是记录的崩溃位置是可执行文件中的绝对地址,需要用相关的软件加载对应的.map文件来分析,得到代码中的崩溃位置.如果程序在崩溃时可以自动保存崩溃点在代码中的位置,记在log中,那么分析起来会方便很多.尤其如果记录的log量多一些的时候. 
Codeproject上有一个名为blackbox的动态链接库,该库的作用就是在程序崩溃时自动保存现场的一切有用信息,比如,堆栈;寄存器;当时的cpu使用;内存使用;当时存在的其他进程;计算机的物理信息等. 
某种应用如果用在我们的服务器端,大量修改代码是不现实的,最好的情况是不需要改动现有代码,如果必要,也只改动几行代码.blackbox提供的使用方式极为简单,只需要在程序启动时加载该动态链接库就可以了,如果一旦程序崩溃了,blackbox就会弹出自己的窗口: 

图1图1

 

 

 

 

 

 

 

 

 


使用: 
如介绍中所说,该库的使用非常方便,一切对宿主程序来说都是透明的,程序只需要在开始的时候: 
HINSTANCE hLib = LoadLibrary( "BlackBox.dll" ); 
然后就不需要任何操作了,blackbox会在程序异常时自动工作.当然,最好在程序结束前释放它: 
if ( NULL != hLib ) 
FreeLibrary( hLib ); 
下面给出我写的一个最简单的测试代码来说明该库的工作方式: 
#include "stdafx.h" 
#include 
HINSTANCE hLib = LoadLibrary( "BlackBox.dll" ); 

class NoUse 

public: 
virtual void NoUseApi(void) 

int a=1,b=1; 
int c=100/(a-b); 

}; 

int main(int argc, char* argv[]) 

NoUse t; 
t.NoUseApi();//除0 异常 

printf("dfsdfsdfsdf"); 

if ( NULL != hLib ) { 
FreeLibrary( hLib ); 


return 0; 

示例非常简单,黄色部分是blackbox的加载与释放,实际上加载可以放在任何地方,当然越早越好,这样可以跑在异常发生之前;红色部分实现了一个简单的除0异常.也可以实验任何其他异常.程序启动后就会弹出如上图所示的界面. 
缺点: 
Blackbox提供了大量的功能,包括将log信息email给开发人员等,这实际上更适合给终端程序使用,比如应用在客户端,做信息反馈用; 
因为程序在异常后会结束,而我们需要服务器持续运行,所以blackbox并不完全适合我们的服务端应用,幸运的是,该库的作者Jim Crafton提供了程序的全部源码,因此我们可以在此基础上修改,使之符合我们的需求. 

展望: 
对于改造blackbox,以下是必要的部分: 

• 精简该库,只保留最重要的堆栈信息. 
• 去掉弹出式界面,直接记log 
• 程序异常后,记log,但程序继续运行 

前两个修改比较简单,在现有代码上简单修改就可以了,至于最后一个,改动比较麻烦,但也不是不可能,我会修改后使之与服务器端basecod中DEBUG_TRY,DEBUG_CATCH相结合,这样不用修改现有代码也可以实现崩溃位置记录功能,并且出错记log后,程序可以继续运行。