天天看點

使用C語言中的宏來定位出錯資訊

    編寫一個軟體時,軟體的健壯性時特别值得考慮的問題。使用C++時可以使用異常捕獲機制,在設計完軟體的子產品架構的時候然後再設計異常捕獲架構,一般來說需要設計一個異常捕獲網來捕獲程式中可能的異常。

    對于異常的處理,有些情況下沒有辦法實作程式的自恢複,這時候隻能無奈的輸出程式的出錯的一些資訊。在我看來,這些資訊具體又分為靜态資訊和動态資訊。靜态資訊是編譯器期間确定的一些屬性,動态期間是在運作時期間才能确定的屬性。

    例如,程式子產品a中的函數f的第l行出現錯誤,在輸出錯誤的時候我們要能夠輸出這些定位錯誤的資訊。利用C語言提供的内置宏可以得到這些資訊,常用的内置宏為:__FILE__,__LINE__,__FUNCTION__,__TIME__,分别為檔案名,行号,函數名,以及該子產品對應得源檔案被預處理器處理的時間。這些資訊都是編譯期間确定的,也就是我所說的靜态錯誤資訊。

    下面是一個例子:

    這個是頭檔案:tmp_header.h

/* 

*Author:Chaos Lee 

*Date:2012-02-26 16:52 

*/ 

#ifndef TMP_HEADER_H 

#define TMP_HEADER_H 

#include<stdio.h> 

#define MSGDEBUG fprintf(stderr,"Error Occured at:\nFile:%s\nFunction:%s\nLine:%d\nDate:%s\nTime:%s\n",__FILE__,__FUNCTION__,__LINE__,__DATE__,__TIME__); 

#endif 

     下面是源檔案:

*Date:2012-02-26 16:55 

#include"tmp_header.h" 

int main() 

    MSGDEBUG; 

    return 0; 

    輸出結果如下:

Error Occured at:  

File:tmp_test.c  

Function:main  

Line:8  

Date:Feb 26 2012  

Time:17:04:27  

   還有一種情況就是動态資訊,可以确定子產品在記憶體中的位置,這就是常見的堆棧跟蹤資訊。可以調用庫函數backtrace實作堆棧跟蹤,這個放在下一篇文章中。

   還有一個庫函數也是友善調試的,就是assert函數,下面是一個assert函數的例子。assert函數根據參數情況來決定程式的運作,如果參數判定為假或者0,将對程序發出ABORT信号,預設的情況下,程式運作結束。

*Date:2012-02-26 10:37 

#include<assert.h>  //for assert 

#include<signal.h>  //for signal 

void sig_abrt(int signo) 

    printf("signal 'Aborted' catched.\n"); 

void installSignalHandler() 

    signal(SIGABRT,sig_abrt); 

    int input=1; 

    installSignalHandler(); 

    while(input) 

    { 

        scanf("%d",&input); 

        assert(input); 

        printf("you have entered:%d\n",input); 

    } 

    程式運作結果如下:

32 

you have entered:32 

54 

you have entered:54 

assert_test: assert_test.c:23: main: Assertion `input' failed. 

signal 'Aborted' catched. 

Abort 

本文轉自hipercomer 51CTO部落格,原文連結:http://blog.51cto.com/hipercomer/790175

繼續閱讀