From ede3a6d68af66772b4f5f94208b4126bab566cc8 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 27 Mar 2005 22:22:24 +0000 Subject: [PATCH] use popen() instead of wxExecute(), it works inside wxYield() unlike the latter git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@33110 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/unix/stackwalk.cpp | 106 ++++++++++++++++++++++++++++------------- 1 file changed, 73 insertions(+), 33 deletions(-) diff --git a/src/unix/stackwalk.cpp b/src/unix/stackwalk.cpp index 36a85a7ac8..9ad52db9e6 100644 --- a/src/unix/stackwalk.cpp +++ b/src/unix/stackwalk.cpp @@ -40,6 +40,35 @@ #include #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 // ============================================================================ @@ -122,47 +151,58 @@ 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()); + } } } -- 2.45.2