#ifndef WX_PRECOMP
#include "wx/string.h"
+ #include "wx/app.h"
+ #include "wx/log.h"
+ #include "wx/utils.h"
#endif
#include "wx/stackwalk.h"
#include <cxxabi.h>
#endif // HAVE_CXA_DEMANGLE
+// ----------------------------------------------------------------------------
+// tiny helper wrapper around popen/pclose()
+// ----------------------------------------------------------------------------
+
+class wxStdioPipe
+{
+public:
+ // ctor parameters are passed to popen()
+ wxStdioPipe(const char *command, const char *type)
+ {
+ m_fp = popen(command, type);
+ }
+
+ // conversion to stdio FILE
+ operator FILE *() const { return m_fp; }
+
+ // dtor closes the pipe
+ ~wxStdioPipe()
+ {
+ if ( m_fp )
+ pclose(m_fp);
+ }
+
+private:
+ FILE *m_fp;
+
+ DECLARE_NO_COPY_CLASS(wxStdioPipe)
+};
+
// ============================================================================
// implementation
// ============================================================================
m_offset = ofs;
}
}
- }
- m_module.assign(syminfo, posOpen);
+ m_module.assign(syminfo, posOpen);
+ }
+ else // not in "module(funcname+offset)" format
+ {
+ m_module = syminfo;
+ }
}
void wxStackFrame::OnGetLocation()
exepath = wxTheApp->argv[0];
}
- wxArrayString output;
- wxLogNull noLog;
- if ( wxExecute(wxString::Format(_T("addr2line -C -f -e \"%s\" %p"),
- exepath.c_str(),
- m_address), output) == 0 )
+ wxStdioPipe fp(wxString::Format(_T("addr2line -C -f -e \"%s\" %p"),
+ exepath.c_str(), m_address).mb_str(),
+ "r");
+
+ if ( !fp )
+ return;
+
+ // parse addr2line output
+ char buf[1024];
+ if ( !fgets(buf, WXSIZEOF(buf), fp) )
{
- if ( output.GetCount() != 2 )
- {
- wxLogDebug(_T("Unexpected addr2line output."));
- }
- else // 1st line has function name, 2nd one -- the file/line info
- {
- if ( GetName().empty() )
- {
- m_name = output[0];
- if ( m_name == _T("??") )
- m_name.clear();
- }
+ wxLogDebug(_T("Empty addr2line output?"));
+ return;
+ }
+
+ // 1st line has function name
+ if ( GetName().empty() )
+ {
+ m_name = wxString::FromAscii(buf);
+ m_name.RemoveLast(); // trailing newline
+
+ if ( m_name == _T("??") )
+ m_name.clear();
+ }
- const size_t posColon = output[1].find(_T(':'));
- if ( posColon != wxString::npos )
+ // 2nd one -- the file/line info
+ if ( fgets(buf, WXSIZEOF(buf), fp) )
+ {
+ wxString output(wxString::FromAscii(buf));
+ output.RemoveLast();
+
+ const size_t posColon = output.find(_T(':'));
+ if ( posColon != wxString::npos )
+ {
+ m_filename.assign(output, 0, posColon);
+ if ( m_filename == _T("??") )
{
- m_filename.assign(output[1], 0, posColon);
- if ( m_filename == _T("??") )
- {
- m_filename.clear();
- }
- else
- {
- unsigned long line;
- if ( wxString(output[1], posColon + 1, wxString::npos).
- ToULong(&line) )
- m_line = line;
- }
+ m_filename.clear();
}
else
{
- wxLogDebug(_T("Unexpected addr2line format: \"%s\""),
- output[1].c_str());
+ unsigned long line;
+ if ( wxString(output, posColon + 1, wxString::npos).
+ ToULong(&line) )
+ m_line = line;
}
}
+ else
+ {
+ wxLogDebug(_T("Unexpected addr2line format: \"%s\""),
+ output.c_str());
+ }
}
}
char **symbols = backtrace_symbols(addresses, depth);
- for ( int n = 0; n < depth; n++ )
+ // we have 3 more "intermediate" frames which the calling code doesn't know
+ // about., account for them
+ skip += 3;
+
+ for ( int n = skip; n < depth; n++ )
{
- wxStackFrame frame(n, addresses[n], symbols[n]);
+ wxStackFrame frame(n - skip, addresses[n], symbols[n]);
OnStackFrame(frame);
}
}