~efargaspro/+junk/codeblocks-16.01-release

« back to all changes in this revision

Viewing changes to src/tools/Addr2LineUI/Addr2LineUIMain.cpp

  • Committer: damienlmoore at gmail
  • Date: 2016-02-02 02:43:22 UTC
  • Revision ID: damienlmoore@gmail.com-20160202024322-yql5qmtbwdyamdwd
Code::BlocksĀ 16.01

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "Addr2LineUIMain.h"
 
2
 
 
3
//(*InternalHeaders(Addr2LineUIDialog)
 
4
#include <wx/settings.h>
 
5
#include <wx/font.h>
 
6
#include <wx/intl.h>
 
7
#include <wx/string.h>
 
8
//*)
 
9
 
 
10
#include <wx/busyinfo.h>
 
11
#include <wx/msgdlg.h>
 
12
#include <wx/regex.h>
 
13
#include <wx/textfile.h>
 
14
#include <wx/utils.h> // wxExecute
 
15
 
 
16
//(*IdInit(Addr2LineUIDialog)
 
17
const long Addr2LineUIDialog::ID_CRASH_LOG = wxNewId();
 
18
const long Addr2LineUIDialog::ID_ADDR2LINE = wxNewId();
 
19
const long Addr2LineUIDialog::ID_DIR_PREPEND = wxNewId();
 
20
const long Addr2LineUIDialog::ID_CHK_REPLACE = wxNewId();
 
21
const long Addr2LineUIDialog::ID_TXT_REPLACE_THIS = wxNewId();
 
22
const long Addr2LineUIDialog::ID_LBL_REPLACE = wxNewId();
 
23
const long Addr2LineUIDialog::ID_TXT_REPLACE_THAT = wxNewId();
 
24
const long Addr2LineUIDialog::ID_CHK_SKIP_UNRESOLVABLE = wxNewId();
 
25
const long Addr2LineUIDialog::ID_TXT_CRASH_LOG_CONTENT = wxNewId();
 
26
const long Addr2LineUIDialog::ID_TXT_RESULT = wxNewId();
 
27
const long Addr2LineUIDialog::ID_BTN_OPERATE = wxNewId();
 
28
const long Addr2LineUIDialog::ID_BTN_QUIT = wxNewId();
 
29
//*)
 
30
 
 
31
BEGIN_EVENT_TABLE(Addr2LineUIDialog,wxDialog)
 
32
  //(*EventTable(Addr2LineUIDialog)
 
33
  //*)
 
34
END_EVENT_TABLE()
 
35
 
 
36
Addr2LineUIDialog::Addr2LineUIDialog(wxWindow* parent) :
 
37
  mFileConfig(),
 
38
  mCrashLog(),
 
39
  mCrashLogFileContent(),
 
40
  mAddr2Line(wxT("addr2line")),
 
41
  mDirPrepend()
 
42
{
 
43
  //(*Initialize(Addr2LineUIDialog)
 
44
  wxStaticText* lblDirPrepend;
 
45
  wxBoxSizer* bszAddr2Line;
 
46
  wxButton* btnQuit;
 
47
  wxBoxSizer* bszMainV;
 
48
  wxStaticText* lblCrashLog;
 
49
  wxBoxSizer* bszReplace;
 
50
  wxBoxSizer* bszMainH;
 
51
  wxStaticText* lblAddr2Line;
 
52
  wxStaticLine* stlLine;
 
53
 
 
54
  Create(parent, wxID_ANY, _("Addr2LineUI"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxMAXIMIZE_BOX|wxMINIMIZE_BOX, _T("wxID_ANY"));
 
55
  bszMainH = new wxBoxSizer(wxHORIZONTAL);
 
56
  bszMainV = new wxBoxSizer(wxVERTICAL);
 
57
  bszAddr2Line = new wxBoxSizer(wxVERTICAL);
 
58
  lblCrashLog = new wxStaticText(this, wxID_ANY, _("Select crash log file:"), wxDefaultPosition, wxDefaultSize, 0, _T("wxID_ANY"));
 
59
  bszAddr2Line->Add(lblCrashLog, 0, wxEXPAND|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
 
60
  m_FPCrashLog = new wxFilePickerCtrl(this, ID_CRASH_LOG, wxEmptyString, _("Select crash log"), _T("Report files (*.rpt)|*.rpt|Log files (*.log)|*.log|All files (*.*)|*.*"), wxDefaultPosition, wxDefaultSize, wxFLP_FILE_MUST_EXIST|wxFLP_OPEN|wxFLP_USE_TEXTCTRL, wxDefaultValidator, _T("ID_CRASH_LOG"));
 
61
  bszAddr2Line->Add(m_FPCrashLog, 0, wxEXPAND|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
 
62
  lblAddr2Line = new wxStaticText(this, wxID_ANY, _("Select Addr2Line tool:"), wxDefaultPosition, wxDefaultSize, 0, _T("wxID_ANY"));
 
63
  bszAddr2Line->Add(lblAddr2Line, 0, wxTOP|wxEXPAND|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
 
64
  m_FPAddr2Line = new wxFilePickerCtrl(this, ID_ADDR2LINE, wxEmptyString, _("Select addr2line tool"), _T("Executables (*.exe)|*.exe|All files (*.*)|*.*"), wxDefaultPosition, wxDefaultSize, wxFLP_FILE_MUST_EXIST|wxFLP_OPEN|wxFLP_USE_TEXTCTRL, wxDefaultValidator, _T("ID_ADDR2LINE"));
 
65
  bszAddr2Line->Add(m_FPAddr2Line, 0, wxEXPAND|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
 
66
  lblDirPrepend = new wxStaticText(this, wxID_ANY, _("(Optionally) Select directory to prepend:"), wxDefaultPosition, wxDefaultSize, 0, _T("wxID_ANY"));
 
67
  bszAddr2Line->Add(lblDirPrepend, 0, wxTOP|wxEXPAND|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
 
68
  m_DPDirPrepend = new wxDirPickerCtrl(this, ID_DIR_PREPEND, wxEmptyString, _("Select directory to prepend"), wxDefaultPosition, wxDefaultSize, wxDIRP_DIR_MUST_EXIST|wxDIRP_USE_TEXTCTRL, wxDefaultValidator, _T("ID_DIR_PREPEND"));
 
69
  bszAddr2Line->Add(m_DPDirPrepend, 0, wxEXPAND|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
 
70
  bszMainV->Add(bszAddr2Line, 0, wxALL|wxEXPAND|wxALIGN_LEFT|wxALIGN_TOP, 5);
 
71
  bszReplace = new wxBoxSizer(wxHORIZONTAL);
 
72
  chkReplace = new wxCheckBox(this, ID_CHK_REPLACE, _("Replace:"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_CHK_REPLACE"));
 
73
  chkReplace->SetValue(false);
 
74
  bszReplace->Add(chkReplace, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
 
75
  txtReplaceThis = new wxTextCtrl(this, ID_TXT_REPLACE_THIS, _("this"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_TXT_REPLACE_THIS"));
 
76
  txtReplaceThis->Disable();
 
77
  bszReplace->Add(txtReplaceThis, 1, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_LEFT|wxALIGN_TOP, 5);
 
78
  lblReplace = new wxStaticText(this, ID_LBL_REPLACE, _("...with:"), wxDefaultPosition, wxDefaultSize, 0, _T("ID_LBL_REPLACE"));
 
79
  lblReplace->Disable();
 
80
  bszReplace->Add(lblReplace, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 5);
 
81
  txtReplaceThat = new wxTextCtrl(this, ID_TXT_REPLACE_THAT, _("that"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_TXT_REPLACE_THAT"));
 
82
  txtReplaceThat->Disable();
 
83
  bszReplace->Add(txtReplaceThat, 1, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_LEFT|wxALIGN_TOP, 5);
 
84
  chkSkipUnresolvable = new wxCheckBox(this, ID_CHK_SKIP_UNRESOLVABLE, _("Skip unresolvable"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_CHK_SKIP_UNRESOLVABLE"));
 
85
  chkSkipUnresolvable->SetValue(false);
 
86
  bszReplace->Add(chkSkipUnresolvable, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
 
87
  bszMainV->Add(bszReplace, 0, wxEXPAND|wxALIGN_LEFT|wxALIGN_TOP, 5);
 
88
  txtCrashLogContent = new wxTextCtrl(this, ID_TXT_CRASH_LOG_CONTENT, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE, wxDefaultValidator, _T("ID_TXT_CRASH_LOG_CONTENT"));
 
89
  txtCrashLogContent->SetMinSize(wxSize(450,200));
 
90
  wxFont txtCrashLogContentFont = wxSystemSettings::GetFont(wxSYS_ANSI_FIXED_FONT);
 
91
  if ( !txtCrashLogContentFont.Ok() ) txtCrashLogContentFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
 
92
  txtCrashLogContent->SetFont(txtCrashLogContentFont);
 
93
  bszMainV->Add(txtCrashLogContent, 1, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_LEFT|wxALIGN_TOP, 5);
 
94
  txtResult = new wxTextCtrl(this, ID_TXT_RESULT, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE, wxDefaultValidator, _T("ID_TXT_RESULT"));
 
95
  txtResult->SetMinSize(wxSize(450,200));
 
96
  wxFont txtResultFont = wxSystemSettings::GetFont(wxSYS_ANSI_FIXED_FONT);
 
97
  if ( !txtResultFont.Ok() ) txtResultFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
 
98
  txtResult->SetFont(txtResultFont);
 
99
  bszMainV->Add(txtResult, 1, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_LEFT|wxALIGN_TOP, 5);
 
100
  stlLine = new wxStaticLine(this, wxID_ANY, wxDefaultPosition, wxSize(10,-1), wxLI_HORIZONTAL, _T("wxID_ANY"));
 
101
  bszMainV->Add(stlLine, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_LEFT|wxALIGN_TOP, 5);
 
102
  btnOperate = new wxButton(this, ID_BTN_OPERATE, _("Operate"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BTN_OPERATE"));
 
103
  btnOperate->Disable();
 
104
  bszMainV->Add(btnOperate, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxALIGN_TOP|wxALIGN_CENTER_HORIZONTAL, 5);
 
105
  btnQuit = new wxButton(this, ID_BTN_QUIT, _("Quit"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, _T("ID_BTN_QUIT"));
 
106
  bszMainV->Add(btnQuit, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxALIGN_TOP|wxALIGN_CENTER_HORIZONTAL, 5);
 
107
  bszMainH->Add(bszMainV, 1, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 4);
 
108
  SetSizer(bszMainH);
 
109
  bszMainH->Fit(this);
 
110
  bszMainH->SetSizeHints(this);
 
111
 
 
112
  Connect(ID_CRASH_LOG,wxEVT_COMMAND_FILEPICKER_CHANGED,wxFileDirPickerEventHandler(Addr2LineUIDialog::OnCrashLogFile));
 
113
  Connect(ID_ADDR2LINE,wxEVT_COMMAND_FILEPICKER_CHANGED,wxFileDirPickerEventHandler(Addr2LineUIDialog::OnAddr2LineFile));
 
114
  Connect(ID_DIR_PREPEND,wxEVT_COMMAND_DIRPICKER_CHANGED,wxFileDirPickerEventHandler(Addr2LineUIDialog::OnDirPrependDir));
 
115
  Connect(ID_CHK_REPLACE,wxEVT_COMMAND_CHECKBOX_CLICKED,wxCommandEventHandler(Addr2LineUIDialog::OnReplaceClick));
 
116
  Connect(ID_BTN_OPERATE,wxEVT_COMMAND_BUTTON_CLICKED,wxCommandEventHandler(Addr2LineUIDialog::OnOperateClick));
 
117
  Connect(ID_BTN_QUIT,wxEVT_COMMAND_BUTTON_CLICKED,wxCommandEventHandler(Addr2LineUIDialog::OnQuit));
 
118
  //*)
 
119
 
 
120
  mFileConfig.Read(wxT("CrashLog"),   &mCrashLog,   wxT("")); m_FPCrashLog->SetPath(mCrashLog);
 
121
  mFileConfig.Read(wxT("Addr2Line"),  &mAddr2Line,  wxT("")); m_FPAddr2Line->SetPath(mAddr2Line);
 
122
  mFileConfig.Read(wxT("DirPrepend"), &mDirPrepend, wxT("")); m_DPDirPrepend->SetPath(mDirPrepend);
 
123
 
 
124
  bool     Replace;          mFileConfig.Read(wxT("Replace"),          &Replace,          false  ); chkReplace->SetValue(Replace);
 
125
  if (Replace) { txtReplaceThis->Enable(); lblReplace->Enable(); txtReplaceThat->Enable(); }
 
126
  wxString ReplaceThis;      mFileConfig.Read(wxT("ReplaceThis"),      &ReplaceThis,      wxT("")); txtReplaceThis->SetValue(ReplaceThis);
 
127
  wxString ReplaceThat;      mFileConfig.Read(wxT("ReplaceThat"),      &ReplaceThat,      wxT("")); txtReplaceThat->SetValue(ReplaceThat);
 
128
 
 
129
  bool     SkipUnresolvable; mFileConfig.Read(wxT("SkipUnresolvable"), &SkipUnresolvable, false  ); chkSkipUnresolvable->SetValue(SkipUnresolvable);
 
130
}
 
131
 
 
132
Addr2LineUIDialog::~Addr2LineUIDialog()
 
133
{
 
134
  //(*Destroy(Addr2LineUIDialog)
 
135
  //*)
 
136
}
 
137
 
 
138
void Addr2LineUIDialog::OnCrashLogFile(wxFileDirPickerEvent& event)
 
139
{
 
140
  mCrashLog = event.GetPath();
 
141
 
 
142
  wxTextFile file(mCrashLog);
 
143
  if (file.Open())
 
144
  {
 
145
    mCrashLogFileContent.Clear();
 
146
    txtCrashLogContent->Clear();
 
147
    for (wxString line = file.GetFirstLine(); !file.Eof(); line = file.GetNextLine())
 
148
    {
 
149
      mCrashLogFileContent.Add(line);
 
150
      txtCrashLogContent->AppendText(line + wxT("\n"));
 
151
    }
 
152
 
 
153
    if (mCrashLogFileContent.Count()>0) btnOperate->Enable(); else btnOperate->Disable();
 
154
  }
 
155
  else
 
156
    wxMessageBox(wxT("Error: File could not be opened."), wxT("Addr2LineUI"), wxOK|wxICON_ERROR, this);
 
157
}
 
158
 
 
159
void Addr2LineUIDialog::OnAddr2LineFile(wxFileDirPickerEvent& event)
 
160
{
 
161
  mAddr2Line = event.GetPath();
 
162
}
 
163
 
 
164
void Addr2LineUIDialog::OnDirPrependDir(wxFileDirPickerEvent& event)
 
165
{
 
166
  mDirPrepend = event.GetPath();
 
167
}
 
168
 
 
169
void Addr2LineUIDialog::OnReplaceClick(wxCommandEvent& event)
 
170
{
 
171
  if (event.IsChecked())
 
172
  { txtReplaceThis->Enable();  lblReplace->Enable();  txtReplaceThat->Enable();  }
 
173
  else
 
174
  { txtReplaceThis->Disable(); lblReplace->Disable(); txtReplaceThat->Disable(); }
 
175
}
 
176
 
 
177
void Addr2LineUIDialog::OnOperateClick(wxCommandEvent& WXUNUSED(event))
 
178
{
 
179
  // Style w/  debug symbols:
 
180
  /*
 
181
004013AE 00000008 60000000 40166666  sample_d.exe!Function  [C:\Devel\CodeBlocks\MinGW\bin\DrMinGW\demo/sample.cpp @ 10]
 
182
        ...
 
183
 
 
184
        static void Function(int i, double j, const char * pszString) {
 
185
>           sscanf("12345", "%i", (int *)1);
 
186
        }
 
187
 
 
188
        ...
 
189
 
 
190
00401CCE 00000004 40B33333 0028FF08  sample_d.exe!StaticMethod  [C:\Devel\CodeBlocks\MinGW\bin\DrMinGW\demo/sample.cpp @ 15]
 
191
        ...
 
192
        struct Class {
 
193
            static void StaticMethod(int i, float j) {
 
194
>               Function(i * 2, j, "Hello");
 
195
            }
 
196
 
 
197
        ...
 
198
  */
 
199
 
 
200
  // Sytle w/o debug symbols:
 
201
  /*
 
202
004013AE 00000008 60000000 40166666  sample_r.exe!Function(int, double, char const*)
 
203
00401CCE 00000004 40B33333 0028FF08  sample_r.exe!Class::StaticMethod(int, float)
 
204
  */
 
205
 
 
206
  // The address element "XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX " needs to be removed later, compute size here.
 
207
  wxRegEx reAddr32(wxT("([A-Fa-f0-9]{8})"));  wxString tag32(wxT("AddrPC   Params"));         size_t len32 = 4*8 +4; // 4 times 8bit  address + 4 times space
 
208
  wxRegEx reAddr64(wxT("([A-Fa-f0-9]{16})")); wxString tag64(wxT("AddrPC           Params")); size_t len64 = 4*16+4; // 4 times 16bit address + 4 times space
 
209
  bool is64Bit = false;
 
210
  txtResult->Clear();
 
211
 
 
212
  txtResult->AppendText(wxT("Working directory is '") + wxGetCwd() + wxT("'.\n"));
 
213
 
 
214
 
 
215
  bool operate_line = false;
 
216
  for (size_t i=0; i<mCrashLogFileContent.Count(); i++)
 
217
  {
 
218
    wxString line = mCrashLogFileContent.Item(i);
 
219
    if (line.IsSameAs(tag32))
 
220
    {
 
221
      txtResult->AppendText(wxT("*************************************\n"));
 
222
      txtResult->AppendText(wxT("* Found (another) 32 bit call stack *\n"));
 
223
      txtResult->AppendText(wxT("*************************************\n"));
 
224
      operate_line = true;
 
225
      continue;
 
226
    }
 
227
    else if (line.IsSameAs(tag64))
 
228
    {
 
229
      txtResult->AppendText(wxT("*************************************\n"));
 
230
      txtResult->AppendText(wxT("* Found (another) 64 bit call stack *\n"));
 
231
      txtResult->AppendText(wxT("*************************************\n"));
 
232
      operate_line = true;
 
233
      is64Bit = true;
 
234
      continue;
 
235
    }
 
236
 
 
237
    if (!operate_line)
 
238
      continue;
 
239
 
 
240
    line = line.Trim(true).Trim(false);
 
241
    if (line.IsEmpty())
 
242
      continue;
 
243
 
 
244
    if (!is64Bit && !reAddr32.Matches(line) )
 
245
      continue;
 
246
    if ( is64Bit && !reAddr64.Matches(line) )
 
247
      continue;
 
248
 
 
249
    wxString theAddr;
 
250
    wxString theFile;
 
251
 
 
252
 
 
253
    // Obtain address
 
254
    if (is64Bit)
 
255
    {
 
256
      for (size_t j=1; j<=reAddr64.GetMatchCount(); j++)
 
257
      {
 
258
        switch (j)
 
259
        {
 
260
          case 1: { theAddr = reAddr64.GetMatch(line, 1); } break;
 
261
          case 2: // fall through
 
262
          case 3: // fall through
 
263
          case 4: // fall through
 
264
          default: break;
 
265
        }
 
266
      }
 
267
    }
 
268
    else // 32 bit
 
269
    {
 
270
      for (size_t j=1; j<=reAddr32.GetMatchCount(); j++)
 
271
      {
 
272
        switch (j)
 
273
        {
 
274
          case 1: { theAddr = reAddr32.GetMatch(line, 1); } break;
 
275
          case 2: // fall through
 
276
          case 3: // fall through
 
277
          case 4: // fall through
 
278
          default: break;
 
279
        }
 
280
      }
 
281
    }
 
282
 
 
283
    // Verify address
 
284
    if (theAddr.IsEmpty())
 
285
    {
 
286
      txtResult->AppendText(wxT("Skipping empty address '") + line + wxT("'\n"));
 
287
      continue;
 
288
    }
 
289
 
 
290
    // Remove "XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX "
 
291
    line = line.Right(line.Length() - (is64Bit ? len64 : len32)).Trim(true).Trim(false) ; // 8 times address + 8 times space
 
292
    wxString sep = wxT("!");
 
293
    int sep_pos = line.Find(wxT('!'), true);
 
294
    if (sep_pos!=wxNOT_FOUND)
 
295
      theFile = line.SubString(0,sep_pos-1);
 
296
 
 
297
    // Verify file
 
298
    if (theFile.IsEmpty())
 
299
    {
 
300
      txtResult->AppendText(wxT("Skipping address '") + theAddr + wxT("' for unknown file : '") + theFile + wxT("'\n"));
 
301
      continue;
 
302
    }
 
303
 
 
304
    // prepend directory if requested
 
305
    if (!mDirPrepend.IsEmpty())
 
306
      theFile = mDirPrepend + wxFILE_SEP_PATH + theFile;
 
307
 
 
308
    // replacements in command (if any):
 
309
    if (chkReplace->IsChecked())
 
310
    {
 
311
      wxString repl_this = txtReplaceThis->GetValue();
 
312
      wxString repl_that = txtReplaceThat->GetValue();
 
313
      // avoid endless loops
 
314
      if (   !repl_this.IsSameAs(repl_that)
 
315
          && !(   repl_this.Trim(true).Trim(false).IsEmpty()
 
316
               && repl_that.Trim(true).Trim(false).IsEmpty() )
 
317
          && !(repl_this.Trim(true).Trim(false).IsSameAs(
 
318
                 repl_that.Trim(true).Trim(false)) ) )
 
319
      {
 
320
        theFile.Replace(repl_this, repl_that);
 
321
      }
 
322
      else
 
323
      {
 
324
        wxMessageBox(wxT("Error: Invalid setup for replacements (would cause a loop)."), wxT("Addr2LineUI"), wxOK|wxICON_ERROR, this);
 
325
        chkReplace->SetValue(false);
 
326
      }
 
327
    }
 
328
 
 
329
    if ( !wxFileExists(theFile) )
 
330
    {
 
331
      txtResult->AppendText(wxT("Skipping non-existent file '") + theFile + wxT("'\n"));
 
332
      continue;
 
333
    }
 
334
 
 
335
    // apply file mask if needed
 
336
    if (theFile.Contains(wxT(" "))) theFile = wxT("\"") + theFile + wxT("\"");
 
337
 
 
338
    // compute (initial) command line argument to addr2line
 
339
    wxString command_args = wxT(" -C -e ") + theFile + wxT(" ") + theAddr;
 
340
    // Now prepend the addr2line tool and compile the full command
 
341
    wxString command      = mAddr2Line + command_args;
 
342
 
 
343
    { // BEGIN Lifetime of wxWindowDisabler and wxBusyInfo
 
344
      wxWindowDisabler disableAll;
 
345
      wxBusyInfo       wait(wxT("Please wait, operating:\n") + command);
 
346
 
 
347
      wxArrayString output, error;
 
348
      long ret = wxExecute(command, output, error); // sync process
 
349
      if (ret==-1)
 
350
      {
 
351
        txtResult->AppendText(command + wxT(":\n"));
 
352
        txtResult->AppendText(wxT("-1 for: ") + command + wxT("\n"));
 
353
        txtResult->AppendText(wxT("----------------------------------------\n"));
 
354
      }
 
355
      else if (!error.IsEmpty())
 
356
      {
 
357
        txtResult->AppendText(command + wxT(":\n"));
 
358
        txtResult->AppendText(wxT("Error for: ") + command + wxT("\n:"));
 
359
        for (size_t j=0; j<error.Count(); j++)
 
360
          txtResult->AppendText(error.Item(j) + wxT("\n"));
 
361
        txtResult->AppendText(wxT("----------------------------------------\n"));
 
362
      }
 
363
      else
 
364
      {
 
365
        bool do_show = true;
 
366
        if (chkSkipUnresolvable->IsChecked())
 
367
        {
 
368
          if (output.Count()>0 && output.Item(0).Contains(wxT("??:0")))
 
369
            do_show = false;
 
370
        }
 
371
 
 
372
        if (do_show)
 
373
        {
 
374
          txtResult->AppendText(command + wxT(":\n"));
 
375
          txtResult->AppendText(theFile + wxT("[") + theAddr + wxT("]:\n"));
 
376
          for (size_t j=0; j<output.Count(); j++)
 
377
            txtResult->AppendText(output.Item(j) + wxT("\n"));
 
378
          txtResult->AppendText(wxT("----------------------------------------\n"));
 
379
        }
 
380
      }
 
381
    }// END Lifetime of wxWindowDisabler and wxBusyInfo
 
382
  }// for
 
383
}
 
384
 
 
385
void Addr2LineUIDialog::OnQuit(wxCommandEvent& WXUNUSED(event))
 
386
{
 
387
  mFileConfig.Write(wxT("CrashLog"),         mCrashLog                       );
 
388
  mFileConfig.Write(wxT("Addr2Line"),        mAddr2Line                      );
 
389
  mFileConfig.Write(wxT("DirPrepend"),       mDirPrepend                     );
 
390
  mFileConfig.Write(wxT("Replace"),          chkReplace->IsChecked()         );
 
391
  mFileConfig.Write(wxT("ReplaceThis"),      txtReplaceThis->GetValue()      );
 
392
  mFileConfig.Write(wxT("ReplaceThat"),      txtReplaceThat->GetValue()      );
 
393
  mFileConfig.Write(wxT("SkipUnresolvable"), chkSkipUnresolvable->IsChecked());
 
394
 
 
395
  EndModal(wxID_OK);
 
396
  Destroy();
 
397
}