您的位置:首页 > 其它

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

2008-04-30 00:11 204 查看
有一次为了调试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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐