我正在寻找一种聪明的方法来跟踪函数调用和返回。我知道我可以使用调试器,但我想要一种方法,让它在调用函数时将某些内容打印到终端,而不是单步执行代码。
我在想,我也许可以使用预处理器,但我不确定什么是最好的方法。
或者,有没有一种方法可以使用gdb打印出有用的信息,而不必遍历代码。
发布于 2010-07-23 12:08:07
大多数编译器允许您在函数调用之前和之后插入插入指令插入函数。
在MSVC中,它们是_penter和_pexit。一篇不错的文章:http://www.drdobbs.com/184403601。
在GCC中,您将使用-finstrument-functions选项,请参见the docs。
您可以使用调试库或映射文件来获取更多信息。
发布于 2010-07-23 16:16:40
一个相当复杂的解决方案是使用RAII来控制函数的范围。这将对性能有很大的影响,但在日志中将非常明确,而不需要用户在可能离开函数的所有可能的代码路径中添加工具:
class ScopeLogger {
public:
ScopeLogger( std::string const & msg ) : msg(msg)
{ std::cout << "Enter: " << msg << std::endl; }
~ScopeLogger()
{ std::cout << "Exit: " << msg << std::endl; }
std::string msg;
};
#if DEBUG
#define FUNCTION(x) ScopeLogger l_##x##_scope(x);
#endif
void foo( int value ) {
FUNCTION( __FUNCTION__ );
if ( value > 10 ) throw std::exception;
std::cout << "." << std::endl;
}
int main() {
foo(0); // Enter: foo\n.\nExit: foo
foo(100); // Enter: foo\nExit: foo
}如果代码是单线程的,您甚至可能希望向ScopedLogger添加一个具有一定缩进级别的静态变量,而不会增加太多已经很严重的性能影响:
class ScopeLogger {
public:
ScopeLogger( std::string const & msg ) : msg(msg)
{ std::cout << std::string(indent++,' ') << "Enter: " << msg << std::endl; }
~ScopeLogger()
{ std::cout << std::string(--indent,' ') << "Exit: " << msg << std::endl; }
std::string msg;
static int indent;
};
int ScopeLogger::indent = 0;发布于 2012-04-20 04:05:01
既然您使用的是GCC,那么您也可以使用链接器函数包装。
Link-Time Replacement / Wrapping
– GCC option: -Wl,--wrap,function_name基本上,您可以使用名为"function_name()“的函数,并用名为"__wrap_function_name()”的函数包装它。您可以通过调用"__real_function_name()“来访问原始函数。
https://stackoverflow.com/questions/3315248
复制相似问题