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

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

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

 GCC实现了如下的函数宏

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

__FUNCTION__ 同__func__,

__PRETTY_FUNCTION__ 非标准宏。这个宏比__FUNCTION__功能更强, 若用g++编译C++程序, __FUNCTION__只能输出类的成员名,不会输出类名; 而__PRETTY_FUNCTION__则会以  ::() 的格式输出成员函数的详悉信息(注: 只会输出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

转自:https://blog.csdn.net/fullsail/article/details/2345225

你可能感兴趣的:((转)利用小技巧用于跟踪函数的进出过程)