Code::Blocks  SVN r11506
gdb_commands.h
Go to the documentation of this file.
1 /*
2  * This file is part of the Code::Blocks IDE and licensed under the GNU General Public License, version 3
3  * http://www.gnu.org/licenses/gpl-3.0.html
4  */
5 
6 #ifndef GDB_DEBUGGER_COMMANDS_H
7 #define GDB_DEBUGGER_COMMANDS_H
8 
9 // get rid of wxWidgets debug ugliness
10 #ifdef new
11  #undef new
12 #endif
13 
14 #include <map>
15 
16 #include <wx/string.h>
17 #include <wx/regex.h>
18 #include <wx/tipwin.h>
19 #include <wx/tokenzr.h>
20 
21 #include <cbeditor.h>
22 #include <cbdebugger_interfaces.h>
23 #include <configmanager.h>
24 #include <globals.h>
25 #include <manager.h>
26 #include <editormanager.h>
27 #include <infowindow.h>
28 #include <logmanager.h>
29 #include <macrosmanager.h>
30 
31 #include "debugger_defs.h"
32 #include "debuggergdb.h"
33 #include "gdb_driver.h"
34 #include "remotedebugging.h"
35 #include "parsewatchvalue.h"
36 
37 namespace
38 {
39  template <typename T>
40  T wxStrHexTo(const wxString &str)
41  {
42  T ret = 0; // return
43  std::size_t count = 0; // how many characters we've converted
44  std::size_t pos = 0; // string position
45 
46  // if it begins with 0x or 0X, just ignore it
47  if (str[pos] == _T('0'))
48  {
49  ++pos;
50 
51  if (str[pos] == _T('x') || str[pos] == _T('X'))
52  {
53  ++pos; // start after the x or X
54  }
55 
56  while (str[pos] == _T('0')) // skip all zeros
57  {
58  ++pos;
59  }
60  }
61 
62  while (count < sizeof(T) * 2) // be sure we don't keep adding more to ret
63  {
64  #if wxCHECK_VERSION(3, 0, 0)
65  switch (str[pos].GetValue())
66  #else
67  switch (str[pos])
68  #endif
69  {
70  case _T('0'):
71  case _T('1'):
72  case _T('2'):
73  case _T('3'):
74  case _T('4'):
75  case _T('5'):
76  case _T('6'):
77  case _T('7'):
78  case _T('8'):
79  case _T('9'):
80  ret <<= 4;
81  ret |= str[pos] - _T('0');
82  ++count;
83  break;
84 
85  case _T('a'):
86  case _T('b'):
87  case _T('c'):
88  case _T('d'):
89  case _T('e'):
90  case _T('f'):
91  ret <<= 4;
92  ret |= str[pos] - _T('a') + 10;
93  ++count;
94  break;
95 
96  case _T('A'):
97  case _T('B'):
98  case _T('C'):
99  case _T('D'):
100  case _T('E'):
101  case _T('F'):
102  ret <<= 4;
103  ret |= str[pos] - _T('A') + 10;
104  ++count;
105  break;
106 
107  default: // whatever we find that doesn't match ends the conversion
108  return ret;
109  }
110 
111  ++pos;
112  }
113 
114  return ret;
115  }
116 }
117 
118 //#0 wxEntry () at main.cpp:5
119 //#8 0x77d48734 in USER32!GetDC () from C:\WINDOWS\system32\user32.dll
120 //#9 0x001b04fe in ?? ()
121 //#30 0x00403c0a in WinMain (hInstance=0x400000, hPrevInstance=0x0, lpCmdLine=0x241ef9 "", nCmdShow=10) at C:/Devel/wxSmithTest/app.cpp:297
122 //#31 0x004076ca in main () at C:/Devel/wxWidgets-2.6.1/include/wx/intl.h:555
123 //#50 0x00410c8c in one::~one() (this=0x3d24c8) at main.cpp:14
124 //#11 0x00406810 in main ()
125 static wxRegEx reBT0(_T("#([0-9]+)[ \t]+(.+)[ \t]at[ \t](.+):([0-9]+)")); // case #0
126 static wxRegEx reBT1(_T("#([0-9]+)[ \t]+0x([A-Fa-f0-9]+)[ \t]+in[ \t]+(.+)[ \t]+(\\([^)]*\\))[ \t]")); // all other cases (gdb 6.3)
127 static wxRegEx reBTX(_T("#([0-9]+)[ \t]+0x([A-Fa-f0-9]+)[ \t]+in[ \t]+([^(]+)[ \t]*(\\([^)]*\\)[ \t]*\\([^)]*\\))")); // all other cases (gdb 5.2)
128 static wxRegEx reBT2(_T("\\)[ \t]+[atfrom]+[ \t]+(.*):([0-9]+)"));
129 static wxRegEx reBT3(_T("\\)[ \t]+[atfrom]+[ \t]+(.*)"));
130 static wxRegEx reBT4(_T("#([0-9]+)[ \\t]+(.+)[ \\t]in[ \\t](.+)")); // case #11
131 // Breakpoint 1 at 0x4013d6: file main.cpp, line 8.
132 static wxRegEx reBreakpoint(_T("Breakpoint ([0-9]+) at (0x[0-9A-Fa-f]+)"));
133 // GDB7.4 and before will return:
134 // Breakpoint 1 ("/home/jens/codeblocks-build/codeblocks-1.0svn/src/plugins/debuggergdb/gdb_commands.h:125) pending.
135 // GDB7.5 and later will return:
136 // Breakpoint 4 ("E:/code/cb/test_code/DebugDLLTest/TestDLL/dllmain.cpp:29") pending.
137 static wxRegEx rePendingBreakpoint(_T("Breakpoint ([0-9]+)[ \t]\\(\"(.+):([0-9]+)(\"?)\\)[ \t]pending\\."));
138 // Hardware assisted breakpoint 1 at 0x4013d6: file main.cpp, line 8.
139 static wxRegEx reHWBreakpoint(_T("Hardware assisted breakpoint ([0-9]+) at (0x[0-9A-Fa-f]+)"));
140 // Hardware watchpoint 1: expr
141 static wxRegEx reDataBreakpoint(_T("Hardware watchpoint ([0-9]+):.*"));
142 // Temporary breakpoint 2 at 0x401203: file /home/obfuscated/projects/tests/_cb_dbg/watches/main.cpp, line 115.
143 static wxRegEx reTemporaryBreakpoint(wxT("^[Tt]emporary[ \t]breakpoint[ \t]([0-9]+)[ \t]at.*"));
144 // eax 0x40e66666 1088841318
145 static wxRegEx reRegisters(_T("([A-z0-9]+)[ \t]+(0x[0-9A-Fa-f]+)[ \t]+(.*)"));
146 // wayne registers
147 //static wxRegEx reRegisters(_T("(R[0-9]+)[ \t]+(0x[0-9A-Fa-f]+)"));
148 // 0x00401390 <main+0>: push ebp
149 static wxRegEx reDisassembly(_T("(0x[0-9A-Za-z]+)[ \t]+<.*>:[ \t]+(.*)"));
150 // 9 if(argc > 1)
151 // 10 strcpy(filename, argv[1]) ;
152 // 11 else
153 // 12 strcpy(filename, "c:\\dev\\wxwidgets\\wxWidgets-2.8.10\\build\\msw\\../../src/something.c") ;
154 static wxRegEx reDisassemblySource(_T("([0-9]+)[ \t](.*)"));
155 //Stack level 0, frame at 0x22ff80:
156 // eip = 0x401497 in main (main.cpp:16); saved eip 0x4011e7
157 // source language c++.
158 // Arglist at 0x22ff78, args: argc=1, argv=0x3e3cb0
159 // Locals at 0x22ff78, Previous frame's sp is 0x22ff80
160 // Saved registers:
161 // ebx at 0x22ff6c, ebp at 0x22ff78, esi at 0x22ff70, edi at 0x22ff74, eip at 0x22ff7c
162 static wxRegEx reDisassemblyInit(_T("^[ \t]*Stack level [0-9]+, frame at (0x[A-Fa-f0-9]+):"));
163 // rip = 0x400931 in Bugtest<int> (/src/_cb_dbg/disassembly/main.cpp:6);
164 static wxRegEx reDisassemblyInitSymbol(_T("[ \t]*[er]ip[ \t]+=[ \t]+0x[0-9a-f]+[ \t]+in[ \t]+(.+)\\((.+):([0-9]+)\\);"));
165 static wxRegEx reDisassemblyInitFunc(_T("eip = (0x[A-Fa-f0-9]+) in ([^;]*)"));
166 // or32 variant
167 #ifdef __WXMSW__
168 static wxRegEx reDisassemblyInitFuncOR32(_T("PC = (0x[A-Fa-f0-9]+) in ([^;]*)"));
169 #else
170 // not used on linux, but make sure it exists otherwise compilation fails on linux
171 // if(platform::windows && m_disassemblyFlavor == _T("set disassembly-flavor or32")) blabla
172 static wxRegEx reDisassemblyInitFuncOR32(_T("PC = (0x[A-Fa-f0-9]+) in ([^;]*)"));
173 #endif
174 static wxRegEx reDisassemblyCurPC(_T("=>[ \t]+(0x[A-Fa-f0-9]+)"));
175 // Using the running image of child Thread 46912568064384 (LWP 7051).
176 static wxRegEx reInfoProgramThread(_T("\\(LWP[ \t]([0-9]+)\\)"));
177 // Using the running image of child process 10011.
178 static wxRegEx reInfoProgramProcess(_T("child process ([0-9]+)"));
179 // 2 Thread 1082132832 (LWP 8017) 0x00002aaaac5a2aca in pthread_cond_wait@@GLIBC_2.3.2 () from /lib/libpthread.so.0
180 //* 1 Thread 46912568064384 (LWP 7926) 0x00002aaaac76e612 in poll () from /lib/libc.so.6
181 static wxRegEx reInfoThreads(_T("(\\**)[ \t]*([0-9]+)[ \t](.*)"));
182 static wxRegEx reGenericHexAddress(_T("(0x[A-Fa-f0-9]+)"));
183 
184 static wxRegEx reExamineMemoryLine(wxT("[ \t]*(0x[0-9a-f]+)[ \t]<.+>:[ \t]+(.+)"));
185 
186 //mi output from 'nexti' is:
187 //"^Z^Zc:\dev\cb_exp\cb_debugviz\panels.cpp:409:12533:middle:0x4044f5"
188 //That's tough - guessing that path may/not always be full, i.e. might be
189 //only relative path sometimes(?), windows has possibility of
190 //the ':' in drive specifier... The "middle" can also be "beg"...
191 
192 //how to handle path that may include alternate data streams - appears easy with MI
193 //interface, not with (now current) CLI interface!!!
194 //This might handle the (windows only) leading drive prefix, but not embedded colons ini path!!!
195 //"\x1a\x1a(([a-zA-Z]:)?.*?):([0-9]*):([0-9]*):(.*?):(.*)"
196 //I've seen 'middle' and 'beg', but what if there's not line number info available?Hmm, doesn't
197 //appear to be another option of any sort for that (gdb annotate_source()
198 //"\x1a\x1a(([a-zA-Z]:)?.*?):([0-9]*):([0-9]*):(middle|beg|):(.*)"
199 //static wxRegEx reStepI(_T("\x1a\x1a.*?:([0-9]*):([0-9]*):(.*?):(.*)"));
200 //static wxRegEx reStepI(_T("\x1a\x1a(([a-zA-Z]:)?.*?):([0-9]*):([0-9]*):(middle|beg):(.*)"));
201 static wxRegEx reStepI(wxT("(((.*)[a-zA-Z]:)?.*)?:(\\d+):(middle|beg):(.*)"),
202 #ifndef __WXMAC__
203  wxRE_ADVANCED);
204 #else
205  wxRE_EXTENDED);
206 #endif
207 static wxRegEx reStepI2(_T("\\A(0x[A-Fa-f0-9]+)\\s+(\\d+)\\s+in (.*)"),
208 #ifndef __WXMAC__
209  wxRE_ADVANCED);
210 #else
211  wxRE_EXTENDED);
212 #endif
213 static wxRegEx reStepI3(_T("^(0x[A-Fa-f0-9]+) in (.*)? from (.*)"));
214 static wxRegEx reStepI4(_T("^(0x[A-Fa-f0-9]+) in (.*)? at (.*)"));
215 
216 static wxRegEx reNextI(_T("\x1a\x1a(([a-zA-Z]:)?.*?):([0-9]*):([0-9]*):(middle|beg):(.*)"),
217 #ifndef __WXMAC__
218  wxRE_ADVANCED);
219 #else
220  wxRE_EXTENDED);
221 #endif
222 
227 {
228  public:
231  : DebuggerCmd(driver)
232  {
233  m_Cmd << _T("directory ") << dir;
234  }
235  void ParseOutput(const wxString& output)
236  {
237  // Output:
238  // Warning: C:\Devel\tmp\console\111: No such file or directory.
239  // Source directories searched: <dir>;$cdir;$cwd
240  if (output.StartsWith(_T("Warning: ")))
241  m_pDriver->Log(output.BeforeFirst(_T('\n')));
242  }
243 };
244 
249 {
250  public:
253  : DebuggerCmd(driver)
254  {
255  m_Cmd << _T("file ") << file;
256  }
257  void ParseOutput(const wxString& output)
258  {
259  // Output:
260  // Reading symbols from C:\Devel\tmp\console/console.exe...done.
261  // or if it doesn't exist:
262  // console.exe: No such file or directory.
263 
264  // just log everything before the prompt
265  m_pDriver->Log(output.BeforeFirst(_T('\n')));
266  }
267 };
268 
273 {
274  public:
277  : DebuggerCmd(driver)
278  {
279  m_Cmd << _T("add-symbol-file ") << file;
280  }
281  void ParseOutput(const wxString& output)
282  {
283  // Output:
284  //
285  // add symbol table from file "console.exe" at
286  // Reading symbols from C:\Devel\tmp\console/console.exe...done.
287  //
288  // or if it doesn't exist:
289  // add symbol table from file "console.exe" at
290  // console.exe: No such file or directory.
291 
292  // just ignore the "add symbol" line and log the rest before the prompt
293  m_pDriver->Log(output.AfterFirst(_T('\n')).BeforeLast(_T('\n')));
294  }
295 };
296 
301 {
302  public:
305  : DebuggerCmd(driver)
306  {
307  m_Cmd << _T("set args ") << args;
308  }
309  void ParseOutput(cb_unused const wxString& output)
310  {
311  // No output
312  }
313 };
314 
319 {
320  public:
323  : DebuggerCmd(driver)
324  {
325  m_Cmd << _T("attach ") << wxString::Format(_T("%d"), pid);
326  m_pDriver->Log(wxString::Format(_("Attaching to program with pid: %d"), pid));
327  }
328  void ParseOutput(const wxString& output)
329  {
330  // Output:
331  // Attaching to process <pid>
332  // or,
333  // Can't attach to process.
334  wxArrayString lines = GetArrayFromString(output, _T('\n'));
335  for (unsigned int i = 0; i < lines.GetCount(); ++i)
336  {
337  if (lines[i].StartsWith(_T("Attaching")))
338  m_pDriver->Log(lines[i]);
339  else if (lines[i].StartsWith(wxT("Can't "))
340  || lines[i].StartsWith(wxT("Could not attach to process"))
341  || lines[i].StartsWith(wxT("ptrace: No such process")))
342  {
343  // log this and quit debugging
344  m_pDriver->Log(_("Attaching failed: ")+lines[i]);
347  }
348 // m_pDriver->DebugLog(lines[i]);
349  }
350  }
351 
352  bool IsContinueCommand() const override { return true; }
353 };
354 
359 {
360  public:
363  : DebuggerCmd(driver)
364  {
365  m_Cmd << _T("detach");
366  }
367  void ParseOutput(const wxString& output)
368  {
369  // Output:
370  // Attaching to process <pid>
371  wxArrayString lines = GetArrayFromString(output, _T('\n'));
372  for (unsigned int i = 0; i < lines.GetCount(); ++i)
373  {
374  if (lines[i].StartsWith(_T("Detaching")))
375  m_pDriver->Log(lines[i]);
376 // m_pDriver->DebugLog(lines[i]);
377  }
378  }
379 };
380 
388 {
389  cb::shared_ptr<DebuggerBreakpoint> m_BP;
390  public:
392  GdbCmd_AddBreakpointCondition(DebuggerDriver* driver, cb::shared_ptr<DebuggerBreakpoint> bp)
393  : DebuggerCmd(driver),
394  m_BP(bp)
395  {
396  m_Cmd << _T("condition ") << wxString::Format(_T("%ld"), (int) m_BP->index);
397  if (m_BP->useCondition)
398  m_Cmd << _T(" ") << m_BP->condition;
399  }
400  void ParseOutput(const wxString& output)
401  {
402  if (output.StartsWith(_T("No symbol ")))
403  {
404  wxString s = wxString::Format(_("While setting up custom conditions for breakpoint %ld (%s, line %d),\n"
405  "the debugger responded with the following error:\n"
406  "\nError: %s\n\n"
407  "Do you want to make this an un-conditional breakpoint?"),
408  m_BP->index,
409  m_BP->filename.c_str(),
410  m_BP->line + 1,
411  output.c_str());
412  if (cbMessageBox(s, _("Warning"), wxICON_WARNING | wxYES_NO) == wxID_YES)
413  {
414  // re-run this command but without a condition
415  m_BP->useCondition = false;
417  }
418  else if ( m_BP->alreadySet )
419  {
421  ((cbEditor*)Manager::Get()->GetEditorManager()->GetActiveEditor())->SetDebugLine(-1);
422  m_pDriver->Continue();
423  }
424  }
425 
426  }
427 };
428 
433 {
434  cb::shared_ptr<DebuggerBreakpoint> m_BP;
435  public:
437  GdbCmd_AddBreakpoint(DebuggerDriver* driver, cb::shared_ptr<DebuggerBreakpoint> bp)
438  : DebuggerCmd(driver),
439  m_BP(bp)
440  {
441  // gdb doesn't allow setting the bp number.
442  // instead, we must read it back in ParseOutput()...
443  m_BP->index = -1;
444 
445  if (m_BP->enabled)
446  {
447  if (m_BP->type == DebuggerBreakpoint::bptCode)//m_BP->func.IsEmpty())
448  {
449  wxString out = m_BP->filename;
450  // we add one to line, because scintilla uses 0-based line numbers, while gdb uses 1-based
451  if (!m_BP->temporary)
452  m_Cmd << _T("break ");
453  else
454  m_Cmd << _T("tbreak ");
455  m_Cmd << _T('"') << out << _T(":") << wxString::Format(_T("%d"), m_BP->line) << _T('"');
456  }
457  else if (m_BP->type == DebuggerBreakpoint::bptData)
458  {
459  if (m_BP->breakOnRead && m_BP->breakOnWrite)
460  m_Cmd << _T("awatch ");
461  else if (m_BP->breakOnRead)
462  m_Cmd << _T("rwatch ");
463  else
464  m_Cmd << _T("watch ");
465  m_Cmd << m_BP->breakAddress;
466  }
467  //GDB workaround
468  //Use function name if this is C++ constructor/destructor
469  else
470  {
471 // if (m_BP->temporary)
472 // cbThrow(_T("Temporary breakpoint on constructor/destructor is not allowed"));
473  m_Cmd << _T("rbreak ") << m_BP->func;
474  }
475  //end GDB workaround
476 
477  m_BP->alreadySet = true;
478  // condition and ignore count will be set in ParseOutput, where we 'll have the bp number
479  }
480  }
481  void ParseOutput(const wxString& output)
482  {
483  // possible outputs (we 're only interested in 1st and 2nd samples):
484  //
485  // Hardware watchpoint 1: expr
486  // Breakpoint 1 at 0x4013d6: file main.cpp, line 8.
487  // No line 100 in file "main.cpp".
488  // No source file named main2.cpp.
489  if (reBreakpoint.Matches(output))
490  {
491 // m_pDriver->DebugLog(wxString::Format(_("Breakpoint added: file %s, line %d"), m_BP->filename.c_str(), m_BP->line + 1));
492  if (!m_BP->func.IsEmpty())
493  m_pDriver->Log(_("GDB workaround for constructor/destructor breakpoints activated."));
494 
495  reBreakpoint.GetMatch(output, 1).ToLong(&m_BP->index);
496  reBreakpoint.GetMatch(output, 2).ToULong(&m_BP->address, 16);
497 
498  // conditional breakpoint
499  if (m_BP->useCondition && !m_BP->condition.IsEmpty())
500  {
502  }
503 
504  // ignore count
505  if (m_BP->useIgnoreCount && m_BP->ignoreCount > 0)
506  {
507  wxString cmd;
508  cmd << _T("ignore ") << wxString::Format(_T("%d"), (int) m_BP->index) << _T(" ") << wxString::Format(_T("%d"), (int) m_BP->ignoreCount);
510  }
511  }
512  else if (rePendingBreakpoint.Matches(output))
513  {
514  if (!m_BP->func.IsEmpty())
515  m_pDriver->Log(_("GDB workaround for constructor/destructor breakpoints activated."));
516 
517  rePendingBreakpoint.GetMatch(output, 1).ToLong(&m_BP->index);
518 
519  // conditional breakpoint
520  // condition can not be evaluated for pending breakpoints, so we only set a flag and do this later
521  if (m_BP->useCondition && !m_BP->condition.IsEmpty())
522  {
523  m_BP->wantsCondition = true;
524  }
525 
526  // ignore count
527  if (m_BP->useIgnoreCount && m_BP->ignoreCount > 0)
528  {
529  wxString cmd;
530  cmd << _T("ignore ") << wxString::Format(_T("%d"), (int) m_BP->index) << _T(" ") << wxString::Format(_T("%d"), (int) m_BP->ignoreCount);
532  }
533  }
534  else if (reDataBreakpoint.Matches(output))
535  {
536  reDataBreakpoint.GetMatch(output, 1).ToLong(&m_BP->index);
537  }
538  else if (reHWBreakpoint.Matches(output))
539  {
540  reHWBreakpoint.GetMatch(output, 1).ToLong(&m_BP->index);
541  reHWBreakpoint.GetMatch(output, 2).ToULong(&m_BP->address, 16);
542  }
543  else if (reTemporaryBreakpoint.Matches(output))
544  reTemporaryBreakpoint.GetMatch(output, 1).ToLong(&m_BP->index);
545  else
546  m_pDriver->Log(output); // one of the error responses
547 
549  }
550 };
551 
556 {
557  cb::shared_ptr<DebuggerBreakpoint> m_BP;
558  public:
560  GdbCmd_AddDataBreakpoint(DebuggerDriver* driver, cb::shared_ptr<DebuggerBreakpoint> bp)
561  : DebuggerCmd(driver),
562  m_BP(bp)
563  {
564  if (m_BP->enabled)
565  m_Cmd << _T("output &") << m_BP->breakAddress;
566  }
567  void ParseOutput(const wxString& output)
568  {
569  // Hardware watchpoint 1: expr
570  if (output.StartsWith(_T("No symbol ")) || output.StartsWith(_T("Attempt to ")))
571  m_pDriver->Log(output);
572  else
573  {
574  if (reGenericHexAddress.Matches(output))
575  {
576  wxString contents = reGenericHexAddress.GetMatch(output, 1);
577  m_BP->breakAddress = _T("*") + contents;
579  dbgManager->GetBreakpointDialog()->Reload();
580 
582  }
583  }
584  }
585 };
586 
591 {
592  public:
594  GdbCmd_RemoveBreakpoint(DebuggerDriver* driver, cb::shared_ptr<DebuggerBreakpoint> bp)
595  : DebuggerCmd(driver),
596  m_BP(bp)
597  {
598  if (!bp)
599  {
600  m_Cmd << _T("delete breakpoints");
601  return;
602  }
603  if (bp->index >= 0)
604  {
605  m_Cmd << _T("delete breakpoints ") << wxString::Format(_T("%d"), (int) bp->index);
606  }
607  }
608  void ParseOutput(const wxString& output)
609  {
610  if (!m_BP)
611  return;
612 
613  // This can crash because m_BP could already be deleted
614  // and if it isn't deleted already, it will be soon
615  // so there's no point in invalidating the bp number anyway
616 
617  // invalidate bp number
618 // m_BP->index = -1;
619 
620  if (!output.IsEmpty())
621  m_pDriver->Log(output);
622 // m_pDriver->DebugLog(wxString::Format(_("Breakpoint removed: file %s, line %d"), m_BP->filename.c_str(), m_BP->line + 1));
623  }
624 
625  cb::shared_ptr<DebuggerBreakpoint> m_BP;
626 };
627 
632 {
636  public:
637  GdbCmd_SetCatch(DebuggerDriver *driver, const wxString &type, int *resultIndex) :
638  DebuggerCmd(driver),
639  m_type(type),
640  m_resultIndex(resultIndex),
641  m_regExp(wxT("^Catchpoint[ \\t]([0-9]+)[ \\t]\\(") + type + wxT("\\)$"), wxRE_ADVANCED)
642  {
643  m_Cmd = wxT("catch ") + type;
644  }
645 
646  void ParseOutput(const wxString& output)
647  {
648  if (m_regExp.Matches(output))
649  {
650  long index;
651  m_regExp.GetMatch(output, 1).ToLong(&index);
652  *m_resultIndex = index;
653  }
654  }
655 };
656 
657 
662 {
663  public:
665  DebuggerContinueBaseCmd(driver, wxT("cont"))
666  {
667  }
668 
669  virtual void Action()
670  {
672  }
673 };
674 
676 {
677  public:
678  GdbCmd_Start(DebuggerDriver* driver, const wxString &cmd) :
679  DebuggerContinueBaseCmd(driver, cmd)
680  {
681  }
682 
683  virtual void ParseOutput(const wxString &output)
684  {
685  const wxArrayString &lines = GetArrayFromString(output, _T('\n'));
686  for (size_t ii = 0; ii < lines.GetCount(); ++ii)
687  {
688  if ( lines[ii].StartsWith(wxT("No symbol table loaded"))
689  || lines[ii].StartsWith(wxT("No executable file specified"))
690  || lines[ii].StartsWith(wxT("No executable specified"))
691  || lines[ii].StartsWith(wxT("Don't know how to run")))
692  {
693  // log this and quit debugging
694  m_pDriver->Log(_("Starting the debuggee failed: ")+lines[ii]);
697  }
698  }
699  }
700 };
701 
706 {
707  public:
709  : DebuggerCmd(driver)
710  {
711  m_Cmd << _T("info program");
712  }
713  void ParseOutput(const wxString& output)
714  {
715  wxString pid_str;
716  if (reInfoProgramThread.Matches(output))
717  pid_str = reInfoProgramThread.GetMatch(output, 1);
718  else if (reInfoProgramProcess.Matches(output))
719  pid_str = reInfoProgramProcess.GetMatch(output, 1);
720 
721  if (!pid_str.IsEmpty())
722  {
723  long pid;
724  if (pid_str.ToLong(&pid, 10) && pid != 0)
725  m_pDriver->SetChildPID(pid);
726  }
727  }
728 };
729 
734 {
735  public:
738  : DebuggerCmd(driver)
739  {
740  m_Cmd << _T("info threads");
741  }
742  void ParseOutput(const wxString& output)
743  {
744  m_pDriver->GetThreads().clear();
745  wxArrayString lines = GetArrayFromString(output, _T('\n'));
746  for (unsigned int i = 0; i < lines.GetCount(); ++i)
747  {
748 // m_pDriver->Log(lines[i]);
749  if (reInfoThreads.Matches(lines[i]))
750  {
751 // m_pDriver->Log(_T("MATCH!"));
752  wxString active = reInfoThreads.GetMatch(lines[i], 1);
753  active.Trim(true);
754  active.Trim(false);
755  wxString num = reInfoThreads.GetMatch(lines[i], 2);
756  wxString info = reInfoThreads.GetMatch(lines[i], 3);
757 
758  #if defined(_WIN64)
759  long long int number;
760  num.ToLongLong(&number, 10);
761  #else
762  long number;
763  num.ToLong(&number, 10);
764  #endif
765 
767  threads.push_back(cb::shared_ptr<cbThread>(new cbThread(!active.empty(), number, info)));
768  }
769  }
771  }
772 };
773 
777 class GdbCmd_Watch : public DebuggerCmd
778 {
779  cb::shared_ptr<GDBWatch> m_watch;
780  public:
781  GdbCmd_Watch(DebuggerDriver* driver, cb::shared_ptr<GDBWatch> watch) :
782  DebuggerCmd(driver),
783  m_watch(watch)
784  {
785  wxString type;
786  wxString symbol;
787 
788  m_watch->GetSymbol(symbol);
789  m_watch->GetType(type);
790  type.Trim(true);
791  type.Trim(false);
792  m_Cmd << _T("output ");
793  switch (m_watch->GetFormat())
794  {
795  case Decimal: m_Cmd << _T("/d "); break;
796  case Unsigned: m_Cmd << _T("/u "); break;
797  case Hex: m_Cmd << _T("/x "); break;
798  case Binary: m_Cmd << _T("/t "); break;
799  case Char: m_Cmd << _T("/c "); break;
800  case Float: m_Cmd << _T("/f "); break;
801  case Last:
802  case Any:
803  case Undefined:
804  default: break;
805  }
806 
807  if (g_DebugLanguage == dl_Cpp)
808  {
809  // auto-set array types
810  if (!m_watch->IsArray() && m_watch->GetFormat() == Undefined && type.Contains(_T('[')))
811  m_watch->SetArray(true);
812 
813  if (m_watch->IsArray() && m_watch->GetArrayCount() > 0)
814  {
815  m_Cmd << wxT("(") << symbol << wxT(")");
816  m_Cmd << wxString::Format(_T("[%d]@%d"), m_watch->GetArrayStart(), m_watch->GetArrayCount());
817  }
818  else
819  m_Cmd << symbol;
820  }
821  else // (g_DebugLanguage == dl_Fortran)
822  {
823  if (m_watch->IsArray() && m_watch->GetArrayCount() > 0)
824  {
825  if (m_watch->GetArrayStart() < 1)
826  m_watch->SetArrayParams(1, m_watch->GetArrayCount());
827  m_Cmd << symbol;
828  m_Cmd << wxString::Format(_T("(%d)@%d"), m_watch->GetArrayStart(), m_watch->GetArrayCount());
829  }
830  else
831  m_Cmd << symbol;
832  }
833  }
834  void ParseOutput(const wxString& output)
835  {
836  wxString w = output;
837  w.Trim(true);
838  w.Trim(false);
839 
840  if (!ParseGDBWatchValue(m_watch, w))
841  {
842  wxString symbol;
843  m_watch->GetSymbol(symbol);
844  wxString const &msg = wxT("Parsing GDB output failed for '") + symbol + wxT("'!");
845  m_watch->SetValue(msg);
847  }
848  }
849 };
850 
855 {
856  cb::shared_ptr<GDBWatch> m_watch;
858  public:
859  GdbCmd_FindWatchType(DebuggerDriver* driver, cb::shared_ptr<GDBWatch> watch, bool firstTry = true) :
860  DebuggerCmd(driver),
861  m_watch(watch),
862  m_firstTry(firstTry)
863  {
864  if (m_firstTry)
865  m_Cmd << wxT("whatis ");
866  else
867  m_Cmd << wxT("whatis &");
868  wxString symbol;
869  m_watch->GetSymbol(symbol);
870  m_Cmd << symbol;
871  }
872  void ParseOutput(const wxString& output)
873  {
874  // happens, when wxString is passed as const reference parameter
875  if (m_firstTry && output == wxT("Attempt to take contents of a non-pointer value."))
876  {
878  return;
879  }
880  if (output.StartsWith(wxT("No symbol \"")) && output.EndsWith(wxT("\" in current context.")))
881  {
882  m_watch->RemoveChildren();
883  m_watch->SetType(wxEmptyString);
884  m_watch->SetValue(_("Not available in current context!"));
885  return;
886  }
887 
888  // examples:
889  // type = wxString
890  // type = const wxChar
891  // type = Action *
892  // type = bool
893 
894  wxString tmp = output.AfterFirst(_T('='));
895  if (!m_firstTry && !tmp.empty())
896  tmp = tmp.substr(0, tmp.length() - 1);
897 
898  wxString old_type;
899  m_watch->GetType(old_type);
900  if(old_type != tmp)
901  {
902  m_watch->RemoveChildren();
903  m_watch->SetType(tmp);
904  m_watch->SetValue(wxEmptyString);
905  }
907  }
908 };
909 
914 {
920  public:
925  GdbCmd_TooltipEvaluation(DebuggerDriver* driver, const wxString& what, const wxRect& tiprect,
926  const wxString& w_type = wxEmptyString, const wxString& address = wxEmptyString)
927  : DebuggerCmd(driver),
928  m_WinRect(tiprect),
929  m_What(what),
930  m_Type(w_type),
931  m_Address(address),
932  m_autoDereferenced(false)
933  {
934  m_Type.Trim(true);
935  m_Type.Trim(false);
936  if (IsPointerType(w_type))
937  {
938  m_What = wxT("*") + m_What;
939  m_autoDereferenced = true;
940  }
941 
942  m_Cmd << wxT("output ");
943  m_Cmd << m_What;
944  }
945  void ParseOutput(const wxString& output)
946  {
947  wxString contents = output;
948  contents.Trim(true);
949  contents.Trim(false);
950 
951  cb::shared_ptr<GDBWatch> watch(new GDBWatch(m_What));
952  watch->SetType(m_Type);
953 
954  ParseGDBWatchValue(watch, contents);
955  if (!m_Address.empty() && m_autoDereferenced)
956  {
957  // Add the address of the expression only if the value is empty, this
958  // way we won't override the value of the dereferenced expression.
959  wxString value;
960  watch->GetValue(value);
961  if (value.empty())
962  watch->SetValue(m_Address);
963  else if (!value.Contains(m_Address))
964  watch->SetValue(m_Address + wxT(": ") + value);
965  }
966  watch->SetForTooltip(true);
967  if (watch->GetChildCount() > 0)
968  watch->Expand(true);
969 
970  if (Manager::Get()->GetDebuggerManager()->ShowValueTooltip(watch, m_WinRect))
972  }
973 };
974 
979 {
983  public:
985  GdbCmd_FindTooltipAddress(DebuggerDriver* driver, const wxString& what, const wxRect& tiprect, const wxString& w_type = wxEmptyString)
986  : DebuggerCmd(driver),
987  m_WinRect(tiprect),
988  m_What(what),
989  m_Type(w_type)
990  {
991  if (m_Type.IsEmpty())
992  {
994  return;
995  }
996  m_Cmd << _T("output ");
997  if (m_Type.Last() != _T('*'))
998  m_Cmd << _T('&');
999  m_Cmd << m_What;
1000  }
1001  void ParseOutput(const wxString& output)
1002  {
1003  // examples:
1004  // type = wxString
1005  // type = const wxChar
1006  // type = Action *
1007  // type = bool
1008 
1009  wxString tmp;
1010  if (reGenericHexAddress.Matches(output))
1011  tmp = reGenericHexAddress.GetMatch(output, 1);
1012 
1013  // add the actual evaluation command with high priority
1014  m_pDriver->QueueCommand(new GdbCmd_TooltipEvaluation(m_pDriver, m_What, m_WinRect, m_Type, tmp), DebuggerDriver::High);
1015  }
1016 };
1017 
1022 {
1025  static bool singleUsage; // special flag to avoid launching multiple tooltips because of event chain latency
1026  public:
1028  GdbCmd_FindTooltipType(DebuggerDriver* driver, const wxString& what, const wxRect& tiprect)
1029  : DebuggerCmd(driver),
1030  m_WinRect(tiprect),
1031  m_What(what)
1032  {
1033  if (!singleUsage)
1034  {
1035  singleUsage = true;
1036  m_Cmd << _T("whatis ");
1037  m_Cmd << m_What;
1038  }
1039  }
1041  {
1042  singleUsage = false;
1043  }
1044  void ParseOutput(const wxString& output)
1045  {
1046  // examples:
1047  // type = wxString
1048  // type = const wxChar
1049  // type = Action *
1050  // type = bool
1051 
1052  wxString tmp = output.AfterFirst(_T('='));
1053  tmp.Trim(false);
1054 
1055  // add the actual evaluation command with high priority
1057  }
1058 };
1059 bool GdbCmd_FindTooltipType::singleUsage = false;
1060 
1062 {
1063  cb::shared_ptr<GDBWatch> m_watch;
1065  public:
1066  GdbCmd_LocalsFuncArgs(DebuggerDriver* driver, cb::shared_ptr<GDBWatch> watch, bool doLocals) :
1067  DebuggerCmd(driver),
1068  m_watch(watch),
1069  m_doLocals(doLocals)
1070  {
1071  if (m_doLocals)
1072  m_Cmd = wxT("info locals");
1073  else
1074  m_Cmd = wxT("info args");
1075  }
1076  void ParseOutput(const wxString& output)
1077  {
1078  if ((m_doLocals && output == wxT("No locals.")) || (!m_doLocals && output == wxT("No arguments.")))
1079  {
1080  m_watch->RemoveChildren();
1081  return;
1082  }
1083 
1084  std::vector<GDBLocalVariable> watchStrings;
1085  TokenizeGDBLocals(watchStrings, output);
1086 
1087  m_watch->MarkChildsAsRemoved();
1088  for (std::vector<GDBLocalVariable>::const_iterator it = watchStrings.begin(); it != watchStrings.end(); ++it)
1089  {
1090  if (it->error)
1091  continue;
1092  cb::shared_ptr<GDBWatch> watch = AddChild(m_watch, it->name);
1093  ParseGDBWatchValue(watch, it->value);
1094  }
1095  m_watch->RemoveMarkedChildren();
1096  }
1097 };
1098 
1105 {
1107  public:
1108  int AddrChgMode() { return m_addrchgmode; }
1109  GdbCmd_ChangeFrame(DebuggerDriver* driver, int frameno, int p_addrchgmode=1)
1110  : DebuggerCmd(driver)
1111  ,m_addrchgmode(p_addrchgmode) //1 means do not change disassembly address
1112  {
1113  m_Cmd << _T("frame ") << frameno;
1114  }
1115  void ParseOutput(const wxString& output)
1116  {
1117  m_pDriver->Log(output);
1118  }
1119 };
1124 {
1125  public:
1128  : DebuggerCmd(driver)
1129  {
1130  m_Cmd << _T("bt 30");
1131  }
1132  void ParseOutput(const wxString& output)
1133  {
1134  int validFrameNumber = -1;
1135  cbStackFrame validSF;
1136 
1137  m_pDriver->GetStackFrames().clear();
1138  wxArrayString lines = GetArrayFromString(output, _T('\n'));
1139  for (unsigned int i = 0; i < lines.GetCount(); ++i)
1140  {
1141  cbStackFrame sf;
1142  bool hasLineInfo;
1143  bool matched = MatchLine(sf, hasLineInfo, lines[i]);
1144  if (matched)
1145  {
1146  if (hasLineInfo && validFrameNumber == -1)
1147  {
1148  validSF = sf;
1149  validFrameNumber = sf.GetNumber();
1150  }
1151  m_pDriver->GetStackFrames().push_back(cb::shared_ptr<cbStackFrame>(new cbStackFrame(sf)));
1152  }
1153  }
1154  if (validFrameNumber > 0) // if it's 0, then the driver already synced the editor
1155  {
1157  if (!autoSwitch)
1158  {
1159  long line;
1160 
1161  // replace the valid stack frame with the first frame or the user selected frame
1162  if (!m_pDriver->GetStackFrames().empty())
1163  {
1164  if (m_pDriver->GetUserSelectedFrame() != -1)
1165  {
1166  validFrameNumber = m_pDriver->GetUserSelectedFrame();
1168 
1169  if (validFrameNumber >= 0 && validFrameNumber <= static_cast<int>(frames.size()))
1170  validSF = *frames[validFrameNumber];
1171  else if (!frames.empty())
1172  validSF = *frames.front();
1173  }
1174  }
1175  if (validSF.GetLine().ToLong(&line))
1176  {
1177  m_pDriver->Log(wxString::Format(_T("Displaying first frame with valid source info (#%d)"), validFrameNumber));
1178  m_pDriver->ShowFile(validSF.GetFilename(), line);
1179  }
1180  }
1181  else
1182  {
1183  if (m_pDriver->GetUserSelectedFrame() != -1)
1184  validFrameNumber = m_pDriver->GetUserSelectedFrame();
1185  // can't call m_pDriver->SwitchToFrame() here
1186  // because it causes a cascade update, never stopping...
1187  //m_pDriver->Log(wxString::Format(_T("Switching to frame #%d which has valid source info"), validFrameNumber));
1188 
1189  //The following output:
1190  //>>>>>>cb_gdb:
1191  //> frame 1
1192  //#1 0x6f826722 in wxInitAllImageHandlers () at ../../src/common/imagall.cpp:29
1193  //^Z^ZC:\dev\wxwidgets\wxWidgets-2.8.10\build\msw/../../src/common/imagall.cpp:29:961:beg:0x6f826722
1194  //>>>>>>cb_gdb:
1195  //matches output from both break and frame responses. We need to ignore it
1196  //for a frame command to avoid incorrect disassembly displays when stepping instructions.
1197  m_pDriver->QueueCommand(new GdbCmd_ChangeFrame(m_pDriver, validFrameNumber));
1198  m_pDriver->SetCurrentFrame(validFrameNumber, false);
1199  }
1200  }
1202  }
1203 
1204  static bool MatchLine(cbStackFrame &sf, bool &hasLineInfo, const wxString &line)
1205  {
1206  hasLineInfo = false;
1207  // reBT1 matches frame number, address, function and args (common to all formats)
1208  // reBT2 matches filename and line (optional)
1209  // reBT3 matches filename only (for DLLs) (optional)
1210 
1211  // #0 main (argc=1, argv=0x3e2440) at my main.cpp:15
1212  if (reBTX.Matches(line))
1213  {
1214  long int number;
1215  reBTX.GetMatch(line, 1).ToLong(&number);
1216  sf.SetNumber(number);
1218  sf.SetSymbol(reBTX.GetMatch(line, 3) + reBTX.GetMatch(line, 4));
1219  }
1220  else if (reBT1.Matches(line))
1221  {
1222  long int number;
1223  reBT1.GetMatch(line, 1).ToLong(&number);
1224  sf.SetNumber(number);
1226  sf.SetSymbol(reBT1.GetMatch(line, 3) + reBT1.GetMatch(line, 4));
1227  }
1228  else if (reBT0.Matches(line))
1229  {
1230  long int number;
1231  reBT0.GetMatch(line, 1).ToLong(&number);
1232  sf.SetNumber(number);
1233  sf.SetAddress(0);
1234  sf.SetSymbol(reBT0.GetMatch(line, 2));
1235  sf.SetFile(reBT0.GetMatch(line, 3), wxEmptyString);
1236  }
1237  else if (reBT4.Matches(line))
1238  {
1239  long int number;
1240  reBT4.GetMatch(line, 1).ToLong(&number);
1241  sf.SetNumber(number);
1243  sf.SetSymbol(reBT4.GetMatch(line, 3));
1244  }
1245  else
1246  return false;
1247 
1248  sf.MakeValid(true);
1249  if (reBT2.Matches(line))
1250  {
1251  sf.SetFile(reBT2.GetMatch(line, 1), reBT2.GetMatch(line, 2));
1252  hasLineInfo = true;
1253  }
1254  else if (reBT3.Matches(line))
1255  sf.SetFile(reBT3.GetMatch(line, 1), wxEmptyString);
1256  return true;
1257  }
1258 };
1259 
1264 {
1266 
1267  public:
1270  // only tested on mingw/pc/win env
1271  GdbCmd_InfoRegisters(DebuggerDriver* driver, wxString disassemblyFlavor = wxEmptyString) :
1272  DebuggerCmd(driver),
1273  m_disassemblyFlavor(disassemblyFlavor)
1274  {
1275  m_Cmd << _T("info registers");
1276  };
1277 
1278  void ParseOutput(const wxString& output)
1279  {
1280  // output is a series of:
1281  //
1282  // eax 0x40e66666 1088841318
1283  // ecx 0x40cbf0 4246512
1284  // edx 0x77c61ae8 2009471720
1285  // ebx 0x4000 16384
1286  // esp 0x22ff50 0x22ff50
1287  // ebp 0x22ff78 0x22ff78
1288  // esi 0x22ef80 2289536
1289  // edi 0x5dd3f4 6149108
1290  // eip 0x4013c9 0x4013c9
1291  // eflags 0x247 583
1292  // cs 0x1b 27
1293  // ss 0x23 35
1294  // ds 0x23 35
1295  // es 0x23 35
1296  // fs 0x3b 59
1297  // gs 0x0 0
1298 
1299  // or32 register string parser
1300  if(m_disassemblyFlavor == _T("set disassembly-flavor or32"))
1301  {
1302  ParseOutputFromOR32gdbPort(output);
1303  }
1304  else
1305  // use generic parser - this may work for other platforms or you may have to write your own
1306  {
1308 
1309  wxArrayString lines = GetArrayFromString(output, _T('\n'));
1310  for (unsigned int i = 0; i < lines.GetCount(); ++i)
1311  {
1312  if (reRegisters.Matches(lines[i]))
1313  {
1314  const wxString &addr = reRegisters.GetMatch(lines[i], 1);
1315  const wxString &hex = reRegisters.GetMatch(lines[i], 2);
1316  const wxString &interpreted = reRegisters.GetMatch(lines[i], 3);
1317  dialog->SetRegisterValue(addr, hex, interpreted);
1318  }
1319  }
1320  }
1321 
1322 // m_pDlg->Show(true);
1323 // m_pDriver->DebugLog(output);
1324  }
1325 
1327  {
1328 // (gdb) info reg
1329 // R0 R1 R2 R3 R4 R5 R6 R7
1330 // 00000000 f0016f2c f0016ff8 00000005 00000008 00004c84 ffffbfff 00000001
1331 // R8 R9 R10 R11 R12 R13 R14 R15
1332 // 00000001 00004ce0 0001e888 00000000 00000000 00000000 f0001754 00000014
1333 // R16 R17 R18 R19 R20 R21 R22 R23
1334 // 000000e1 00000000 00000003 00000000 8000000c 00000000 f0000870 00000000
1335 // R24 R25 R26 R27 R28 R29 R30 R31
1336 // 000000c0 00000000 00030021 00000000 00000000 00000000 00000000 f0016f2c
1337 
1338  // produce an array of alternate register/value string lines, each entry
1339  // is started on detecting a '\n'
1340  wxArrayString lines = GetArrayFromString(output, _T("\n"));
1341 
1342  // check for empty or short string
1343  if((output == _T("")) || (lines.GetCount()<2))
1344  {
1345  return;
1346  }
1348 
1349  for (unsigned int i = 0; i < lines.GetCount(); i+=2)
1350  {
1351  wxArrayString regMnemonics;
1352  wxArrayString regValues;
1353  wxString RegisterMnemonicString;
1354  wxString RegisterValueString;
1355 
1356  // filter register values
1357  RegisterValueString =lines.Item(i+1);
1358 
1359  wxStringTokenizer RegisterValueStringTokenizer((RegisterValueString), wxT(" "), wxTOKEN_STRTOK);
1360  while ( RegisterValueStringTokenizer.HasMoreTokens() )
1361  {
1362  wxString RegisterValueStringToken = RegisterValueStringTokenizer.GetNextToken();
1363  // add register value to array
1364  regValues.Add(RegisterValueStringToken);
1365  }
1366  // register mnemonics on even (and zero) lines
1367  RegisterMnemonicString =lines.Item(i);
1368 
1369  wxStringTokenizer RegisterMnemonicStringTokenizer((RegisterMnemonicString), wxT(" "), wxTOKEN_STRTOK);
1370  while ( RegisterMnemonicStringTokenizer.HasMoreTokens() )
1371  {
1372  wxString RegisterMnemonicStringToken = RegisterMnemonicStringTokenizer.GetNextToken();
1373  // add register mnemonic to arrau
1374  regMnemonics.Add(RegisterMnemonicStringToken);
1375  }
1376 
1377  // loop around the values and mnemonics arrays and add them to the dialog boxes
1378  for (unsigned int j = 0; j < regMnemonics.GetCount(); j++)
1379  {
1380  wxString reg = regMnemonics.Item(j);
1381  wxString addr = regValues.Item(j);
1382 
1383  if (!reg.IsEmpty() && !addr.IsEmpty())
1384  dialog->SetRegisterValue(reg, addr, wxEmptyString);
1385  }
1386  }
1387  }
1388 };
1389 
1394 {
1396 
1397  public:
1398  GdbCmd_Disassembly(DebuggerDriver* driver, bool MixedMode, wxString hexAddrStr)
1399  : DebuggerCmd(driver)
1400  , m_mixedMode(MixedMode)
1401  {
1402  m_Cmd << _T("disassemble");
1403  if(m_mixedMode)
1404  //gdb's ordering of instructions with /m can be pretty confusing...
1405  //with /m, sometimes, some instructions are missing ( for gdb 7.1/7.2 x86
1406  //on output from tdm gxx 4.4.1) from returned responses.
1407  m_Cmd << _T(" /m");
1408 
1409  if(hexAddrStr.IsEmpty())
1410  //****NOTE: If this branch is taken, disassembly may not reflect the program's
1411  //actual current location. Other areas of code will change the current (stack) frame
1412  //which results in $pc reflecting the eip(x86-based) of that frame. After changing to
1413  //a non-top frame, a request (gdb 7.2 x86) to print either '$pc' or '$eip' will
1414  //return the same value.
1415  //So, there seems to be no way to obtain the actual current address in this (non-MI)
1416  //interface. Hence, we can't get the correct disassembly (when the $pc does not
1417  //reflect actual current address.) GDB itself does continue to step from the correct address, so
1418  //there may be some other way to obtain it yet to be found.
1419  m_Cmd << _T(" $pc");
1420  else if(wxT("0x") == hexAddrStr.Left(2) || wxT("0X") == hexAddrStr.Left(2))
1421  m_Cmd << wxT(" ") << hexAddrStr;
1422  else
1423  m_Cmd << wxT(" 0x") << hexAddrStr;
1424  }
1425  void ParseOutput(const wxString& output)
1426  {
1427  // output for "disassemble" is a series of:
1428  //
1429  // Dump of assembler code for function main:
1430  // 0x00401390 <main+0>: push ebp
1431  // ...
1432  // End of assembler dump.
1433  //
1434  // OR, output for "disassemble /m" is:
1435  //Dump of assembler code for function main:
1436  //6 {
1437  // 0x00401318 <+0>: push %ebp
1438  // 0x00401319 <+1>: mov %esp,%ebp
1439  // 0x0040131b <+3>: and $0xfffffff0,%esp
1440  // 0x0040131e <+6>: push %ebx
1441  // 0x0040131f <+7>: mov $0x103c,%eax
1442  // 0x00401324 <+12>: call 0x401bac <_alloca>
1443  // 0x00401329 <+17>: call 0x4019a0 <__main>
1444  //
1445  //7 #if 1
1446  //8 char filename[2048], filenameabs[2048] ;
1447  //9 if(argc > 1)
1448  //=> 0x0040132e <+22>: cmpl $0x1,0x8(%ebp)
1449  // 0x00401332 <+26>: jle 0x401351 <main+57>
1450  // ...
1451  // 0x004015aa <+658>: ret
1452  //
1453  //End of assembler dump.
1454  const wxString disasmerror(_T("No function contains specified address."));
1456  wxArrayString lines = GetArrayFromString(output, _T('\n'));
1457  for (unsigned int i = 0; i < lines.GetCount(); ++i)
1458  {
1459  if (lines[i].StartsWith(disasmerror))
1460  {
1461  //So, GDB won't disassemble anywhere there is code????
1462  dialog->AddSourceLine(0, disasmerror);
1463  break ;
1464  }
1465  else if (reDisassembly.Matches(lines[i]))
1466  {
1467  uint64_t addr = cbDebuggerStringToAddress(reDisassembly.GetMatch(lines[i], 1));
1468  dialog->AddAssemblerLine(addr, reDisassembly.GetMatch(lines[i], 2));
1469  }
1470  else if (m_mixedMode && reDisassemblySource.Matches(lines[i]))
1471  {
1472  long int lineno;
1473  reDisassemblySource.GetMatch(lines[i], 1).ToLong(&lineno, 10);
1474  dialog->AddSourceLine(lineno, reDisassemblySource.GetMatch(lines[i], 2));
1475  }
1476  }
1477  dialog->CenterCurrentLine();
1478  }
1479 };
1480 
1485 {
1488 
1491  public:
1492  // only tested on mingw/pc/win env
1493  GdbCmd_DisassemblyInit(DebuggerDriver* driver, wxString disassemblyFlavor = wxEmptyString,
1494  wxString hexAddrStr = wxT(""))
1495  : DebuggerCmd(driver),
1496  m_disassemblyFlavor(disassemblyFlavor),
1497  m_hexAddrStr(hexAddrStr)
1498  {
1499  m_Cmd << _T("if 1\n") ;
1500  if(m_hexAddrStr.empty())
1501  {
1502  const Cursor &cursor = driver->GetCursor() ;
1503  if(cursor.address.empty())
1504  m_Cmd << _T("disassemble $pc,$pc+50\n") ;
1505  else
1506  {
1507  m_Cmd << _T("disassemble ") << cursor.address << _T("\n") ;
1508  }
1509  }
1510  else
1511  m_Cmd << _T("disassemble ") << m_hexAddrStr << _T("\n") ;
1512 
1513  m_Cmd << _T("info frame\n") << _T("end");
1514  };
1515 
1516  void ParseOutput(const wxString& p_output)
1517  {
1519 
1520  wxString frame_output, reg_output ;
1521  size_t apos ;
1522  apos = p_output.find(_T("Stack level ")); //looking for 'info frame' output
1523  if(apos == wxString::npos)
1524  {
1525  m_pDriver->Log(_T("Failure finding \"Stack level \""));
1526  apos = p_output.length();
1527  }
1528  reg_output = p_output.substr(0,apos);
1529  frame_output = p_output.substr(apos, p_output.length()-apos);
1530  wxString &output = frame_output ;
1531  if(reDisassemblyCurPC.Matches(reg_output))
1532  {
1533  if(m_hexAddrStr.empty())
1534  {
1535  m_hexAddrStr = reDisassemblyCurPC.GetMatch(reg_output,1);
1536  }
1537  }
1538  else
1539  {
1540  m_pDriver->Log(_T("Failure matching reg_output"));
1541  }
1542  //process 'info frame'
1543  const wxArrayString &lines = GetArrayFromString(output, _T('\n'));
1544  if (lines.Count() <= 2)
1545  return;
1546  size_t firstLine = 0;
1547  for (; firstLine < lines.Count() && !reDisassemblyInit.Matches(lines[firstLine]); ++firstLine)
1548  ;
1549  if (firstLine + 1 < lines.Count())
1550  {
1551  bool sameSymbol = false;
1552  if (reDisassemblyInitSymbol.Matches(lines[firstLine]))
1553  {
1554  const wxString &symbol = reDisassemblyInitSymbol.GetMatch(lines[firstLine], 1)
1555  + reDisassemblyInitSymbol.GetMatch(lines[firstLine], 2);
1556  sameSymbol = (LastSymbol == symbol);
1557 
1558  if (!sameSymbol)
1559  LastSymbol = symbol;
1560  }
1561 
1562  cbStackFrame sf;
1563  const wxString &addr = reDisassemblyInit.GetMatch(output, 1);
1564  if (addr == LastAddr && sameSymbol)
1565  return;
1566  LastAddr = addr;
1568  if (reDisassemblyInitFunc.Matches(output))
1569  sf.SetSymbol(reDisassemblyInitFunc.GetMatch(output, 2));
1570 
1571  sf.MakeValid(true);
1572  dialog->Clear(sf);
1573  if(!m_hexAddrStr.empty())
1574  {
1575  dialog->SetActiveAddress(cbDebuggerStringToAddress(m_hexAddrStr));
1576  Cursor acursor = m_pDriver->GetCursor();
1577  acursor.address = m_hexAddrStr;
1578  m_pDriver->SetCursor(acursor);
1579  }
1580  bool mixedmode = Manager::Get()->GetDebuggerManager()->IsDisassemblyMixedMode();
1581  m_pDriver->QueueCommand(new GdbCmd_Disassembly(m_pDriver, mixedmode, m_hexAddrStr)); //chain call
1582  }
1583  }
1584 
1585  static void Clear()
1586  {
1587  LastAddr.Clear();
1588  LastSymbol.Clear();
1589  }
1590 };
1591 // static
1594 
1599 {
1600  public:
1603  : DebuggerCmd(driver)
1604  {
1606  const wxString &address = CleanStringValue(dialog->GetBaseAddress());
1607  m_Cmd.Printf(_T("x/%dxb %s"), dialog->GetBytes(), address.c_str());
1608  }
1609  void ParseOutput(const wxString& output)
1610  {
1611  // output is a series of:
1612  //
1613  // 0x22ffc0: 0xf0 0xff 0x22 0x00 0x4f 0x6d 0x81 0x7c
1614  // or
1615  // 0x85267a0 <RS485TxTask::taskProc()::rcptBuf>: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
1616 
1618 
1619  dialog->Begin();
1620  dialog->Clear();
1621 
1622  wxArrayString lines = GetArrayFromString(output, _T('\n'));
1623  wxString addr, memory;
1624  for (unsigned int i = 0; i < lines.GetCount(); ++i)
1625  {
1626  if (reExamineMemoryLine.Matches(lines[i]))
1627  {
1628  addr = reExamineMemoryLine.GetMatch(lines[i], 1);
1629  memory = reExamineMemoryLine.GetMatch(lines[i], 2);
1630  }
1631  else
1632  {
1633  if (lines[i].First(_T(':')) == -1)
1634  {
1635  dialog->AddError(lines[i]);
1636  continue;
1637  }
1638  addr = lines[i].BeforeFirst(_T(':'));
1639  memory = lines[i].AfterFirst(_T(':'));
1640  }
1641 
1642  size_t pos = memory.find(_T('x'));
1643  while (pos != wxString::npos)
1644  {
1645  wxString hexbyte;
1646  hexbyte << memory[pos + 1];
1647  hexbyte << memory[pos + 2];
1648  dialog->AddHexByte(addr, hexbyte);
1649  pos = memory.find(_T('x'), pos + 1); // skip current 'x'
1650  }
1651  }
1652  dialog->End();
1653  }
1654 };
1655 
1657 {
1658  public:
1660  : DebuggerCmd(driver)
1661  {
1662  m_Cmd << _T("set remotebaud ") << baud;
1663  driver->Log(_("Setting serial connection speed to ") + baud);
1664  }
1665  void ParseOutput(cb_unused const wxString& output)
1666  {
1667  }
1668 };
1669 
1671 {
1672  public:
1674  : DebuggerCmd(driver)
1675  {
1676  const wxString targetRemote = rd->extendedRemote ? _T("target extended-remote ") : _T("target remote ");
1677  switch (rd->connType)
1678  {
1679  case RemoteDebugging::TCP:
1680  {
1681  if (!rd->ip.IsEmpty() && !rd->ipPort.IsEmpty())
1682  m_Cmd << targetRemote << _T("tcp:") << rd->ip << _T(":") << rd->ipPort;
1683  }
1684  break;
1685 
1686  case RemoteDebugging::UDP:
1687  {
1688  if (!rd->ip.IsEmpty() && !rd->ipPort.IsEmpty())
1689  m_Cmd << targetRemote << _T("udp:") << rd->ip << _T(":") << rd->ipPort;
1690  }
1691  break;
1692 
1694  {
1695  if (!rd->serialPort.IsEmpty())
1696  m_Cmd << targetRemote << rd->serialPort;
1697  }
1698  break;
1699 
1700  default:
1701  break;
1702  }
1703 
1705  if (!m_Cmd.IsEmpty())
1706  driver->Log(_("Connecting to remote target"));
1707  else
1708  m_pDriver->Log(_("Invalid settings for remote debugging!"));
1709  }
1710  void ParseOutput(const wxString& output)
1711  {
1712  // This command will either output an error or a breakpoint address info
1713  // Connection errors are of the form:
1714  //
1715  // tcp:10.10.1.205:2345: No route to host.
1716  // (remote system can't be contacted on the IP level)
1717  //
1718  // tcp:10.10.1.205:2345: Connection refused.
1719  // (no gdb proxy/server running on the specified remote system ip/port)
1720  //
1721  // tcp:1111:222: Invalid argument.
1722  //
1723  // sdsdsds: unknown host
1724  // tcp:sdsdsds:ddd: No such file or directory.
1725  //
1726  // Malformed response to offset query, *
1727  // Ignoring packet error, continuing...
1728  // (serial line errors)
1729  //
1730  // Now, we could use a regex to filter these but this might be overkill
1731  // since the above errors are the only (?) ones we could get.
1732  // So for now we 'll just check them verbatim...
1733 
1734  wxString errMsg;
1735 
1736  if (output.Contains(_T("No route to host")))
1737  errMsg << _("Can't connect to the remote system.\nVerify your connection settings and that\nthe remote system is reachable/powered-on.");
1738  else if (output.Contains(_T("Connection refused")))
1739  errMsg << _("Connection refused by the remote system.\nVerify your connection settings and that\nthe GDB server/proxy is running on the remote system.");
1740  else if (output.Contains(_T("Malformed response")) ||
1741  output.Contains(_T("packet error")))
1742  {
1743  errMsg << _("Connection can't be established.\nVerify your connection settings and that\nthe GDB server/proxy is running on the remote system.");
1744  }
1745  else if (output.Contains(_T("Invalid argument")))
1746  errMsg << _("Invalid argument.\nVerify your connection settings (probably some typo).");
1747  else if (output.Contains(_T("unknown host")))
1748  errMsg << _("Unknown host.\nVerify your connection settings (probably some typo).");
1749 
1750  if (!errMsg.IsEmpty())
1751  {
1752  m_pDriver->Log(_("Failed"));
1753 
1754  // tell the user
1755  errMsg << _("\nThe exact error message was:\n\n");
1756  errMsg << output;
1757  InfoWindow::Display(_("Error"), errMsg, 10000, 1000); // show for 10 seconds with 1 second delay
1758  return;
1759  }
1760 
1761  m_pDriver->Log(_("Connected"));
1762  }
1763 };
1764 
1766 {
1767 
1768  public:
1770  : DebuggerContinueBaseCmd(driver)
1771  {
1772  m_Cmd << command;
1773  }
1774  void ParseOutput(const wxString& output)
1775  {
1777  if (!manager->UpdateDisassembly())
1778  return;
1779  wxString disasm_flavour = static_cast<GDB_driver*>(m_pDriver)->AsmFlavour() ;
1780  cbDisassemblyDlg *dialog = manager->GetDisassemblyDialog();
1781  m_pDriver->Log(output);
1782 
1783  wxString addrstr;
1784 
1785  if(reStepI.Matches(output)) //applies to reStepI and reNextI seem to be same
1786  addrstr = reStepI.GetMatch(output, 6);
1787  else if(reStepI2.Matches(output))
1788  addrstr = reStepI2.GetMatch(output, 1);
1789  else if(reStepI3.Matches(output))
1790  addrstr = reStepI3.GetMatch(output, 1);
1791  else if(reStepI4.Matches(output))
1792  addrstr = reStepI4.GetMatch(output, 1);
1793  else
1794  {
1795  // There is an error parsing the output, so clear file/line location info
1796  cbStackFrame sf;
1797  dialog->Clear(sf);
1798  //Since we don't recognize/anticipate that output, and thus
1799  //can't get an address, request a complete re-disassembly.
1801  return;
1802  }
1803 
1804  if (addrstr.empty())
1805  return;
1806 
1807  if (!dialog->SetActiveAddress(cbDebuggerStringToAddress(addrstr)))
1808  m_pDriver->QueueCommand(new GdbCmd_DisassemblyInit(m_pDriver,disasm_flavour ,addrstr));
1809  }
1810 };
1812 {
1813  public:
1815  : GdbCmd_StepOrNextInstruction(driver, _T("nexti"))
1816  {
1817  }
1818 };
1820 {
1821  public:
1823  : GdbCmd_StepOrNextInstruction(driver, _T("stepi"))
1824  {
1825  }
1826 };
1827 
1832 {
1833  public:
1835  DebuggerCmd(driver, wxT("info frame"))
1836  {
1837  }
1838 
1839  void ParseOutput(const wxString& output)
1840  {
1841  const wxArrayString &lines = GetArrayFromString(output, _T('\n'));
1842  if (lines.Count() <= 2)
1843  return;
1844  size_t firstLine = 0;
1845  for (; firstLine < lines.Count() && !reDisassemblyInit.Matches(lines[firstLine]); ++firstLine)
1846  ;
1847  firstLine++;
1848  if (firstLine < lines.Count())
1849  {
1850  wxString symbol, file, line;
1851  if (reDisassemblyInitSymbol.Matches(lines[firstLine]))
1852  {
1853  symbol = reDisassemblyInitSymbol.GetMatch(lines[firstLine], 1);
1854  file = reDisassemblyInitSymbol.GetMatch(lines[firstLine], 2);
1855  line = reDisassemblyInitSymbol.GetMatch(lines[firstLine], 3);
1856  }
1857 
1858  const wxString &addr = reDisassemblyInit.GetMatch(output, 1);
1859  long longAddress;
1860  addr.ToULong((unsigned long int*)&longAddress, 16);
1861 
1862  Cursor cursor = m_pDriver->GetCursor();
1863  cursor.address = addr;
1864  cursor.changed = true;
1865  cursor.file = file;
1866  cursor.function = symbol;
1867  if (!line.ToLong(&cursor.line))
1868  cursor.line = -1;
1869  m_pDriver->SetCursor(cursor);
1871  }
1872  }
1873 };
1874 
1879 {
1880  public:
1882  : DebuggerCmd(driver)
1883  {
1884  m_Cmd << _T("show language");
1885  }
1886 
1887  void ParseOutput(const wxString& output)
1888  {
1889  if (output.Lower().Find(wxT("fortran")) != wxNOT_FOUND)
1891  else
1893  }
1894 };
1895 
1896 #endif // DEBUGGER_COMMANDS_H
Command to get a watched variable&#39;s type.
Definition: gdb_commands.h:854
DLLIMPORT wxArrayString GetArrayFromString(const wxString &text, const wxString &separator=DEFAULT_ARRAY_SEP, bool trimSpaces=true)
Definition: globals.cpp:134
virtual int GetBytes()=0
C++ or C language.
Command that notifies the debugger plugin that the debuggee has been continued.
Definition: gdb_commands.h:661
Command to add a data breakpoint.
Definition: gdb_commands.h:555
GdbCmd_StepInstruction(GDB_driver *driver)
static void Display(const wxString &title, const wxString &message, unsigned int delay=5000, unsigned int hysteresis=1)
Definition: infowindow.cpp:294
GdbCmd_InfoProgram(DebuggerDriver *driver)
Definition: gdb_commands.h:708
int GetNumber() const
virtual void AddHexByte(const wxString &addr, const wxString &hexbyte)=0
virtual void RemoveBreakpoint(cb::shared_ptr< DebuggerBreakpoint > bp)=0
Remove a breakpoint.
void ParseOutput(const wxString &output)
Parses the command&#39;s output.
Variable should be displayed as decimal.
void SetCursor(const Cursor &cursor)
Set debugger&#39;s cursor.
void ParseOutput(const wxString &output)
Parses the command&#39;s output.
Format is undefined (whatever the debugger uses by default).
DebuggerLanguage g_DebugLanguage
void NotifyCursorChanged()
Called by implementations to notify cursor changes.
cbExamineMemoryDlg * GetExamineMemoryDialog()
Returns a pointer to the memory dialog.
const wxString & GetLine() const
virtual void CenterCurrentLine()=0
void ParseOutput(const wxString &output)
Parses the command&#39;s output.
Definition: gdb_commands.h:257
static wxRegEx reBreakpoint(_T("Breakpoint ([0-9]+) at (0x[0-9A-Fa-f]+)"))
static bool GetFlag(Flags flag)
#define wxICON_WARNING
static wxRegEx reExamineMemoryLine(wxT("[ \*(0x[0-9a-f]+)[ <.+>:[ \+(.+)"))
wxString m_disassemblyFlavor
void ShowFile(const wxString &file, int line)
Show a file/line without changing the cursor.
static wxRegEx reDisassemblySource(_T("([0-9]+)[ \(.*)"))
Command to the add symbol files.
Definition: gdb_commands.h:272
static Manager * Get()
Use Manager::Get() to get a pointer to its instance Manager::Get() is guaranteed to never return an i...
Definition: manager.cpp:182
Command to setup an exception breakpoint (for a throw or a catch).
Definition: gdb_commands.h:631
wxString substr(size_t nStart=0, size_t nLen=npos) const
void ParseOutput(const wxString &output)
Parses the command&#39;s output.
Base class for all Continue type of commands.
void ParseOutput(const wxString &output)
Parses the command&#39;s output.
Definition: gdb_commands.h:235
virtual void Continue()=0
cb::shared_ptr< DebuggerBreakpoint > m_BP
Definition: gdb_commands.h:625
GdbCmd_StepIntoInstruction(GDB_driver *driver)
wxString Lower() const
Variable should be displayed as a single character (e.g. &#39;x&#39;).
size_t length() const
Command to remove a breakpoint.
Definition: gdb_commands.h:590
GdbCmd_ExamineMemory(DebuggerDriver *driver)
static wxString LastSymbol
GdbCmd_FindTooltipAddress(DebuggerDriver *driver, const wxString &what, const wxRect &tiprect, const wxString &w_type=wxEmptyString)
Definition: gdb_commands.h:985
cb::shared_ptr< GDBWatch > m_watch
void ParseOutput(const wxString &output)
Parses the command&#39;s output.
virtual void Reload()=0
virtual void AddSourceLine(int lineno, const wxString &line)=0
Command to display a tooltip about a variables value.
Definition: gdb_commands.h:913
void ParseOutput(const wxString &output)
Parses the command&#39;s output.
GdbCmd_ChangeFrame(DebuggerDriver *driver, int frameno, int p_addrchgmode=1)
wxString m_Cmd
the actual command
Definition: debugger_defs.h:77
wxCStrData c_str() const
cbCPURegistersDlg * GetCPURegistersDialog()
Returns a pointer to the CPU registers dialog.
bool Matches(const wxString &text, int flags=0) const
static wxRegEx reBT0(_T("#([0-9]+)[ \+(.+)[ \at[ \(.+):([0-9]+)"))
#define _T(string)
void ParseOutput(const wxString &output)
Parses the command&#39;s output.
Definition: gdb_commands.h:646
virtual void Action()
Executes an action.
Definition: gdb_commands.h:669
Variable should be displayed as floating point number (e.g. 14.35)
wxString BeforeLast(wxUniChar ch, wxString *rest=NULL) const
wxString GetNextToken()
void ParseOutput(const wxString &output)
Parses the command&#39;s output.
Command to get info about running threads.
Definition: gdb_commands.h:733
void TokenizeGDBLocals(std::vector< GDBLocalVariable > &results, wxString const &value)
GdbCmd_Continue(DebuggerDriver *driver)
Definition: gdb_commands.h:664
void ParseOutput(const wxString &output)
Parses the command&#39;s output.
Definition: gdb_commands.h:713
#define wxYES_NO
static wxRegEx reBT4(_T("#([0-9]+)[ \]+(.+)[ \]in[ \](.+)"))
Command to set the arguments to the debuggee.
Definition: gdb_commands.h:300
cb::shared_ptr< DebuggerBreakpoint > m_BP
Definition: gdb_commands.h:389
GdbCmd_StepOrNextInstruction(GDB_driver *driver, const wxChar *command)
void ParseOutput(const wxString &output)
Parses the command&#39;s output.
void ParseOutputFromOR32gdbPort(const wxString &output)
Command to get a symbol&#39;s type and use it for tooltip evaluation.
void ParseOutput(const wxString &output)
Parses the command&#39;s output.
Definition: gdb_commands.h:608
void ParseOutput(const wxString &output)
Parses the command&#39;s output.
cb::shared_ptr< GDBWatch > m_watch
Definition: gdb_commands.h:856
const ThreadsContainer & GetThreads() const
returns the thread container with the current list of threads
bool ToULong(unsigned long *val, int base=10) const
GdbCmd_Backtrace(DebuggerDriver *driver)
long int line
If -1, no line info.
Definition: debugger_defs.h:32
void ParseOutput(const wxString &output)
Parses the command&#39;s output.
Definition: gdb_commands.h:834
void Log(const wxString &msg)
static wxRegEx reDisassemblyInit(_T("^[ \*Stack level [0-9]+, frame at (0x[A-Fa-f0-9]+):"))
wxString AfterFirst(wxUniChar ch) const
#define wxT(string)
void ParseOutput(const wxString &p_output)
Parses the command&#39;s output.
std::vector< cb::shared_ptr< cbStackFrame > > StackFrameContainer
#define wxNOT_FOUND
bool IsPointerType(wxString type)
DebuggerGDB * GetDebugger()
bool empty() const
size_t find(const wxString &str, size_t nStart=0) const
virtual void Reload()=0
const StackFrameContainer & GetStackFrames() const
returns the container with the current backtrace
Command which tries to find the current cursor position.
void ParseOutput(const wxString &output)
Parses the command&#39;s output.
Definition: gdb_commands.h:945
Command to initialize a disassembly.
static wxRegEx reTemporaryBreakpoint(wxT("^[Tt]emporary[ \breakpoint[ \([0-9]+)[ \at.*"))
EditorManager * GetEditorManager() const
Definition: manager.cpp:434
void SetAddress(uint64_t address)
Command to get info about current program and state.
Definition: gdb_commands.h:705
void LogError(const wxString &msg, int i=app_log)
Definition: logmanager.h:142
cb::shared_ptr< GDBWatch > m_watch
Definition: gdb_commands.h:779
Command to get a symbol&#39;s type and use it for tooltip evaluation.
Definition: gdb_commands.h:978
void ParseOutput(cb_unused const wxString &output)
Definition: gdb_commands.h:309
Command to get info about a watched variable.
Definition: gdb_commands.h:777
wxUSE_UNICODE_dependent wxChar
static wxRegEx reHWBreakpoint(_T("Hardware assisted breakpoint ([0-9]+) at (0x[0-9A-Fa-f]+)"))
wxString BeforeFirst(wxUniChar ch, wxString *rest=NULL) const
bool changed
Definition: debugger_defs.h:33
bool Contains(const wxString &str) const
DebuggerManager * GetDebuggerManager() const
Definition: manager.cpp:484
GdbCmd_Watch(DebuggerDriver *driver, cb::shared_ptr< GDBWatch > watch)
Definition: gdb_commands.h:781
GdbCmd_SetDebuggee(DebuggerDriver *driver, const wxString &file)
Definition: gdb_commands.h:252
Command to determine the debugging (working) language.
static wxRegEx reBT2(_T("\[ \+[atfrom]+[ \+(.*):([0-9]+)"))
static wxRegEx reDisassemblyInitFunc(_T("eip = (0x[A-Fa-f0-9]+) in ([^;]*)"))
GdbCmd_FindWatchType(DebuggerDriver *driver, cb::shared_ptr< GDBWatch > watch, bool firstTry=true)
Definition: gdb_commands.h:859
GdbCmd_Disassembly(DebuggerDriver *driver, bool MixedMode, wxString hexAddrStr)
Command to add a search directory for source files in debugger&#39;s paths.
Definition: gdb_commands.h:226
bool extendedRemote
connect with extended remote or not
static wxRegEx reStepI4(_T("^(0x[A-Fa-f0-9]+) in (.*)? at (.*)"))
EditorBase * GetActiveEditor()
bool ParseGDBWatchValue(cb::shared_ptr< GDBWatch > watch, wxString const &value, int &start, int length)
cbDisassemblyDlg * GetDisassemblyDialog()
Returns a pointer to the disassembly dialog.
GdbCmd_TooltipEvaluation(DebuggerDriver *driver, const wxString &what, const wxRect &tiprect, const wxString &w_type=wxEmptyString, const wxString &address=wxEmptyString)
Definition: gdb_commands.h:925
GdbCmd_FindTooltipType(DebuggerDriver *driver, const wxString &what, const wxRect &tiprect)
Command to change the current frame.
wxString Left(size_t count) const
DebuggerCmd(DebuggerDriver *driver, const wxString &cmd=_T(""), bool logToNormalLog=false)
Variable should be displayed as hexadecimal (e.g. 0xFFFFFFFF).
const wxString & GetFilename() const
static wxRegEx reStepI(wxT("(((.*)[a-zA-Z]:)?.*)?:(\+):(middle|beg):(.*)"), wxRE_ADVANCED)
GdbCmd_Threads(DebuggerDriver *driver)
Definition: gdb_commands.h:737
cbThreadsDlg * GetThreadsDialog()
Returns a pointer to the threads dialog.
virtual bool SetActiveAddress(uint64_t addr)=0
static wxRegEx reBT3(_T("\[ \+[atfrom]+[ \+(.*)"))
void NotifyDebuggeeContinued()
void SetChildPID(long pid)
Set child PID (debuggee&#39;s).
bool GetMatch(size_t *start, size_t *len, size_t index=0) const
Variable should be displayed as unsigned.
Command to the set the file to be debugged.
Definition: gdb_commands.h:248
static wxRegEx reInfoProgramThread(_T("\LWP[ \([0-9]+)\"))
LogManager * GetLogManager() const
Definition: manager.cpp:439
wxString & Item(size_t nIndex)
virtual void ParseOutput(const wxString &output)
Parses the command&#39;s output.
Definition: gdb_commands.h:683
Command to run a backtrace.
Utility command to set a breakpoint condition.
Definition: gdb_commands.h:387
Fortran language.
virtual void SetRegisterValue(const wxString &reg_name, const wxString &hexValue, const wxString &interpreted)=0
Command to add a breakpoint.
Definition: gdb_commands.h:432
static wxRegEx reBTX(_T("#([0-9]+)[ \+0x([A-Fa-f0-9]+)[ \+in[ \+([^(]+)[ \*(\[^)]*\[ \*\[^)]*\)"))
void QueueCommand(DebuggerCmd *dcmd, QueuePriority prio=Low)
add a command in the queue. The DebuggerCmd will be deleted automatically when finished.
virtual wxString GetBaseAddress()=0
static wxRegEx reDisassemblyCurPC(_T("=>[ \+(0x[A-Fa-f0-9]+)"))
static wxRegEx reStepI2(_T("\(0x[A-Fa-f0-9]+)\+(\+)\+in (.*)"), wxRE_ADVANCED)
GdbCmd_SetCatch(DebuggerDriver *driver, const wxString &type, int *resultIndex)
Definition: gdb_commands.h:637
std::vector< cb::shared_ptr< cbThread > > ThreadsContainer
void SetNumber(int number)
wxString wxEmptyString
GdbCmd_Start(DebuggerDriver *driver, const wxString &cmd)
Definition: gdb_commands.h:678
virtual void Clear(const cbStackFrame &frame)=0
GdbCmd_AttachToProcess(DebuggerDriver *driver, int pid)
Definition: gdb_commands.h:322
DLLIMPORT uint64_t cbDebuggerStringToAddress(const wxString &address)
Convert a string in hex form to a uint64_t number.
void ParseOutput(const wxString &output)
Parses the command&#39;s output.
GdbCmd_DisassemblyInit(DebuggerDriver *driver, wxString disassemblyFlavor=wxEmptyString, wxString hexAddrStr=wxT(""))
void AddWatchNoUpdate(const cb::shared_ptr< GDBWatch > &watch)
GdbCmd_Detach(DebuggerDriver *driver)
Definition: gdb_commands.h:362
MacrosManager * GetMacrosManager() const
Definition: manager.cpp:454
const wxString & _(const wxString &string)
wxString & Trim(bool fromRight=true)
GdbCmd_DebugLanguage(DebuggerDriver *driver)
Normal file/line breakpoint.
cb::shared_ptr< GDBWatch > AddChild(cb::shared_ptr< GDBWatch > parent, wxString const &full_value, Token &name)
GdbCmd_RemoveBreakpoint(DebuggerDriver *driver, cb::shared_ptr< DebuggerBreakpoint > bp)
Definition: gdb_commands.h:594
static wxRegEx reGenericHexAddress(_T("(0x[A-Fa-f0-9]+)"))
virtual void Reload()=0
static wxRegEx reRegisters(_T("([A-z0-9]+)[ \+(0x[0-9A-Fa-f]+)[ \+(.*)"))
void ParseOutput(const wxString &output)
Parses the command&#39;s output.
Definition: gdb_commands.h:481
bool ToLong(long *val, int base=10) const
bool HasMoreTokens() const
void ParseOutput(const wxString &output)
Parses the command&#39;s output.
Definition: gdb_commands.h:367
wxString function
Definition: debugger_defs.h:31
Variable should be displayed as binary (e.g. 00011001).
static wxRegEx reStepI3(_T("^(0x[A-Fa-f0-9]+) in (.*)? from (.*)"))
Command to the attach to a process.
Definition: gdb_commands.h:318
A file editor.
Definition: cbeditor.h:43
void SetCurrentFrame(int number, bool user_selected)
static wxRegEx rePendingBreakpoint(_T("Breakpoint ([0-9]+)[ \\\.+):([0-9]+)(\)\[ \pending\"))
bool IsEmpty() const
bool IsContinueCommand() const override
Tells if the command is a continue type command (continue, step, next and run to cursor commands shou...
Definition: gdb_commands.h:352
used for iterations
void Clear()
Debugger cursor info.
Definition: debugger_defs.h:26
virtual void AddAssemblerLine(uint64_t addr, const wxString &line)=0
static wxRegEx reInfoProgramProcess(_T("child process ([0-9]+)"))
used for watches searches
static wxRegEx reNextI(_T("\a\a(([a-zA-Z]:)?.*?):([0-9]*):([0-9]*):(middle|beg):(.*)"), wxRE_ADVANCED)
static const size_t npos
void ReplaceEnvVars(wxString &buffer)
Definition: macrosmanager.h:32
GdbCmd_AddBreakpointCondition(DebuggerDriver *driver, cb::shared_ptr< DebuggerBreakpoint > bp)
Definition: gdb_commands.h:392
cbBacktraceDlg * GetBacktraceDialog()
void ParseOutput(const wxString &output)
Parses the command&#39;s output.
Definition: gdb_commands.h:328
cbBreakpointsDlg * GetBreakpointDialog()
Returns a pointer to the breakpoints dialog.
wxString CleanStringValue(wxString value)
virtual void Begin()=0
GdbCmd_LocalsFuncArgs(DebuggerDriver *driver, cb::shared_ptr< GDBWatch > watch, bool doLocals)
static wxRegEx reDisassembly(_T("(0x[0-9A-Za-z]+)[ \+<.*>:[ \+(.*)"))
GdbCmd_FindCursor(GDB_driver *driver)
void ParseOutput(const wxString &output)
Parses the command&#39;s output.
Definition: gdb_commands.h:567
bool ToLongLong(wxLongLong_t *val, int base=10) const
GdbCmd_AddSourceDir(DebuggerDriver *driver, const wxString &dir)
If dir is empty, resets all search dirs to $cdir:$cwd, the default.
Definition: gdb_commands.h:230
void ParseOutput(const wxString &output)
Parses the command&#39;s output.
cb::shared_ptr< DebuggerBreakpoint > m_BP
Definition: gdb_commands.h:434
virtual void AddError(const wxString &err)=0
bool EndsWith(const wxString &suffix, wxString *rest=NULL) const
GdbCmd_AddSymbolFile(DebuggerDriver *driver, const wxString &file)
Definition: gdb_commands.h:276
void ParseOutput(const wxString &output)
Parses the command&#39;s output.
void MakeValid(bool flag)
void SetFile(const wxString &filename, const wxString &line)
GdbCmd_RemoteBaud(DebuggerDriver *driver, const wxString &baud)
DebuggerDriver * m_pDriver
the driver
Definition: debugger_defs.h:79
GdbCmd_AddBreakpoint(DebuggerDriver *driver, cb::shared_ptr< DebuggerBreakpoint > bp)
Definition: gdb_commands.h:437
cb::shared_ptr< DebuggerBreakpoint > m_BP
Definition: gdb_commands.h:557
size_t Add(const wxString &str, size_t copies=1)
Command to examine a memory region.
void ParseOutput(const wxString &output)
Parses the command&#39;s output.
Definition: gdb_commands.h:281
static wxRegEx reDataBreakpoint(_T("Hardware watchpoint ([0-9]+):.*"))
bool StartsWith(const wxString &prefix, wxString *rest=NULL) const
const Cursor & GetCursor() const
Get debugger&#39;s cursor.
GdbCmd_SetArguments(DebuggerDriver *driver, const wxString &args)
Definition: gdb_commands.h:304
wxString file
Definition: debugger_defs.h:29
void ParseOutput(const wxString &output)
Parses the command&#39;s output.
Definition: gdb_commands.h:872
size_t GetCount() const
Command to obtain register info.
int Find(wxUniChar ch, bool fromEnd=false) const
GdbCmd_AddDataBreakpoint(DebuggerDriver *driver, cb::shared_ptr< DebuggerBreakpoint > bp)
Definition: gdb_commands.h:560
wxUniChar Last() const
wxString address
Definition: debugger_defs.h:30
static wxRegEx reDisassemblyInitSymbol(_T("[ \*[er]ip[ \+=[ \+0x[0-9a-f]+[ \+in[ \+(.+)\(.+):([0-9]+)\;"))
GdbCmd_InfoRegisters(DebuggerDriver *driver, wxString disassemblyFlavor=wxEmptyString)
static wxString LastAddr
GdbCmd_RemoteTarget(DebuggerDriver *driver, RemoteDebugging *rd)
Command to the detach from the process.
Definition: gdb_commands.h:358
static wxRegEx reDisassemblyInitFuncOR32(_T("PC = (0x[A-Fa-f0-9]+) in ([^;]*)"))
int Printf(const wxString &pszFormat,...)
void ParseOutput(cb_unused const wxString &output)
void SetSymbol(const wxString &symbol)
void ParseOutput(const wxString &output)
Parses the command&#39;s output.
Basic interface for debugger commands.
Definition: debugger_defs.h:49
static wxRegEx reInfoThreads(_T("(\*)[ \*([0-9]+)[ \(.*)"))
int GetUserSelectedFrame() const
static wxRegEx reBT1(_T("#([0-9]+)[ \+0x([A-Fa-f0-9]+)[ \+in[ \+(.+)[ \+(\[^)]*\)[ \"))
void ParseOutput(const wxString &output)
Parses the command&#39;s output.
Definition: gdb_commands.h:742
Command to run a disassembly.
static wxString Format(const wxString &format,...)
ConnectionType connType
void MarkProgramStopped(bool stopped)
static bool MatchLine(cbStackFrame &sf, bool &hasLineInfo, const wxString &line)
DLLIMPORT int cbMessageBox(const wxString &message, const wxString &caption=wxEmptyString, int style=wxOK, wxWindow *parent=NULL, int x=-1, int y=-1)
wxMessageBox wrapper.
Definition: globals.cpp:1395
void ParseOutput(const wxString &output)
Parses the command&#39;s output.
Definition: gdb_commands.h:400
virtual void Clear()=0
virtual void End()=0