Sunday, April 15, 2012

__FILE__,__LINE__,FUNCTION__實現代碼跟蹤調試(linux下c語言編程)

資料來源:__FILE__,__LINE__,FUNCTION__實現代碼跟蹤調試(linux下c語言編程)



先看下簡單的初始代碼:注意其編譯運行後的結果。
root@xuanfei-desktop:~/cpropram/2# cat global.h //頭文件
#ifndef GLOBAL_H
#define GLOBAL_H

#include <stdio.h>

int funca(void);
int funcb(void);

#endif
root@xuanfei-desktop:~/cpropram/2# cat funca.c //函數a
#include "global.h"

int funca(void)
{
   printf ("this is function\n");
   return 0;
}
root@xuanfei-desktop:~/cpropram/2# cat funcb.c //函數b
#include "global.h"

int funcb(void)
{
   printf ("this is function\n");
   return 0;
}
root@xuanfei-desktop:~/cpropram/2# gcc -Wall funca.c funcb.c main.c //聯合編譯
root@xuanfei-desktop:~/cpropram/2# ./a.out //運行
this is main
this is function
this is main
this is function
this is main
相同結果很難讓人看出那裡出錯,下面我們用用 __FILE__,__LINE__,__FUNCTION__加入代碼,看看有什麼區別嗎.
把 __FILE__,__LINE__,__FUNCTION__加入到mail.c中
root@xuanfei-desktop:~/cpropram/2# cat main.c
#include "global.h"

int main(int argc, char **argv)
{
   printf("%s(%d)-%s: this is main\n",__FILE__,__LINE__,__FUNCTION__);
   funca();
   printf("%s(%d)-%s: this is main\n",__FILE__,__LINE__,__FUNCTION__);
   funcb();
   printf("%s(%d)-%s: this is main\n",__FILE__,__LINE__,__FUNCTION__);
   return 0;
}
root@xuanfei-desktop:~/cpropram/2# gcc -Wall funca.c funcb.c main.c
root@xuanfei-desktop:~/cpropram/2# ./a.out
main.c(4)-main: this is main
this is function
main.c(6)-main: this is main
this is function
main.c(8)-main: this is main
上面的結果main.c(4)-main:this is main 表示在mian.c源代碼的第四行main函數裡邊打印出來的 this is main
那樣的話就很方便的讓程序員對自己的程序進行排錯!
為了更方便的使用它我們可以通過在global.h代碼中進行宏定義
root@xuanfei-desktop:~/cpropram/2# cat global.h
#ifndef GLOBAL_H
#define GLOBAL_H
#include <stdio.h>

int funca(void);
int funcb(void);

#define DEBUGFMT  "%s(%d)-%s"
#define DEBUGARGS __FILE__,__LINE__,__FUNCTION__
#endif
root@xuanfei-desktop:~/cpropram/2# cat funca.c
#include "global.h"

int funca(void)
{
   printf (DEBUGFMT " this is function\n",DEBUGARGS);
   return 0;
}
root@xuanfei-desktop:~/cpropram/2# cat funcb.c
#include "global.h"

int funcb(void)
{
   printf (DEBUGFMT " this is function\n",DEBUGARGS);
   return 0;
}
root@xuanfei-desktop:~/cpropram/2# cat main.c
#include "global.h"

int main(int argc, char **argv)
{
   printf(DEBUGFMT "this is main\n", DEBUGARGS);
   funca();
   printf(DEBUGFMT "this is main\n", DEBUGARGS);
   funcb();
   printf(DEBUGFMT "this is main\n", DEBUGARGS);
   return 0;
}
root@xuanfei-desktop:~/cpropram/2# gcc -Wall funca.c funcb.c main.c
root@xuanfei-desktop:~/cpropram/2# ./a.out
main.c(4)-mainthis is main
funca.c(4)-funca this is function
main.c(6)-mainthis is main
funcb.c(4)-funcb this is function
main.c(8)-mainthis is main
root@xuanfei-desktop:~/cpropram/2#
這就是通過定義__FILE__,__LINE__,FUNCTION__的宏來簡單實現代碼的跟蹤調試:)

下面是一個可供調試用的頭文件
#ifndef _GOLD_DEBUG_H
#define _GOLD_DEBUG_H

#ifdef __cplusplus
#if __cplusplus
extern "C"{
#endif
#endif /* __cplusplus */

//#define GI_DEBUG

#ifdef GI_DEBUG

#define GI_DEBUG_POINT()   printf("\n\n[File:%s Line:%d] Fun:%s\n\n", __FILE__, __LINE__, __FUNCTION__)
#define dbg_printf(arg...)   printf(arg);

#define GI_ASSERT(expr)                                     \
    do{                                                     \
        if (!(expr)) { \
            printf("\nASSERT failed at:\n  >File name: %s\n  >Function : %s\n  >Line No. : %d\n  >Condition: %s\n", \
                    __FILE__,__FUNCTION__, __LINE__, #expr);\
        } \
    }while(0);

/*調試宏, 用於暫停*/
#define GI_DEBUG_PAUSE()           \
 do               \
 {               \
  GI_DEBUG_POINT();          \
  printf("pause for debug, press 'q' to exit!\n");  \
  char c;             \
  while( ( c = getchar() ) )        \
   {             \
    if('q' == c)         \
     {           \
      getchar();        \
      break;         \
     }           \
   }             \
 }while(0);
#define GI_DEBUG_PAUSE_ARG(arg...)          \
  do               \
  {               \
   printf(arg);           \
   GI_DEBUG_PAUSE()          \
  }while(0);


#define GI_DEBUG_ASSERT(expression)      \
if(!(expression))                        \
{                                  \
    printf("[ASSERT],%s,%s:%d\n", __FILE__,  __FUNCTION__, __LINE__);\
    exit(-1);             \
}
#else
#define GI_ASSERT(expr)
#define GI_DEBUG_PAUSE()
#define GI_DEBUG_PAUSE_ARG(arg...)
#define GI_DEBUG_POINT()
#define dbg_printf(arg...)
#define GI_DEBUG_ASSERT(expression)

#endif

#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */


#endif

No comments: