2011-03-14 75 views
0

我的概念可能听起来有点神秘,但我什么一些启动信息,我们如何可以使用GDB的API /调试技术与GCC程序时,我们编译程序。我们完全可以告诉gcc链接GDB库。最终的援助将是编译程序执行时,它应该产生以下格式的日志:GDB和GCC工会

filename.cpp:行号

有什么办法,我们可以实现它 - 我相信这是原因怎么会GDB知道这些细节,我寻找一些知识的开始。

+0

在代码做你想要写日志?你能编辑源代码并将调用插入日志宏吗? – 2011-03-14 06:37:25

+0

这将是一个更加繁琐的手工方法在每个源代码文件添加一个项目。如何GDB知道源代码列表/痕迹等等 - 但我的要求就是源代码清单也哪个函数/线。如果在程序启动时,我们可以添加一个GDB API和能够打印的代码的功能/线路 - 是可能的 – Sanjay 2011-03-14 06:47:04

+0

当你想打印出来的行号信息?每次功能开始或停止? – 2011-03-14 06:48:37

回答

1

正如在评论中已经建议,其中一个选项是使用宏像下面这样:

#define TRACE(_lvl, _msg) \ 
    if (IsTraceActive() && _lvl <= TraceActiveLevel()) { \ 
     std::ostringstream _trc_sstr; \ 
     _trc_sstr << _msg; \ 
     TraceWrite(__PRETTY_FUNCTION__, __FILE__, __LINE__, _trc_sstr.str()); \ 
    }\ 

如果您正在使用C++,你可以用一个类,它写入日志结合起来当进入或退出的功能(在构造函数和析构函数),并用回溯(http://www.linuxjournal.com/article/6391)。

#include <execinfo.h> 
#include <dlfcn.h> 
#include <cxxabi.h> 

class TraceFunc { 
public: 
    TraceFunc(const char* fnc, const char* file, int line) 
    : _fnc(fnc), _file(file), _line(line) 
    { 
     TraceWrite(_fnc, _file, _line, std::string(_fnc) + " in"); 
    } 


    virtual ~TraceFnc() 
    { 
     TraceWrite(_fnc, m_file, _line, std::string(_fnc) + " out"); 
    } 

private: 
    const char* _fnc; 
    const char* _file; 
    int   _line; 
}; 

#define FNTRACE() TraceFunc _this_fnc(__PRETTY_FUNCTION__, __FILE__, __LINE__) 

typedef std::vector<std::string> Stack; 

Stack GetExecutionStack(int a_maxDepth) 
{ 
    Stack stack; 

    const int c_maxFuncName(500); 

    void *trace[c_maxDepth+1]; 
    char **symbols(NULL); 
    char fname[c_maxFuncName]; 
    int traceSize(0); 

    traceSize = backtrace(trace, a_maxDepth+1); 
    symbols = backtrace_symbols(trace, traceSize); 

    if (symbols == NULL) { 
     return stack; 
    } 

    // Starting at 1 to skip the function that we are currently in 
    for (int i = 1; i < traceSize; ++i) { 
     Dl_info info; 
     if (dladdr(trace[i], &info) != 0) { 
      int stat; 
      char *demangled = abi::__cxa_demangle(info.dli_sname, 0, 0, &stat); 

      if (demangled != NULL) { 
       // Re-compose the stack info with de-mangled C++ name 
       snprintf(fname, c_maxFuncName, "%s(%s) [0x%p]", 
        info.dli_fname, demangled, info.dli_saddr); 
       stack.push_back(fname); 
       free(demangled); 
      } 
      else { 
       stack.push_back(std::string(symbols[i])); 
      } 
     } 
     else { 
      stack.push_back(std::string(symbols[i])); 
     } 
    } 

    free(symbols); 
    return stack; 
} 

它这样使用:

int MySpecialFunc() 
{ 
    FNTRACE(); 

    // Some code 

    TRACE(1, "Intermediate value: " << z << " mm."); 

    // more code 
}