2011-06-02 82 views
1

我想爲我們的大型C++代碼庫開發縮進軌跡,這對開發人員來說很有幫助,可以幫助您找到問題。我想要縮進跟蹤功能。例如,考慮以下代碼: -C++中的縮進軌跡

void FunctionA() 
{ 
    TR_ENTER("Function A"); 
    TR_PRINT("Dignostic message Function A"); 
    FunctionB(); // Call function B 
} 

void FunctionB() 
{ 
    TR_ENTER("Function B"); 
    TR_PRINT("Dignostic message Function B"); 
    FunctionC(); // Call function B 
} 

void FunctionC() 
{ 
    TR_ENTER("Function C"); 
    TR_PRINT("Dignostic message Function C");   
} 

正如你所看到的,上面的調用是嵌套在一起的。我想生成跟蹤日誌,如下所示:

Function A - Start 
Dignostic message Function A 
    Function B - Start 
    Dignostic message Function B 
      Function C - Start 
      Dignostic message Function C 
      Function C - End 
    Function B - End 
Function A - End 

TR_ENTER和TR_PRINT是我用作示例的一些宏。要說功能啓動我已經使用TR_ENTER和打印一些dignostic消息我已經使用TR_PRINT。

正如你所看到的嵌套函數調用的軌跡是相互縮進的。我是否知道有什麼已經有的東西可以阻止我自己重新開始工作。

感謝, Omky

回答

7

你需要跟蹤呼叫深度:

class trace_entry; 

class trace_log { 
public: 
    trace_log() : depth_(0) { } 

private: 
    // noncopyable so we don't accidentally copy it 
    trace_log(trace_log&); 
    void operator=(trace_log); 

    friend trace_entry; 

    int depth_; 
}; 

class trace_entry { 
public: 
    trace_entry(trace_log& log, const std::string& frame) 
     : log_(log), frame_(frame) { 
     std::cout << std::string(4 * log.depth_, ' ') 
        << "ENTER " << frame_ << std::endl; 
     ++log_.depth_; 
    } 

    ~trace_entry() { 
     --log_.depth_; 
     std::cout << std::string(4 * log_.depth_, ' ') 
        << "EXIT " << frame_ << std::endl; 
    } 
private: 
    // noncopyable so we don't accidentally copy it 
    trace_entry(trace_entry&); 
    void operator=(trace_entry); 

    trace_log& log_; 
    std::string frame_; 
}; 

用例:

void a(trace_log& log) { 
    trace_entry e(log, "a"); 
} 

void b(trace_log& log) { 
    trace_entry e(log, "b"); 
    return a(log); 
} 

int main() { 
    trace_log log; 
    trace_entry e(log, "main"); 
    b(log); 
} 

輸出:

ENTER main 
    ENTER b 
     ENTER a 
     EXIT a 
    EXIT b 
EXIT main 

這是EAS ily可擴展以支持其他形式的日誌記錄,允許額外的日誌消息,以及任何你想做的事情。 (如果trace_log實際執行日誌記錄會更好,但是爲了說明目的,這是證明你正在嘗試做什麼的最簡單的方法。)

+0

非常感謝詹姆斯......我會嘗試這種方法。 – Omkar 2011-06-02 06:26:33

+1

如果你知道你是單線程的,你可以讓你的'trace_log'成爲一個全局變量。如果你是多線程的,你可以使用perthread變量來獲得相同的效果。這樣你就不需要修改應用程序中的每個函數調用來添加和傳遞'trace_log'變量。 – 2011-06-02 07:41:24

+0

另一件需要注意的事情是......編譯器在你寫'trace_entry(log,「foo」);'而不是正確的'trace_entry e(log,「foo」);'時不會抱怨。第一個創建一個臨時的並立即銷燬它,立即輸出ENTER和EXIT日誌。第二種是正確的格式,輸出對象創建時的ENTER,當它超出作用域時退出(通常在函數出口處)。 – 2011-06-02 07:44:46