2011-03-14 32 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 
}