一种获取过程调用堆栈信息的简单方法

在程序崩溃或出现异常时,通常需要给开发人员提供基本的过程调用的信息,这里给出一个简单的C++实现。主要思路是:过程调用的开始时,在栈上创建一个类,利用类的构造函数记录相关信息,在过程调用完毕时会自动调用析构函数,再将记录信息删除。

Track.h
 1 #ifndef _TRACK_HPP_
 2 #define _TRACK_HPP_
 3 #include <vector>
 4 
 5 //!调用堆栈类
 6 class CallStack
 7 {
 8 public:
 9     struct CallInfo
10     {
11         const char* func_name;  ///<调用函数名
12         const char* file_name;  ///<源程序文件名
13         int         line_number;///<行编号
14 
15         CallInfo(const char* func,const char* file,int line)
16             :func_name(func),file_name(file),line_number(line)
17         {}
18     };
19 
20     //!添加一个调用过程
21     inline void Push(const char* func_name,const char* file_name,int line_number)
22     {
23         call_stack.push_back(CallInfo(func_name,file_name,line_number));
24     }
25     //!弹出一个调用过程
26     inline void Pop()
27     {
28         call_stack.pop_back();
29     }
30     //!获取当前的调用堆栈信息
31     inline const std::vector<CallInfo>& GetCallStack()const
32     {
33         return call_stack;
34     }
35 
36     static CallStack& GetInstance(){
37         static CallStack g_stack;
38         return g_stack;
39     }
40 
41 private:
42     CallStack():call_stack(){}
43     std::vector<CallInfo> call_stack;
44 };
45 #define g_CallStack CallStack::GetInstance()
46 
47 //!调用过程跟踪类
48 class Track
49 {
50 public:
51     Track(const char* func_name,const char* file_name,int line_number)
52     {
53         g_CallStack.Push(func_name,file_name,line_number);
54     }
55     ~Track()
56     {
57         g_CallStack.Pop();
58     }
59 
60 private:
61     Track();
62 };
63 
64 ///使用该宏实现调用信息的记录
65 #define TRACK(func) Track track(#func,__FILE__,__LINE__);
66 
67 ///使用该宏实现仅在调试阶段记录过程调用信息
68 #ifdef _DEBUG
69     #define TRACK_D(func) TRACK(func)
70 #else
71     #define TRACK_D(func)
72 #endif
73 
74 #endif //_TRACK_HPP_

 

test.cpp
#include "Track.hpp"

void Test2();

void Test1()
{
    TRACK(Test1);

    Test2();
}

void Test2()
{
    TRACK(Test2);
    
    //查看调用堆栈信息
    const std::vector<CallStack::CallInfo>& stack = g_CallStack.GetCallStack();
}

void main()
{
    TRACK(main);

    Test1();
}

posted on 2012-01-04 20:18  codezhang  阅读(895)  评论(0编辑  收藏  举报

导航