C++是促进脑死亡的最佳方式

一个老程序员坐在这个角落,看眼前人来人往。

利用小技巧用于跟踪函数的进出过程

 有一次为了调试ACE的代码打开了ACE_TRACE的开关,除了对蜂拥而出的日志输出有印象外还对ACE的函数进出提示产生了好感。对于后台调试的时候,往往必须使用大量的日志跟踪。而简单的加入函数进出的功能是一个不错的选择。

稍稍看了一下ACE的实现,感觉效果一般,还要自己写跟踪的函数名称。也不是太爽。(ACE估计是苦于大家对C++标准的支持程度)。感觉了一下,其实函数的进出跟踪都可以使用一个结构的构造和析构函数跟踪,而函数的信息完全可以使用各种宏代替。而这些信息可以作为参数传递给这个结构。

 GCC实现了如下的函数宏

__func__   C99的标准,但是GCC只输出函数名称。不知道VC.NET 为啥不支持

__FUNCTION__  __func__

__PRETTY_FUNCTION__  非标准宏。这个宏比__FUNCTION__功能更强,  若用g++编译C++程序, __FUNCTION__只能输出类的成员名,不会输出类名; __PRETTY_FUNCTION__则会以 <return-type>  <class-name>::<member-function-name>(<parameters-list>) 的格式输出成员函数的详悉信息(: 只会输出parameters-list的形参类型, 而不会输出形参名).若用gcc编译C程序,__PRETTY_FUNCTION____FUNCTION__的功能相同.

VC.NET提供的函数宏为:

__FUNCTION__ 函数,提供类名和函数名称的输出。

 实现代码如下:

//利用一个结构的构造和析构函数进行函数跟踪

struct __zenlib_func_trace_struct

{

public:

    //函数名称

    const char *func_name_;

    //文件名称

    const char *file_name_;

    //文件的行号,行号是函数体内部的位置,不是函数声明的起始位置,但这又何妨

    int         file_line_;

public:

    //利用构造函数显示进入函数的输出

    __zenlib_func_trace_struct(const char *func_name,const char *file_name,int file_line):

        func_name_(func_name),

        file_name_(file_name),

        file_line_(file_line)

    {

        ACE_DEBUG((LM_TRACE,"%s entry,File %s|%u /n",func_name_,file_name_,file_line_));

    }

    //利用析构函数显示进入函数的输出

    ~__zenlib_func_trace_struct()

    {

        ACE_DEBUG((LM_TRACE,"%s exit,File %s|%u /n",func_name_,file_name_,file_line_));

    }

 

};

 

//---------------------------------------------------------------------------------

//ZEN_FUNCTION_TRACE宏用于跟踪函数的进出

//请在函数的开始使用ZEN_FUNCTION_TRACE这个宏,后面必须加分号

#ifndef ZEN_FUNCTION_TRACE

#ifdef WIN32

    //这儿定义的是一个结构

        #define ZEN_FUNCTION_TRACE        __zenlib_func_trace_struct ____tmp_func_trace_(__FUNCTION__,__FILE__,__LINE__)

        //GCC

    #else

        #define ZEN_FUNCTION_TRACE        __zenlib_func_trace_struct ____tmp_func_trace_(__PRETTY_FUNCTION__,__FILE__,__LINE__)

    #endif

#endif //#ifndef ZEN_FUNCTION_TRACE

 

 

//ZEN_FILELINE_TRACE用于程序运行到的地方。

#ifdef ZEN_FILELINE_TRACE

    #ifdef WIN32

        #define ZEN_FILELINE_TRACE        ACE_DEBUG((LM_TRACE,"Goto File %s|%d,function:%s./n",__FILE__,__LINE__,__FUNCTION__));

    //GCC   

    #else

        #define ZEN_FILELINE_TRACE        ACE_DEBUG((LM_TRACE,"Goto File %s|%d,function:%s./n",__FILE__,__LINE__,__PRETTY_FUNCTION__));

    #endif //#ifndef ZEN_FILELINE_TRACE

#endif

 

代码的使用如下,只要在函数的开头使用ZEN_FILELINE_TRACE这个宏就可以。

TransactionBase::TRANSACTION_PROCESS MarketBuyItemTrans::OnInit()

{

    ZEN_FUNCTION_TRACE;

    return NEXT_PROCESS;

}

 最后的输出如下:

Feb 12 11:43:59.356 2007@LM_TRACE@int MarketBuyItemTrans::SendBuyItemsRspToClient(int) entry,File market_trans_buy_items.cpp|964

Feb 12 11:43:59.356 2007@LM_DEBUG@Send Rsp To Client: rs_buy_items_.buy_item_num_:1,rs_buy_items_.buy_package_num_:0 .

Feb 12 11:43:59.356 2007@LM_DEBUG@Output AppFrame Head::

Len:108 Framedesc:0x0 Command:8502       Uin:348642895 TransactionID:1          Sendip:0        

Rcvsvr:30001|348642895  Sndsvr:5    |1          Proxysvr:0    |0        

Feb 12 11:43:59.356 2007@LM_TRACE@int MarketBuyItemTrans::SendBuyItemsRspToClient(int) exit,File market_trans_buy_items.cpp|964

 

 

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭