2011-06-02 79 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