軟體崩潰後相關資訊儲存
簡介:
現在我們的服務端程式在崩潰後,雖然記錄了相關的堆棧資訊,但是記錄的崩潰位置是可執行檔中的絕對位址,需要用相關的軟體載入對應的.map檔案來分析,得到代碼中的崩潰位置.如果程式在崩潰時可以自動儲存崩潰點在代碼中的位置,記在log中,那麼分析起來會方便很多.尤其如果記錄的log量多一些的時候.
Codeproject上有一個名為blackbox的動態連結程式庫,該庫的作用就是在程式崩潰時自動儲存現場的一切有用資訊,比如,堆棧;寄存器;當時的cpu使用;記憶體使用量;當時存在的其他進程;電腦的物理資訊等.
某種應用如果用在我們的伺服器端,大量修改代碼是不現實的,最好的情況是不需要改動現有代碼,如果必要,也只改動幾行代碼.blackbox提供的使用方式極為簡單,只需要在程式啟動時載入該動態連結程式庫就可以了,如果一旦程式崩潰了,blackbox就會彈出自己的視窗:
圖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後,程式可以繼續運行。