1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        wx/stackwalk.h
3 // Purpose:     wxStackWalker and related classes, common part
4 // Author:      Vadim Zeitlin
5 // Modified by:
6 // Created:     2005-01-07
7 // Copyright:   (c) 2004 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence:     wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10 
11 #ifndef _WX_STACKWALK_H_
12 #define _WX_STACKWALK_H_
13 
14 #include "wx/defs.h"
15 
16 #if wxUSE_STACKWALKER
17 
18 #include "wx/string.h"
19 
20 class WXDLLIMPEXP_FWD_BASE wxStackFrame;
21 
22 #define wxSTACKWALKER_MAX_DEPTH       (200)
23 
24 // ----------------------------------------------------------------------------
25 // wxStackFrame: a single stack level
26 // ----------------------------------------------------------------------------
27 
28 class WXDLLIMPEXP_BASE wxStackFrameBase
29 {
30 private:
31     // put this inline function here so that it is defined before use
ConstCast()32     wxStackFrameBase *ConstCast() const
33         { return const_cast<wxStackFrameBase *>(this); }
34 
35 public:
36     wxStackFrameBase(size_t level, void *address = NULL)
37     {
38         m_level = level;
39 
40         m_line =
41         m_offset = 0;
42 
43         m_address = address;
44     }
45 
46     // get the level of this frame (deepest/innermost one is 0)
GetLevel()47     size_t GetLevel() const { return m_level; }
48 
49     // return the address of this frame
GetAddress()50     void *GetAddress() const { return m_address; }
51 
52 
53     // return the unmangled (if possible) name of the function containing this
54     // frame
GetName()55     wxString GetName() const { ConstCast()->OnGetName(); return m_name; }
56 
57     // return the instruction pointer offset from the start of the function
GetOffset()58     size_t GetOffset() const { ConstCast()->OnGetName(); return m_offset; }
59 
60     // get the module this function belongs to (not always available)
GetModule()61     wxString GetModule() const { ConstCast()->OnGetName(); return m_module; }
62 
63 
64     // return true if we have the filename and line number for this frame
HasSourceLocation()65     bool HasSourceLocation() const { return !GetFileName().empty(); }
66 
67     // return the name of the file containing this frame, empty if
68     // unavailable (typically because debug info is missing)
GetFileName()69     wxString GetFileName() const
70         { ConstCast()->OnGetLocation(); return m_filename; }
71 
72     // return the line number of this frame, 0 if unavailable
GetLine()73     size_t GetLine() const { ConstCast()->OnGetLocation(); return m_line; }
74 
75 
76     // return the number of parameters of this function (may return 0 if we
77     // can't retrieve the parameters info even although the function does have
78     // parameters)
GetParamCount()79     virtual size_t GetParamCount() const { return 0; }
80 
81     // get the name, type and value (in text form) of the given parameter
82     //
83     // any pointer may be NULL
84     //
85     // return true if at least some values could be retrieved
GetParam(size_t WXUNUSED (n),wxString * WXUNUSED (type),wxString * WXUNUSED (name),wxString * WXUNUSED (value))86     virtual bool GetParam(size_t WXUNUSED(n),
87                           wxString * WXUNUSED(type),
88                           wxString * WXUNUSED(name),
89                           wxString * WXUNUSED(value)) const
90     {
91         return false;
92     }
93 
94 
95     // although this class is not supposed to be used polymorphically, give it
96     // a virtual dtor to silence compiler warnings
~wxStackFrameBase()97     virtual ~wxStackFrameBase() { }
98 
99 protected:
100     // hooks for derived classes to initialize some fields on demand
OnGetName()101     virtual void OnGetName() { }
OnGetLocation()102     virtual void OnGetLocation() { }
103 
104 
105     // fields are protected, not private, so that OnGetXXX() could modify them
106     // directly
107     size_t m_level;
108 
109     wxString m_name,
110              m_module,
111              m_filename;
112 
113     size_t m_line;
114 
115     void *m_address;
116     size_t m_offset;
117 };
118 
119 // ----------------------------------------------------------------------------
120 // wxStackWalker: class for enumerating stack frames
121 // ----------------------------------------------------------------------------
122 
123 class WXDLLIMPEXP_BASE wxStackWalkerBase
124 {
125 public:
126     // ctor does nothing, use Walk() to walk the stack
wxStackWalkerBase()127     wxStackWalkerBase() { }
128 
129     // dtor does nothing neither but should be virtual
~wxStackWalkerBase()130     virtual ~wxStackWalkerBase() { }
131 
132     // enumerate stack frames from the current location, skipping the initial
133     // number of them (this can be useful when Walk() is called from some known
134     // location and you don't want to see the first few frames anyhow; also
135     // notice that Walk() frame itself is not included if skip >= 1)
136     virtual void Walk(size_t skip = 1, size_t maxDepth = wxSTACKWALKER_MAX_DEPTH) = 0;
137 
138 #if wxUSE_ON_FATAL_EXCEPTION
139     // enumerate stack frames from the location of uncaught exception
140     //
141     // this version can only be called from wxApp::OnFatalException()
142     virtual void WalkFromException(size_t maxDepth = wxSTACKWALKER_MAX_DEPTH) = 0;
143 #endif // wxUSE_ON_FATAL_EXCEPTION
144 
145 protected:
146     // this function must be overridden to process the given frame
147     virtual void OnStackFrame(const wxStackFrame& frame) = 0;
148 };
149 
150 #ifdef __WINDOWS__
151     #include "wx/msw/stackwalk.h"
152 #elif defined(__UNIX__)
153     #include "wx/unix/stackwalk.h"
154 #else
155     #error "wxStackWalker is not supported, set wxUSE_STACKWALKER to 0"
156 #endif
157 
158 #endif // wxUSE_STACKWALKER
159 
160 #endif // _WX_STACKWALK_H_
161 
162