]>
git.saurik.com Git - wxWidgets.git/blob - src/unix/stackwalk.cpp
556eaf68379842fcab6c3e3181df09d957f37ba9
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: msw/stackwalk.cpp
3 // Purpose: wxStackWalker implementation for Unix/glibc
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 2005 Vadim Zeitlin <vadim@wxwindows.org>
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 #include "wx/wxprec.h"
29 #include "wx/string.h"
32 #include "wx/stackwalk.h"
36 #ifdef HAVE_CXA_DEMANGLE
38 #endif // HAVE_CXA_DEMANGLE
40 // ============================================================================
42 // ============================================================================
44 wxString
wxStackWalker::ms_exepath
;
46 // ----------------------------------------------------------------------------
48 // ----------------------------------------------------------------------------
50 void wxStackFrame::OnGetName()
57 // try addr2line first because it always gives us demangled names (even if
58 // __cxa_demangle is not available) and because it seems less error-prone
59 // when it works, backtrace_symbols() sometimes returns incorrect results
62 // format is: "module(funcname+offset) [address]" but the part in
63 // parentheses can be not present
64 wxString syminfo
= wxString::FromAscii(m_syminfo
);
65 const size_t posOpen
= syminfo
.find(_T('('));
66 if ( posOpen
!= wxString::npos
)
68 const size_t posPlus
= syminfo
.find(_T('+'), posOpen
+ 1);
69 if ( posPlus
!= wxString::npos
)
71 const size_t posClose
= syminfo
.find(_T(')'), posPlus
+ 1);
72 if ( posClose
!= wxString::npos
)
76 m_name
.assign(syminfo
, posOpen
+ 1, posPlus
- posOpen
- 1);
78 #ifdef HAVE_CXA_DEMANGLE
80 char *cppfunc
= __cxxabiv1::__cxa_demangle
83 NULL
, // output buffer (none, alloc it)
84 NULL
, // [out] len of output buffer
88 m_name
= wxString::FromAscii(cppfunc
);
91 #endif // HAVE_CXA_DEMANGLE
95 if ( wxString(syminfo
, posPlus
+ 1, posClose
- posPlus
- 1).
102 m_module
.assign(syminfo
, posOpen
);
105 void wxStackFrame::OnGetLocation()
110 m_hasLocation
= true;
112 // we need to launch addr2line tool to get this information and we need to
113 // have the program name for this
114 wxString exepath
= wxStackWalker::GetExePath();
115 if ( exepath
.empty() )
117 if ( !wxTheApp
|| !wxTheApp
->argv
)
119 exepath
= wxTheApp
->argv
[0];
122 wxArrayString output
;
124 if ( wxExecute(wxString::Format(_T("addr2line -C -f -e \"%s\" %p"),
126 m_address
), output
) == 0 )
128 if ( output
.GetCount() != 2 )
130 wxLogDebug(_T("Unexpected addr2line output."));
132 else // 1st line has function name, 2nd one -- the file/line info
134 if ( GetName().empty() )
137 if ( m_name
== _T("??") )
141 const size_t posColon
= output
[1].find(_T(':'));
142 if ( posColon
!= wxString::npos
)
144 m_filename
.assign(output
[1], 0, posColon
);
145 if ( m_filename
== _T("??") )
152 if ( wxString(output
[1], posColon
+ 1, wxString::npos
).
159 wxLogDebug(_T("Unexpected addr2line format: \"%s\""),
166 // ----------------------------------------------------------------------------
168 // ----------------------------------------------------------------------------
170 void wxStackWalker::Walk(size_t skip
)
172 // that many frames should be enough for everyone
173 void *addresses
[200];
175 int depth
= backtrace(addresses
, WXSIZEOF(addresses
));
179 char **symbols
= backtrace_symbols(addresses
, depth
);
181 for ( int n
= 0; n
< depth
; n
++ )
183 wxStackFrame
frame(n
, addresses
[n
], symbols
[n
]);
188 #endif // wxUSE_STACKWALKER