C/C++需要一种聪明的方法来跟踪函数调用

Mat*_* FL 6 c c++ gdb c-preprocessor

我正在寻找一种聪明的方法来跟踪函数调用和返回.我知道我可以使用调试器,但是我希望有一种方法可以让它在调用函数时向终端输出一些东西而不必逐步执行代码.
我想我可以使用预处理器,但我不确定最好的方法是什么.
或者有没有办法使用gdb打印出有用的信息,而无需单步执行代码.

Jon*_*off 14

大多数编译器允许您在函数调用之前和之后注入检测函数.

在msvc中,它们是_penter和_pexit
很好的文章 http://www.drdobbs.com/184403601

在gcc中你会使用-finstrument-functions
http://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Code-Gen-Options.html

您可以使用调试库或映射文件来获取更多信息.


Dav*_*eas 5

一个非常侵入性的解决方案是使用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
}
Run Code Online (Sandbox Code Playgroud)

如果代码是单线程的,则您甚至可能希望添加具有某种缩进级别的静态变量,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;
Run Code Online (Sandbox Code Playgroud)


Mic*_*yan 2

或者有没有办法使用 gdb 打印出有用的信息,而不必逐步执行代码

是的。仅在您真正关心的函数处设置断点。使用“继续”直到您到达这些功能或直到您的程序崩溃。然后使用“backtrace”(或“bt”)来获取堆栈跟踪。