OpenCPN Partial API docs
crashprint.cpp
1 // File: crashprint.cpp
3 // Purpose: wxCrashPrint
4 // Maintainer: Wyo
5 // Created: 2004-09-28
6 // RCS-ID: $Id: crashprint.cpp,v 1.11 2005-04-14 19:41:33 wyo Exp $
7 // Copyright: (c) 2004 wxCode
8 // Licence: wxWindows
10 
11 //----------------------------------------------------------------------------
12 // information
13 //----------------------------------------------------------------------------
14 
15 //----------------------------------------------------------------------------
16 // headers
17 //----------------------------------------------------------------------------
18 
19 // For compilers that support precompilation, includes <wx/wx.h>.
20 #include <wx/wxprec.h>
21 
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25 
26 // for all others, include the necessary headers (this file is usually all you
27 // need because it includes almost all 'standard' wxWidgets headers)
28 #ifndef WX_PRECOMP
29 #include <wx/wx.h>
30 #endif
31 
33 #if defined(__linux__)
34 #include <execinfo.h> // Needed for backtrace
35 #include <cxxabi.h> // Needed for __cxa_demangle
36 #include <unistd.h>
37 #endif
38 
39 // wxWidgets headers
40 #include <wx/string.h> // strings support
41 
42 // crashprint headers
43 #include "crashprint.h" // crash print support
44 
45 //----------------------------------------------------------------------------
46 // resources
47 //----------------------------------------------------------------------------
48 
49 //============================================================================
50 // declarations
51 //============================================================================
52 
53 //============================================================================
54 // implementation
55 //============================================================================
56 
57 //----------------------------------------------------------------------------
58 // wxCrashPrint
59 //----------------------------------------------------------------------------
60 
61 wxCrashPrint::wxCrashPrint(int flags, const wxString &fname) {
62  m_flags = flags;
63  m_fname = fname;
64 };
65 
66 //----------------------------------------------------------------------------
67 // settings functions
68 
69 //----------------------------------------------------------------------------
70 // general functions
71 
72 void wxCrashPrint::Report() {
73 #if defined(__linux__)
74  wxString appname = wxTheApp->GetAppName();
75 
76  // get the backtrace with symbols
77  int btCount;
78  btCount = backtrace(m_btBuffer, maxBtCount);
79  if (btCount < 0) {
80  wxPrintf(_T("\n%s: Backtrace could not be created\n"), appname.c_str());
81  }
82  m_btStrings = backtrace_symbols(m_btBuffer, btCount);
83  if (!m_btStrings) {
84  wxPrintf(_T("\n%s: Backtrace could not get symbols\n"), appname.c_str());
85  }
86 
87  // print backtrace announcement
88  wxPrintf(_T("\n*** %s (%s) crashed ***, see backtrace!\n"), appname.c_str(),
89  wxVERSION_STRING);
90 
91  // format backtrace lines
92  int status;
93  wxString cur, addr, func, addrs;
94  wxArrayString lines;
95  size_t pos1, pos2;
96  if (m_btStrings)
97  for (int i = 0; i < btCount; ++i) {
98  cur = wxString::FromAscii(m_btStrings[i]);
99  pos1 = cur.rfind('[');
100  pos2 = cur.rfind(']');
101  if ((pos1 != wxString::npos) && (pos2 != wxString::npos)) {
102  addr = cur.substr(pos1 + 1, pos2 - pos1 - 1);
103  addrs.Append(addr + _T(" "));
104  }
105  pos1 = cur.rfind(_T("_Z"));
106  pos2 = cur.rfind('+');
107  if (pos2 == wxString::npos) pos2 = cur.rfind(')');
108  if (pos1 != wxString::npos) {
109  func = cur.substr(pos1, pos2 - pos1);
110  func = wxString::FromAscii(
111  abi::__cxa_demangle(func.mb_str(), 0, 0, &status));
112  } else {
113  pos1 = cur.rfind('(');
114  if (pos1 != wxString::npos) {
115  func = cur.substr(pos1 + 1, pos2 - pos1 - 1);
116  } else {
117  pos2 = cur.rfind('[');
118  func = cur.substr(0, pos2 - 1);
119  }
120  }
121  lines.Add(addr + _T(" in ") + func);
122  if (func == _T("main")) break;
123  }
124 
125  // determine line from address
126  wxString cmd =
127  wxString::Format(_T("addr2line -e /proc/%d/exe -s "), getpid());
128  wxArrayString fnames;
129  if (wxExecute(cmd + addrs, fnames) != -1) {
130  for (size_t i = 0; i < fnames.GetCount(); ++i) {
131  wxPrintf(_T("%s at %s\n"), lines[i].c_str(), fnames[i].c_str());
132  }
133  } else {
134  for (size_t i = 0; i < lines.GetCount(); ++i) {
135  wxPrintf(_T("%s\n"), lines[i].c_str());
136  }
137  }
138 #endif
139 }
wxCrashPrint(int flags=0, const wxString &fname=wxEmptyString)
constructor
Definition: crashprint.cpp:61