Code::Blocks  SVN r11506
gdb_driver.cpp
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  * $Revision: 11490 $
6  * $Id: gdb_driver.cpp 11490 2018-10-03 14:27:48Z mortenmacfly $
7  * $HeadURL: https://svn.code.sf.net/p/codeblocks/code/trunk/src/plugins/debuggergdb/gdb_driver.cpp $
8  */
9 
10 #include <sdk.h>
11 #include "gdb_driver.h"
12 #include "gdb_commands.h"
13 #include "debuggeroptionsdlg.h"
14 #include "debuggerstate.h"
15 #include <cbdebugger_interfaces.h>
16 #include <manager.h>
17 #include <macrosmanager.h>
18 #include <configmanager.h>
19 #include <globals.h>
20 #include <infowindow.h>
21 
22 #ifdef __WXMSW__
23 // for Registry detection of Cygwin
24 #include "wx/msw/wrapwin.h" // Wraps windows.h
25 #endif
26 
27 // the ">>>>>>" is a hack: sometimes, especially when watching uninitialized char*
28 // some random control codes in the stream (like 'delete') will mess-up our prompt and the debugger
29 // will seem like frozen (only "stop" button available). Using this dummy prefix,
30 // we allow for a few characters to be "eaten" this way and still get our
31 // expected prompt back.
32 #define GDB_PROMPT _T("cb_gdb:")
33 #define FULL_GDB_PROMPT _T(">>>>>>") GDB_PROMPT
34 
35 //[Switching to thread 2 (Thread 1082132832 (LWP 12298))]#0 0x00002aaaac5a2aca in pthread_cond_wait@@GLIBC_2.3.2 () from /lib/libpthread.so.0
36 static wxRegEx reThreadSwitch(_T("^\\[Switching to thread .*\\]#0[ \t]+(0x[A-Fa-f0-9]+) in (.*) from (.*)"));
37 static wxRegEx reThreadSwitch2(_T("^\\[Switching to thread .*\\]#0[ \t]+(0x[A-Fa-f0-9]+) in (.*) from (.*):([0-9]+)"));
38 
39 // Regular expresion for breakpoint. wxRegEx don't want to recognize '?' command, so a bit more general rule is used
40 // here.
41 // ([A-Za-z]*[:]*) corresponds to windows disk name. Under linux it can be none empty in crosscompiling sessions;
42 // ([^:]+) corresponds to the path in linux or to the path within windows disk in windows to current file;
43 // ([0-9]+) corresponds to line number in current file;
44 // (0x[0-9A-Fa-f]+) correponds to current memory address.
45 static wxRegEx reBreak(_T("\032*([A-Za-z]*[:]*)([^:]+):([0-9]+):[0-9]+:[begmidl]+:(0x[0-9A-Fa-f]+)"));
46 
47 static wxRegEx reBreak2(_T("^(0x[A-Fa-f0-9]+) in (.*) from (.*)"));
48 static wxRegEx reBreak3(_T("^(0x[A-Fa-f0-9]+) in (.*)"));
49 // Catchpoint 1 (exception thrown), 0x00007ffff7b982b0 in __cxa_throw () from /usr/lib/gcc/x86_64-pc-linux-gnu/4.4.4/libstdc++.so.6
50 static wxRegEx reCatchThrow(_T("^Catchpoint ([0-9]+) \\(exception thrown\\), (0x[0-9a-f]+) in (.+) from (.+)$"));
51 // Catchpoint 1 (exception thrown), 0x00401610 in __cxa_throw ()
52 static wxRegEx reCatchThrowNoFile(_T("^Catchpoint ([0-9]+) \\(exception thrown\\), (0x[0-9a-f]+) in (.+)$"));
53 
54 // easily match cygwin paths
55 //static wxRegEx reCygwin(_T("/cygdrive/([A-Za-z])/"));
56 
57 // Pending breakpoint "C:/Devel/libs/irr_svn/source/Irrlicht/CSceneManager.cpp:1077" resolved
58 #ifdef __WXMSW__
59 static wxRegEx rePendingFound(_T("^Pending[ \t]+breakpoint[ \t]+[\"]+([A-Za-z]:)([^:]+):([0-9]+)\".*"));
60 #else
61 static wxRegEx rePendingFound(_T("^Pending[ \t]+breakpoint[ \t]+[\"]+([^:]+):([0-9]+)\".*"));
62 #endif
63 // Breakpoint 2, irr::scene::CSceneManager::getSceneNodeFromName (this=0x3fa878, name=0x3fbed8 "MainLevel", start=0x3fa87c) at CSceneManager.cpp:1077
64 static wxRegEx rePendingFound1(_T("^Breakpoint[ \t]+([0-9]+),.*"));
65 
66 // Temporary breakpoint 2, main () at /path/projects/tests/main.cpp:136
67 static wxRegEx reTempBreakFound(wxT("^[Tt]emporary[ \t]breakpoint[ \t]([0-9]+),.*"));
68 
69 
70 // [Switching to Thread -1234655568 (LWP 18590)]
71 // [New Thread -1234655568 (LWP 18590)]
72 static wxRegEx reChildPid1(_T("Thread[ \t]+[xA-Fa-f0-9-]+[ \t]+\\(LWP ([0-9]+)\\)]"));
73 // MinGW GDB 6.8 and later
74 // [New Thread 2684.0xf40] or [New thread 2684.0xf40]
75 static wxRegEx reChildPid2(_T("\\[New [tT]hread[ \t]+[0-9]+\\.[xA-Fa-f0-9-]+\\]"));
76 
77 static wxRegEx reInferiorExited(wxT("^\\[Inferior[ \\t].+[ \\t]exited normally\\]$"), wxRE_EXTENDED);
78 static wxRegEx reInferiorExitedWithCode(wxT("^\\[[Ii]nferior[ \\t].+[ \\t]exited[ \\t]with[ \\t]code[ \\t]([0-9]+)\\]$"), wxRE_EXTENDED);
79 
81  DebuggerDriver(plugin),
82  m_CygwinPresent(false),
83  m_BreakOnEntry(false),
84  m_ManualBreakOnEntry(false),
85  m_IsStarted(false),
86  m_GDBVersionMajor(0),
87  m_GDBVersionMinor(0),
88  m_attachedToProcess(false),
89  m_catchThrowIndex(-1)
90 {
91  //ctor
92  m_needsUpdate = false;
93  m_forceUpdate = false;
94 }
95 
97 {
98  //dtor
99 }
100 
101 wxString GDB_driver::GetCommandLine(const wxString& debugger, const wxString& debuggee, const wxString &userArguments)
102 {
103  wxString cmd;
104  cmd << debugger;
106  cmd << _T(" -nx"); // don't run .gdbinit
107  cmd << _T(" -fullname"); // report full-path filenames when breaking
108  cmd << _T(" -quiet"); // don't display version on startup
109  cmd << wxT(" ") << userArguments;
110  cmd << _T(" -args ") << debuggee;
111  return cmd;
112 }
113 
114 wxString GDB_driver::GetCommandLine(const wxString& debugger, cb_unused int pid, const wxString &userArguments)
115 {
116  wxString cmd;
117  cmd << debugger;
119  cmd << _T(" -nx"); // don't run .gdbinit
120  cmd << _T(" -fullname"); // report full-path filenames when breaking
121  cmd << _T(" -quiet"); // don't display version on startup
122  cmd << wxT(" ") << userArguments;
123  return cmd;
124 }
125 
127 {
128  // init for remote debugging
129  m_pTarget = target;
130 }
131 
132 void GDB_driver::Prepare(bool isConsole, int printElements)
133 {
134  // default initialization
135 
136  // for the possibility that the program to be debugged is compiled under Cygwin
137  if (platform::windows)
139 
140  // make sure we 're using the prompt that we know and trust ;)
141  QueueCommand(new DebuggerCmd(this, wxString(_T("set prompt ")) + FULL_GDB_PROMPT));
142 
143  // debugger version
144  QueueCommand(new DebuggerCmd(this, _T("show version")));
145  // no confirmation
146  QueueCommand(new DebuggerCmd(this, _T("set confirm off")));
147  // no wrapping lines
148  QueueCommand(new DebuggerCmd(this, _T("set width 0")));
149  // no pagination
150  QueueCommand(new DebuggerCmd(this, _T("set height 0")));
151  // allow pending breakpoints
152  QueueCommand(new DebuggerCmd(this, _T("set breakpoint pending on")));
153  // show pretty function names in disassembly
154  QueueCommand(new DebuggerCmd(this, _T("set print asm-demangle on")));
155  // unwind stack on signal
156  QueueCommand(new DebuggerCmd(this, _T("set unwindonsignal on")));
157  // disalbe result string truncations
158  QueueCommand(new DebuggerCmd(this, wxString::Format(wxT("set print elements %d"), printElements)));
159 
160  if (platform::windows && isConsole)
161  QueueCommand(new DebuggerCmd(this, _T("set new-console on")));
162 
164  QueueCommand(new DebuggerCmd(this, flavour));
165 
167  {
168  m_catchThrowIndex = -1;
169  // catch exceptions
170  QueueCommand(new GdbCmd_SetCatch(this, wxT("throw"), &m_catchThrowIndex));
171  }
172 
173  // pass user init-commands
175  MacrosManager *macrosManager = Manager::Get()->GetMacrosManager();
176  macrosManager->ReplaceMacros(init);
177  // commands are passed in one go, in case the user defines functions in there
178  // or else it would lock up...
179  if (!init.empty())
180  QueueCommand(new DebuggerCmd(this, init));
181 
182  // add search dirs
183  for (unsigned int i = 0; i < m_Dirs.GetCount(); ++i)
184  QueueCommand(new GdbCmd_AddSourceDir(this, m_Dirs[i]));
185 
186  // set arguments
187  if (!m_Args.IsEmpty())
188  QueueCommand(new DebuggerCmd(this, _T("set args ") + m_Args));
189 
191 
192  // send additional gdb commands before establishing remote connection
193  if (rd)
194  {
195  if (!rd->additionalCmdsBefore.IsEmpty())
196  {
198  for (unsigned int i = 0; i < initCmds.GetCount(); ++i)
199  {
200  macrosManager->ReplaceMacros(initCmds[i]);
201  QueueCommand(new DebuggerCmd(this, initCmds[i]));
202  }
203  }
205  {
207  for (unsigned int i = 0; i < initCmds.GetCount(); ++i)
208  {
209  macrosManager->ReplaceMacros(initCmds[i]);
210  QueueCommand(new DebuggerCmd(this, _T("shell ") + initCmds[i]));
211  }
212  }
213  }
214 
215  // if performing remote debugging, now is a good time to try and connect to the target :)
216  if (rd && rd->IsOk())
217  {
219  QueueCommand(new GdbCmd_RemoteBaud(this, rd->serialBaud));
220  QueueCommand(new GdbCmd_RemoteTarget(this, rd));
221  }
222 
223  // run per-target additional commands (remote debugging)
224  // moved after connection to remote target (if any)
225  if (rd)
226  {
227  if (!rd->additionalCmds.IsEmpty())
228  {
229  wxArrayString initCmds = GetArrayFromString(rd->additionalCmds, _T('\n'));
230  for (unsigned int i = 0; i < initCmds.GetCount(); ++i)
231  {
232  macrosManager->ReplaceMacros(initCmds[i]);
233  QueueCommand(new DebuggerCmd(this, initCmds[i]));
234  }
235  }
237  {
239  for (unsigned int i = 0; i < initCmds.GetCount(); ++i)
240  {
241  macrosManager->ReplaceMacros(initCmds[i]);
242  QueueCommand(new DebuggerCmd(this, _T("shell ") + initCmds[i]));
243  }
244  }
245  }
246 }
247 
248 // remote debugging
250 {
251 // if (!m_pTarget)
252 // return 0;
253 
254  // first, project-level (straight copy)
256 
257  // then merge with target settings
258  RemoteDebuggingMap::iterator it = m_pDBG->GetRemoteDebuggingMap().find(m_pTarget);
259  if (it != m_pDBG->GetRemoteDebuggingMap().end())
260  {
261  m_MergedRDInfo.MergeWith(it->second);
262  }
263  return &m_MergedRDInfo;
264 }
265 
266 // Cygwin check code
267 #ifdef __WXMSW__
268 
269 enum{ BUFSIZE = 64 };
270 
271 // routines to handle cygwin compiled programs on a Windows compiled C::B IDE
273 {
274  LONG lRegistryAPIresult;
275  HKEY hKey_CU;
276  HKEY hKey_LM;
277  TCHAR szCygwinRoot[BUFSIZE];
278  DWORD dwBufLen=BUFSIZE*sizeof(TCHAR);
279 
280  // checking if cygwin mounts are present under HKCU
281  lRegistryAPIresult = RegOpenKeyEx( HKEY_CURRENT_USER,
282  TEXT("Software\\Cygnus Solutions\\Cygwin\\mounts v2"),
283  0, KEY_QUERY_VALUE, &hKey_CU );
284  if ( lRegistryAPIresult == ERROR_SUCCESS )
285  {
286  // try to readback cygwin root (might not exist!)
287  lRegistryAPIresult = RegQueryValueEx( hKey_CU, TEXT("cygdrive prefix"), NULL, NULL,
288  (LPBYTE) szCygwinRoot, &dwBufLen);
289  }
290 
291  // lRegistryAPIresult can be erroneous for two reasons:
292  // 1.) Cygwin entry is not present (could not be opened) in HKCU
293  // 2.) "cygdrive prefix" is not present (could not be read) in HKCU
294  if ( lRegistryAPIresult != ERROR_SUCCESS )
295  {
296  // Now check if probably present under HKLM
297  lRegistryAPIresult = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
298  TEXT("SOFTWARE\\Cygnus Solutions\\Cygwin\\mounts v2"),
299  0, KEY_QUERY_VALUE, &hKey_LM );
300  if ( lRegistryAPIresult != ERROR_SUCCESS )
301  {
302  // cygwin definitely not installed
303  m_CygwinPresent = false;
304  return;
305  }
306 
307  // try to readback cygwin root (now it really should exist here)
308  lRegistryAPIresult = RegQueryValueEx( hKey_LM, TEXT("cygdrive prefix"), NULL, NULL,
309  (LPBYTE) szCygwinRoot, &dwBufLen);
310  }
311 
312  // handle a possible query error
313  if ( (lRegistryAPIresult != ERROR_SUCCESS) || (dwBufLen > BUFSIZE*sizeof(TCHAR)) )
314  {
315  // bit of an assumption, but we won't be able to find the root without it
316  m_CygwinPresent = false;
317  return;
318  }
319 
320  // close opened keys
321  RegCloseKey( hKey_CU ); // ignore key close errors
322  RegCloseKey( hKey_LM ); // ignore key close errors
323 
324  m_CygwinPresent = true; // if we end up here all was OK
325  m_CygdrivePrefix = (szCygwinRoot); // convert to wxString type for later use
326 }
327 
329 {
330  unsigned int i=0, EscCount=0;
331 
332  // preserve any escape characters at start of path - this is true for
333  // breakpoints - value is 2, but made dynamic for safety as we
334  // are only checking for the CDprefix not any furthur correctness
335  if (path.GetChar(0)==g_EscapeChar)
336  {
337  while ( (i<path.Len()) && (path.GetChar(i)==g_EscapeChar) )
338  {
339  // get character
340  EscCount++;
341  i++;
342  }
343  }
344 
345  // prepare to convert to a valid path if Cygwin is being used
346 
347  // step over the escape characters
348  wxString PathWithoutEsc(path); PathWithoutEsc.Remove(0, EscCount);
349 
350  if (PathWithoutEsc.StartsWith(m_CygdrivePrefix))
351  {
352  // remove cygwin prefix
353  if (m_CygdrivePrefix.EndsWith(_T("/"))) // for the case "/c/path"
354  PathWithoutEsc.Remove(0, m_CygdrivePrefix.Len() );
355  else // for cases e.g. "/cygdrive/c/path"
356  PathWithoutEsc.Remove(0, m_CygdrivePrefix.Len()+1);
357 
358  // insert ':' after drive label by reading and removing drive the label
359  // and adding ':' and the drive label back
360  wxString DriveLetter = PathWithoutEsc.GetChar(0);
361  PathWithoutEsc.Replace(DriveLetter, DriveLetter + _T(":"), false);
362  }
363 
364  // Compile corrected path
365  path = wxEmptyString;
366  for (i=0; i<EscCount; i++)
367  path += g_EscapeChar;
368  path += PathWithoutEsc;
369 }
370 #else
371  void GDB_driver::DetectCygwinMount(void){/* dummy */}
372  void GDB_driver::CorrectCygwinPath(cb_unused wxString& path){/* dummy */}
373 #endif
374 
375 #ifdef __WXMSW__
377 {
379  bool remoteDebugging = rd && rd->IsOk();
380  return !remoteDebugging;
381 }
382 #endif
383 
385 {
386  return flavour;
387 }
388 
389 // Only called from DebuggerGDB::Debug
390 // breakOnEntry was always false. Changed by HC.
391 void GDB_driver::Start(bool breakOnEntry)
392 {
393  m_attachedToProcess = false;
394  ResetCursor();
395 
396  // reset other states
398  if (Manager::Get()->GetDebuggerManager()->UpdateDisassembly())
399  {
401  disassembly_dialog->Clear(cbStackFrame());
402  }
403 
404  // if performing remote debugging, use "continue" command
406  bool remoteDebugging = rd && rd->IsOk();
407 
408  m_BreakOnEntry = breakOnEntry && !remoteDebugging;
409 
411  {
412  m_ManualBreakOnEntry = !remoteDebugging;
413  // start the process
414  if (breakOnEntry)
415  QueueCommand(new GdbCmd_Start(this, remoteDebugging ? _T("continue") : _T("start")));
416  else
417  {
418  // if breakOnEntry is not set, we need to use 'run' to make gdb stop at a breakpoint at first instruction
419  m_ManualBreakOnEntry=false; // must be reset or gdb does not stop at first breakpoint
420  QueueCommand(new GdbCmd_Start(this, remoteDebugging ? _T("continue") : _T("run")));
421  }
422  m_IsStarted = true;
423  }
424 } // Start
425 
427 {
428  ResetCursor();
430  QueueCommand(new DebuggerCmd(this, wxT("kill")));
431  QueueCommand(new DebuggerCmd(this, _T("quit")));
432  m_IsStarted = false;
433  m_attachedToProcess = false;
434 }
435 
437 {
438  ResetCursor();
439  if (m_IsStarted)
440  QueueCommand(new GdbCmd_Continue(this));
441  else
442  {
443  // if performing remote debugging, use "continue" command
445  bool remoteDebugging = rd && rd->IsOk();
446  if (remoteDebugging)
447  QueueCommand(new GdbCmd_Continue(this));
448  else
449  QueueCommand(new GdbCmd_Start(this, m_ManualBreakOnEntry ? wxT("start") : wxT("run")));
450  m_ManualBreakOnEntry = false;
451  m_IsStarted = true;
452  m_attachedToProcess = false;
453  }
454 }
455 
457 {
458  ResetCursor();
459  QueueCommand(new DebuggerContinueBaseCmd(this, _T("next")));
460 }
461 
463 {
464  ResetCursor();
466 }
467 
469 {
470  ResetCursor();
472 }
473 
475 {
476  ResetCursor();
477  QueueCommand(new DebuggerContinueBaseCmd(this, _T("step")));
478 }
479 
481 {
482  ResetCursor();
483  QueueCommand(new DebuggerContinueBaseCmd(this, _T("finish")));
484 }
485 
486 void GDB_driver::SetNextStatement(const wxString& filename, int line)
487 {
488  ResetCursor();
489  QueueCommand(new DebuggerCmd(this, wxString::Format(wxT("tbreak %s:%d"), filename.c_str(), line)));
490  QueueCommand(new DebuggerContinueBaseCmd(this, wxString::Format(wxT("jump %s:%d"), filename.c_str(), line)));
491 }
492 
494 {
495  QueueCommand(new GdbCmd_Backtrace(this));
496 }
497 
499 {
500  if (platform::windows)
502  else
504 }
505 
507 {
508  if (platform::windows)
510  else
512 }
513 
514 void GDB_driver::SwitchToFrame(size_t number)
515 {
516  ResetCursor();
517  QueueCommand(new DebuggerCmd(this, wxString(_T("frame ")) << number));
518 }
519 
520 void GDB_driver::SetVarValue(const wxString& var, const wxString& value)
521 {
522  const wxString &cleanValue=CleanStringValue(value);
523  QueueCommand(new DebuggerCmd(this, wxString::Format(_T("set variable %s=%s"), var.c_str(), cleanValue.c_str())));
524 }
525 
527 {
529 }
530 
532 {
533  if (Manager::Get()->GetDebuggerManager()->UpdateThreads())
534  QueueCommand(new GdbCmd_Threads(this));
535 }
536 
538 {
539  QueueCommand(new DebuggerInfoCmd(this, _T("info frame"), _("Selected frame")));
540 }
541 
543 {
544  if (platform::windows)
545  QueueCommand(new DebuggerInfoCmd(this, _T("info dll"), _("Loaded libraries")));
546  else
547  QueueCommand(new DebuggerInfoCmd(this, _T("info sharedlibrary"), _("Loaded libraries")));
548 }
549 
551 {
552  QueueCommand(new DebuggerInfoCmd(this, _T("info files"), _("Files and targets")));
553 }
554 
556 {
557  QueueCommand(new DebuggerInfoCmd(this, _T("info float"), _("Floating point unit")));
558 }
559 
561 {
562  QueueCommand(new DebuggerInfoCmd(this, _T("info signals"), _("Signals handling")));
563 }
564 
566 {
567  if (enable)
568  QueueCommand(new GdbCmd_SetCatch(this, wxT("throw"), &m_catchThrowIndex));
569  else if (m_catchThrowIndex != -1)
570  {
572  m_catchThrowIndex = -1;
573  }
574 }
575 
576 void GDB_driver::SwitchThread(size_t threadIndex)
577 {
578  ResetCursor();
579  QueueCommand(new DebuggerCmd(this, wxString::Format(_T("thread %lu"), static_cast<unsigned long>(threadIndex))));
580  if (Manager::Get()->GetDebuggerManager()->UpdateBacktrace())
581  QueueCommand(new GdbCmd_Backtrace(this));
582 }
583 
584 void GDB_driver::AddBreakpoint(cb::shared_ptr<DebuggerBreakpoint> bp)
585 {
586  if (bp->type == DebuggerBreakpoint::bptData)
587  QueueCommand(new GdbCmd_AddDataBreakpoint(this, bp));
588  //Workaround for GDB to break on C++ constructor/destructor
589  else
590  {
591  if (bp->func.IsEmpty() && !bp->lineText.IsEmpty())
592  {
593  wxRegEx reCtorDtor(_T("([0-9A-z_]+)::([~]?)([0-9A-z_]+)[ \t\(]*"));
594  if (reCtorDtor.Matches(bp->lineText))
595  {
596  wxString strBase = reCtorDtor.GetMatch(bp->lineText, 1);
597  wxString strDtor = reCtorDtor.GetMatch(bp->lineText, 2);
598  wxString strMethod = reCtorDtor.GetMatch(bp->lineText, 3);
599  if (strBase.IsSameAs(strMethod))
600  {
601  bp->func = strBase;
602  bp->func << _T("::");
603  bp->func << strDtor;
604  bp->func << strMethod;
605  // if (bp->temporary)
606  // bp->temporary = false;
607  NotifyCursorChanged(); // to force breakpoints window update
608  }
609  }
610  }
611  //end GDB workaround
612 
613  QueueCommand(new GdbCmd_AddBreakpoint(this, bp));
614  }
615 }
616 
617 void GDB_driver::RemoveBreakpoint(cb::shared_ptr<DebuggerBreakpoint> bp)
618 {
619  if (bp && bp->index != -1)
620  QueueCommand(new GdbCmd_RemoveBreakpoint(this, bp));
621 }
622 
623 void GDB_driver::EvaluateSymbol(const wxString& symbol, const wxRect& tipRect)
624 {
625  QueueCommand(new GdbCmd_FindTooltipType(this, symbol, tipRect));
626 }
627 
628 void GDB_driver::UpdateWatches(cb::shared_ptr<GDBWatch> localsWatch, cb::shared_ptr<GDBWatch> funcArgsWatch,
629  WatchesContainer &watches)
630 {
632  {
635  }
636 
637  bool updateWatches = false;
638  if (localsWatch && localsWatch->IsAutoUpdateEnabled())
639  {
640  QueueCommand(new GdbCmd_LocalsFuncArgs(this, localsWatch, true));
641  updateWatches = true;
642  }
643  if (funcArgsWatch && funcArgsWatch->IsAutoUpdateEnabled())
644  {
645  QueueCommand(new GdbCmd_LocalsFuncArgs(this, funcArgsWatch, false));
646  updateWatches = true;
647  }
648 
649  for (WatchesContainer::iterator it = watches.begin(); it != watches.end(); ++it)
650  {
651  WatchesContainer::reference watch = *it;
652  if (watch->IsAutoUpdateEnabled())
653  {
654  QueueCommand(new GdbCmd_FindWatchType(this, watch));
655  updateWatches = true;
656  }
657  }
658 
659  if (updateWatches)
660  {
661  // run this action-only command to update the tree
663  }
664 }
665 
666 void GDB_driver::UpdateWatch(const cb::shared_ptr<GDBWatch> &watch)
667 {
668  QueueCommand(new GdbCmd_FindWatchType(this, watch));
670 }
671 
672 void GDB_driver::UpdateWatchLocalsArgs(cb::shared_ptr<GDBWatch> const &watch, bool locals)
673 {
674  QueueCommand(new GdbCmd_LocalsFuncArgs(this, watch, locals));
676 }
677 
678 void GDB_driver::Attach(int pid)
679 {
680  m_IsStarted = true;
681  m_attachedToProcess = true;
682  SetChildPID(pid);
683  QueueCommand(new GdbCmd_AttachToProcess(this, pid));
684 }
685 
687 {
688  QueueCommand(new GdbCmd_Detach(this));
689 }
690 
692 {
693  m_Cursor.changed = false;
694 
695  if (platform::windows && m_ChildPID == 0)
696  {
697  if (reChildPid2.Matches(output)) // [New Thread 2684.0xf40] or [New thread 2684.0xf40]
698  {
699  wxString pidStr = reChildPid2.GetMatch(output, 0);
700  pidStr = pidStr.BeforeFirst(_T('.')); //[New Thread 2684.0xf40] -> [New Thread 2684
701  pidStr = pidStr.AfterFirst(_T('d')); //[New Thread 2684 -> 2684
702  long pid = 0;
703  pidStr.ToLong(&pid);
704  SetChildPID(pid);
705  m_pDBG->Log(wxString::Format(_("Child process PID: %ld"), pid));
706  }
707  }
708  else if (!platform::windows && m_ChildPID == 0)
709  {
710  if (reChildPid1.Matches(output)) // [Switching to Thread -1234655568 (LWP 18590)]
711  {
712  wxString pidStr = reChildPid1.GetMatch(output, 1);
713  long pid = 0;
714  pidStr.ToLong(&pid);
715  SetChildPID(pid);
716  m_pDBG->Log(wxString::Format(_("Child process PID: %ld"), pid));
717  }
718  }
719 
720  if ( output.StartsWith(_T("gdb: "))
721  || output.StartsWith(_T("warning: "))
722  || output.StartsWith(_T("Warning: "))
723  || output.StartsWith(_T("ContinueDebugEvent ")) )
724  {
725  return;
726  }
727 
728  static wxString buffer;
729  buffer << output << _T('\n');
730 
731  m_pDBG->DebugLog(output);
732 
733  int idx = buffer.First(GDB_PROMPT);
734  const bool foundPrompt = (idx != wxNOT_FOUND);
735  if (!foundPrompt)
736  {
737  // don't uncomment the following line
738  // m_ProgramIsStopped is set to false in DebuggerDriver::RunQueue()
739 // m_ProgramIsStopped = false;
740  return; // come back later
741  }
742 
743  m_QueueBusy = false;
744  int changeFrameAddr = 0 ;
745  DebuggerCmd* cmd = CurrentCommand();
746  if (cmd)
747  {
748 // DebugLog(wxString::Format(_T("Command parsing output (cmd: %s): %s"), cmd->m_Cmd.c_str(), buffer.Left(idx).c_str()));
749  RemoveTopCommand(false);
750  buffer.Remove(idx);
751  // remove the '>>>>>>' part of the prompt (or what's left of it)
752  int cnt = 6; // max 6 '>'
753  while (!buffer.empty() && buffer.Last() == _T('>') && cnt--)
754  buffer.RemoveLast();
755  if (!buffer.empty() && buffer.Last() == _T('\n'))
756  buffer.RemoveLast();
757  cmd->ParseOutput(buffer.Left(idx));
758 
759  //We do NOT want default output processing for a changed frame as it can result
760  //in disassembly being done for a non-current location, since some of the frame
761  //response lines are in the pattern of breakpoint output.
762  GdbCmd_ChangeFrame *changeFrameCmd = dynamic_cast<GdbCmd_ChangeFrame*>(cmd);
763  if (changeFrameCmd)
764  changeFrameAddr = changeFrameCmd->AddrChgMode();
765 
766  delete cmd;
767  RunQueue();
768  }
769 
770  m_needsUpdate = false;
771  m_forceUpdate = false;
772 
773  // non-command messages (e.g. breakpoint hits)
774  // break them up in lines
775 
776  wxArrayString lines = GetArrayFromString(buffer, _T('\n'));
777  for (unsigned int i = 0; i < lines.GetCount(); ++i)
778  {
779 // Log(_T("DEBUG: ") + lines[i]); // write it in the full debugger log
780 
781  // Check for possibility of a cygwin compiled program
782  // convert to valid path
783  if (platform::windows && m_CygwinPresent)
784  CorrectCygwinPath(lines.Item(i));
785 
786  // log GDB's version
787  if (lines[i].StartsWith(_T("GNU gdb")))
788  {
789  // it's the gdb banner. Just display the version and "eat" the rest
790  m_pDBG->Log(_("Debugger name and version: ") + lines[i]);
791  // keep major and minor version numbers handy
792  wxRegEx re(_T("([0-9.]+)"));
793  if (!re.Matches(lines[i]))
794  {
795  m_pDBG->Log(_T("Unable to determine the version of gdb"));
796  break;
797  }
798  wxString major = re.GetMatch(lines[i],0);
799  wxString minor = major;
800  major = major.BeforeFirst(_T('.')); // 6.3.2 -> 6
801  minor = minor.AfterFirst(_T('.')); // 6.3.2 -> 3.2
802  minor = minor.BeforeFirst(_T('.')); // 3.2 -> 3
803  major.ToLong(&m_GDBVersionMajor);
804  minor.ToLong(&m_GDBVersionMinor);
805 // wxString log;
806 // log.Printf(_T("Line: %s\nMajor: %s (%d)\nMinor: %s (%d)"),
807 // lines[i].c_str(),
808 // major.c_str(),
809 // m_GDBVersionMajor,
810 // minor.c_str(),
811 // m_GDBVersionMinor);
812 // m_pDBG->Log(log);
813  break;
814  }
815 
816  // Is the program exited?
817  else if ( lines[i].StartsWith(_T("Error creating process"))
818  || lines[i].StartsWith(_T("Program exited"))
819  || lines[i].StartsWith(wxT("Program terminated with signal"))
820  || lines[i].StartsWith(wxT("During startup program exited"))
821  || lines[i].Contains(_T("program is not being run"))
822  || lines[i].Contains(_T("Target detached"))
823  || reInferiorExited.Matches(lines[i])
824  || reInferiorExitedWithCode.Matches(lines[i]) )
825  {
826  m_pDBG->Log(lines[i]);
827  m_ProgramIsStopped = true;
828  QueueCommand(new DebuggerCmd(this, _T("quit")));
829  m_IsStarted = false;
830  }
831 
832  // no debug symbols?
833  else if (lines[i].Contains(_T("(no debugging symbols found)")))
834  m_pDBG->Log(lines[i]);
835 
836  // signal
837  else if (lines[i].StartsWith(_T("Program received signal SIG")))
838  {
839  m_ProgramIsStopped = true;
840  m_QueueBusy = false;
841 
842  if ( lines[i].StartsWith(_T("Program received signal SIGINT"))
843  || lines[i].StartsWith(_T("Program received signal SIGTRAP"))
844  || lines[i].StartsWith(_T("Program received signal SIGSTOP")) )
845  {
846  // these are break/trace signals, just log them
847  Log(lines[i]);
848  }
849  else
850  {
851  Log(lines[i]);
853 
854  if (Manager::Get()->GetDebuggerManager()->ShowBacktraceDialog())
855  m_forceUpdate = true;
856 
857  InfoWindow::Display(_("Signal received"), _T("\n\n") + lines[i] + _T("\n\n"));
858  m_needsUpdate = true;
859  // the backtrace will be generated when NotifyPlugins() is called
860  // and only if the backtrace window is shown
861  }
862  }
863 
864  // general errors
865  // we don't deal with them, just relay them back to the user
866  else if ( lines[i].StartsWith(_T("Error "))
867  || lines[i].StartsWith(_T("No such"))
868  || lines[i].StartsWith(_T("Cannot evaluate")) )
869  {
870  m_pDBG->Log(lines[i]);
871  }
872 
873  else if ( (lines[i].StartsWith(_T("Cannot find bounds of current function")))
874  || (lines[i].StartsWith(_T("No stack"))) )
875  {
876  m_pDBG->Log(lines[i]);
877  m_ProgramIsStopped = true;
878  }
879 
880  // pending breakpoint resolved?
881  // e.g.
882  // Pending breakpoint "C:/Devel/libs/irr_svn/source/Irrlicht/CSceneManager.cpp:1077" resolved
883  // Breakpoint 2, irr::scene::CSceneManager::getSceneNodeFromName (this=0x3fa878, name=0x3fbed8 "MainLevel", start=0x3fa87c) at CSceneManager.cpp:1077
884  else if (lines[i].StartsWith(_T("Pending breakpoint ")))
885  {
886  m_pDBG->Log(lines[i]);
887 
888  // we face a problem here:
889  // gdb sets a *new* breakpoint when the pending address is resolved.
890  // this means we must update the breakpoint index we have stored
891  // or else we can never remove this (because the breakpoint index doesn't match)...
892 
893  // Pending breakpoint "C:/Devel/libs/irr_svn/source/Irrlicht/CSceneManager.cpp:1077" resolved
894  wxString bpstr = lines[i];
895 
896  if (rePendingFound.Matches(bpstr))
897  {
898  // there are cases where 'newbpstr' is not the next message
899  // e.g. [Switching to thread...]
900  // so we 'll loop over lines starting with [
901 
902  // Breakpoint 2, irr::scene::CSceneManager::getSceneNodeFromName (this=0x3fa878, name=0x3fbed8 "MainLevel", start=0x3fa87c) at CSceneManager.cpp:1077
903  wxString newbpstr = lines[++i];
904  while (i < lines.GetCount() - 1 && newbpstr.StartsWith(_T("[")))
905  newbpstr = lines[++i];
906 
907  if (rePendingFound1.Matches(newbpstr))
908  {
909 // m_pDBG->Log(_T("MATCH"));
910 
911  wxString file;
912  wxString lineStr;
913 
914  if (platform::windows)
915  {
916  file = rePendingFound.GetMatch(bpstr, 1) + rePendingFound.GetMatch(bpstr, 2);
917  lineStr = rePendingFound.GetMatch(bpstr, 3);
918  }
919  else
920  {
921  file = rePendingFound.GetMatch(bpstr, 1);
922  lineStr = rePendingFound.GetMatch(bpstr, 2);
923  }
924 
925  file = UnixFilename(file);
926  // m_pDBG->Log(wxString::Format(_T("file: %s, line: %s"), file.c_str(), lineStr.c_str()));
927  long line;
928  lineStr.ToLong(&line);
929  DebuggerState& state = m_pDBG->GetState();
930  int bpindex = state.HasBreakpoint(file, line - 1, false);
931  cb::shared_ptr<DebuggerBreakpoint> bp = state.GetBreakpoint(bpindex);
932  if (bp)
933  {
934  // m_pDBG->Log(_T("Found BP!!! Updating index..."));
935  long index;
936  wxString indexStr = rePendingFound1.GetMatch(newbpstr, 1);
937  indexStr.ToLong(&index);
938  // finally! update the breakpoint index
939  bp->index = index;
940  }
941  }
942  }
943  }
944 
945  else if (lines[i].StartsWith(wxT("Breakpoint ")))
946  {
947  if (rePendingFound1.Matches(lines[i]))
948  {
949  long index;
950  rePendingFound1.GetMatch(lines[i],1).ToLong(&index);
951  DebuggerState& state = m_pDBG->GetState();
952  cb::shared_ptr<DebuggerBreakpoint> bp = state.GetBreakpointByNumber(index);
953  if (bp && bp->wantsCondition)
954  {
955  bp->wantsCondition = false;
957  m_needsUpdate = true;
958  }
959  }
960  }
961 
962  else if (lines[i].StartsWith(wxT("Temporary breakpoint")))
963  {
964  if (reTempBreakFound.Matches(lines[i]))
965  {
966  long index;
967  reTempBreakFound.GetMatch(lines[i],1).ToLong(&index);
968  DebuggerState& state = m_pDBG->GetState();
969  cb::shared_ptr<DebuggerBreakpoint> bp = state.GetBreakpointByNumber(index);
970  state.RemoveBreakpoint(bp, false);
972  }
973  }
974 
975  // cursor change
976  else if (lines[i].StartsWith(g_EscapeChar)) // ->->
977  {
978  // breakpoint, e.g.
979  // C:/Devel/tmp/test_console_dbg/tmp/main.cpp:14:171:beg:0x401428
980 
981  // Main breakpoint handler is wrapped into a function so we can use
982  // the same code with different regular expressions - depending on
983  // the platform.
984 
985  //NOTE: This also winds up matching response to a frame command which is generated as
986  //part of a backtrace with autoswitch enabled, (from gdb7.2 mingw) as in:
987  //(win32, x86, mingw gdb 7.2)
988  //>>>>>>cb_gdb:
989  //> frame 1
990  //#1 0x6f826722 in wxInitAllImageHandlers () at ../../src/common/imagall.cpp:29
991  //^Z^ZC:\dev\wxwidgets\wxWidgets-2.8.10\build\msw/../../src/common/imagall.cpp:29:961:beg:0x6f826722
992  //>>>>>>cb_gdb:
993 
994  HandleMainBreakPoint(reBreak, lines[i]);
995  }
996  else
997  {
998  // other break info, e.g.
999  // 0x7c9507a8 in ntdll!KiIntSystemCall () from C:\WINDOWS\system32\ntdll.dll
1000  wxRegEx* re = 0;
1001  if ( reBreak2.Matches(lines[i]) )
1002  re = &reBreak2;
1003  else if (reThreadSwitch.Matches(lines[i]))
1004  re = &reThreadSwitch;
1005 
1006  if ( re )
1007  {
1008  m_Cursor.file = re->GetMatch(lines[i], 3);
1009  m_Cursor.function = re->GetMatch(lines[i], 2);
1010  wxString lineStr = _T("");
1011  m_Cursor.address = re->GetMatch(lines[i], 1);
1012  m_Cursor.line = -1;
1013  m_Cursor.changed = true;
1014  m_needsUpdate = true;
1015  }
1016  else if ( reThreadSwitch2.Matches(lines[i]) )
1017  {
1018  m_Cursor.file = reThreadSwitch2.GetMatch(lines[i], 3);
1019  m_Cursor.function = reThreadSwitch2.GetMatch(lines[i], 2);
1020  wxString lineStr = reThreadSwitch2.GetMatch(lines[i], 4);
1021  m_Cursor.address = reThreadSwitch2.GetMatch(lines[i], 1);
1022  m_Cursor.line = -1;
1023  m_Cursor.changed = true;
1024  m_needsUpdate = true;
1025  }
1026  else if (reBreak3.Matches(lines[i]) )
1027  {
1028  m_Cursor.file=_T("");
1029  m_Cursor.function= reBreak3.GetMatch(lines[i], 2);
1030  m_Cursor.address = reBreak3.GetMatch(lines[i], 1);
1031  m_Cursor.line = -1;
1032  m_Cursor.changed = true;
1033  m_needsUpdate = true;
1034  }
1035  else if (reCatchThrow.Matches(lines[i]) )
1036  {
1037  m_Cursor.file = reCatchThrow.GetMatch(lines[i], 4);
1038  m_Cursor.function= reCatchThrow.GetMatch(lines[i], 3);
1039  m_Cursor.address = reCatchThrow.GetMatch(lines[i], 2);
1040  m_Cursor.line = -1;
1041  m_Cursor.changed = true;
1042  m_needsUpdate = true;
1043  }
1044  else if (reCatchThrowNoFile.Matches(lines[i]) )
1045  {
1049  m_Cursor.line = -1;
1050  m_Cursor.changed = true;
1051  m_needsUpdate = true;
1052  }
1053  }
1054  }
1055  buffer.Clear();
1056 
1057  if (foundPrompt && m_DCmds.empty() && !m_ProgramIsStopped && !m_Cursor.changed)
1058  {
1059  QueueCommand(new GdbCmd_FindCursor(this));
1060  m_ProgramIsStopped = true;
1061  }
1062 
1063  // if program is stopped, update various states
1064  if (m_needsUpdate)
1065  {
1066  if (1 == changeFrameAddr)
1067  {
1068  // clear to avoid change of disassembly address on (auto) frame change
1069  // when NotifyCursorChanged() executes
1071  }
1072  if (m_Cursor.changed)
1073  {
1074  m_ProgramIsStopped = true;
1075  m_QueueBusy = false;
1076  }
1079  }
1080 
1081  if (m_ProgramIsStopped)
1082  RunQueue();
1083 }
1084 
1085 
1087 {
1088  if ( reBreak_in.Matches(line) )
1089  {
1092 
1094  Continue();
1095  else
1096  {
1097  m_ManualBreakOnEntry = false;
1098  wxString lineStr;
1099 
1100  if (platform::windows)
1101  {
1102  m_Cursor.file = reBreak_in.GetMatch(line, 1) + reBreak_in.GetMatch(line, 2);
1103  }
1104  else
1105  {
1106  // For debuging of usual linux application 'GetMatch(line, 1)' is empty.
1107  // While for debuging of application under wine the name of the disk is useless.
1108  m_Cursor.file = reBreak_in.GetMatch( line, 2);
1109  }
1110 
1111  lineStr = reBreak_in.GetMatch(line, 3);
1112  m_Cursor.address = reBreak_in.GetMatch(line, 4);
1113 
1114  lineStr.ToLong(&m_Cursor.line);
1115  m_Cursor.changed = true;
1116  m_needsUpdate = true;
1117  }
1118  }
1119  else
1120  {
1121  m_pDBG->Log(_("The program has stopped on a breakpoint but the breakpoint format is not recognized:"));
1122  m_pDBG->Log(line);
1123  m_Cursor.changed = true;
1124  m_needsUpdate = true;
1125  }
1126 }
1127 
1129 {
1131 }
1132 
virtual void StepIntoInstruction()
Definition: gdb_driver.cpp:468
Command to get a watched variable&#39;s type.
Definition: gdb_commands.h:854
static wxRegEx reBreak3(_T("^(0x[A-Fa-f0-9]+) in (.*)"))
DLLIMPORT wxArrayString GetArrayFromString(const wxString &text, const wxString &separator=DEFAULT_ARRAY_SEP, bool trimSpaces=true)
Definition: globals.cpp:134
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
static void Display(const wxString &title, const wxString &message, unsigned int delay=5000, unsigned int hysteresis=1)
Definition: infowindow.cpp:294
virtual void Start(bool breakOnEntry)
Begin the debugging process by launching a program.
Definition: gdb_driver.cpp:391
void NotifyCursorChanged()
Called by implementations to notify cursor changes.
virtual void Detach()
Detach from running process.
Definition: gdb_driver.cpp:686
virtual void Attach(int pid)
Attach to process.
Definition: gdb_driver.cpp:678
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 m_CygdrivePrefix
Definition: gdb_driver.h:84
Base class for all Continue type of commands.
virtual void RunningThreads()
Definition: gdb_driver.cpp:531
void CorrectCygwinPath(wxString &path)
Definition: gdb_driver.cpp:328
Command to remove a breakpoint.
Definition: gdb_commands.h:590
wxString additionalCmds
commands after remote connection established
void RunQueue()
runs the next command in the queue, if it is idle
std::vector< cb::shared_ptr< GDBWatch > > WatchesContainer
DebuggerGDB * m_pDBG
#define FULL_GDB_PROMPT
Definition: gdb_driver.cpp:33
wxString additionalShellCmdsAfter
shell commands after remote connection established
static wxRegEx rePendingFound1(_T("^Breakpoint[ \+([0-9]+),.*"))
virtual void Reload()=0
RemoteDebugging m_MergedRDInfo
Definition: gdb_driver.h:112
void BringCBToFront()
Definition: cbplugin.cpp:913
long m_GDBVersionMinor
Definition: gdb_driver.h:103
virtual void SwitchThread(size_t threadIndex)
Request to switch to another thread.
Definition: gdb_driver.cpp:576
virtual void EvaluateSymbol(const wxString &symbol, const wxRect &tipRect)
Evaluate a symbol.
Definition: gdb_driver.cpp:623
wxCStrData c_str() const
bool m_BreakOnEntry
Definition: gdb_driver.h:88
bool Matches(const wxString &text, int flags=0) const
static wxRegEx reChildPid2(_T("\New [tT]hread[ \+[0-9]+\[xA-Fa-f0-9-]+\"))
#define _T(string)
int m_catchThrowIndex
Definition: gdb_driver.h:114
Command to get info about running threads.
Definition: gdb_commands.h:733
Command to get a symbol&#39;s type and use it for tooltip evaluation.
virtual void SwitchToFrame(size_t number)
Definition: gdb_driver.cpp:514
void Log(const wxString &msg, Logger::level level=Logger::info)
Definition: cbplugin.cpp:530
virtual void Backtrace()
Definition: gdb_driver.cpp:493
wxString & Remove(size_t pos)
void RemoveTopCommand(bool deleteIt=true)
removes the top command (it has finished)
static wxRegEx reInferiorExited(wxT("^\Inferior[ \].+[ \]exited normally\$"), wxRE_EXTENDED)
long int line
If -1, no line info.
Definition: debugger_defs.h:32
Action-only debugger command to signal the watches tree to update.
void Log(const wxString &msg)
wxString AfterFirst(wxUniChar ch) const
wxString flavour
Definition: gdb_driver.h:104
void RemoveBreakpoint(int idx, bool removeFromDriver=true)
#define wxT(string)
virtual void SetNextStatement(const wxString &filename, int line)
Definition: gdb_driver.cpp:486
#define wxNOT_FOUND
bool empty() const
static wxRegEx reInferiorExitedWithCode(wxT("^\[Ii]nferior[ \].+[ \]exited[ \]with[ \]code[ \]([0-9]+)\$"), wxRE_EXTENDED)
wxString additionalCmdsBefore
commands before establishing remote connection
Command which tries to find the current cursor position.
Command to initialize a disassembly.
virtual void CPURegisters()
Definition: gdb_driver.cpp:506
Command to get info about current program and state.
Definition: gdb_commands.h:705
bool IsAttachedToProcess() const
void DetectCygwinMount(void)
Definition: gdb_driver.cpp:272
wxString BeforeFirst(wxUniChar ch, wxString *rest=NULL) const
bool changed
Definition: debugger_defs.h:33
static wxRegEx reBreak(_T("\2*([A-Za-z]*[:]*)([^:]+):([0-9]+):[0-9]+:[begmidl]+:(0x[0-9A-Fa-f]+)"))
DebuggerManager * GetDebuggerManager() const
Definition: manager.cpp:484
long m_GDBVersionMajor
Definition: gdb_driver.h:102
DLLIMPORT wxString UnixFilename(const wxString &filename, wxPathFormat format=wxPATH_NATIVE)
Definition: globals.cpp:228
Command to determine the debugging (working) language.
virtual void MemoryDump()
Definition: gdb_driver.cpp:526
bool m_IsStarted
Definition: gdb_driver.h:95
cb::shared_ptr< DebuggerBreakpoint > GetBreakpointByNumber(int num)
Command to add a search directory for source files in debugger&#39;s paths.
Definition: gdb_commands.h:226
virtual wxString GetCommandLine(const wxString &debugger, const wxString &debuggee, const wxString &userArguments)
Get the command-line to launch the debugger.
Definition: gdb_driver.cpp:101
void DetermineLanguage()
static wxRegEx reCatchThrow(_T("^Catchpoint ([0-9]+) \exception thrown\, (0x[0-9a-f]+) in (.+) from (.+)$"))
wxString & RemoveLast(size_t n=1)
void InfoFPU()
Definition: gdb_driver.cpp:555
virtual void StepIn()
Definition: gdb_driver.cpp:474
const wxString g_EscapeChar
cbDisassemblyDlg * GetDisassemblyDialog()
Returns a pointer to the disassembly dialog.
void ResetCursor()
Called by implementations to reset the cursor.
Command to change the current frame.
wxString Left(size_t count) const
size_t Replace(const wxString &strOld, const wxString &strNew, bool replaceAll=true)
wxString m_FileName
RemoteDebugging * GetRemoteDebuggingInfo()
Definition: gdb_driver.cpp:249
DebuggerState & GetState()
Definition: debuggergdb.h:114
bool IsSameAs(const wxString &s, bool caseSensitive=true) const
void SetChildPID(long pid)
Set child PID (debuggee&#39;s).
int HasBreakpoint(const wxString &file, int line, bool temp)
bool GetMatch(size_t *start, size_t *len, size_t index=0) const
static wxRegEx reThreadSwitch(_T("^\Switching to thread .*\#0[ \+(0x[A-Fa-f0-9]+) in (.*) from (.*)"))
wxString & Item(size_t nIndex)
This command is similar to DebuggerCmd The only difference is that instead of logging its output in t...
Definition: debugger_defs.h:87
Command to run a backtrace.
Utility command to set a breakpoint condition.
Definition: gdb_commands.h:387
virtual void StepInstruction()
Definition: gdb_driver.cpp:462
Command to add a breakpoint.
Definition: gdb_commands.h:432
void clear()
void QueueCommand(DebuggerCmd *dcmd, QueuePriority prio=Low)
add a command in the queue. The DebuggerCmd will be deleted automatically when finished.
wxArrayString m_Dirs
static wxRegEx reCatchThrowNoFile(_T("^Catchpoint ([0-9]+) \exception thrown\, (0x[0-9a-f]+) in (.+)$"))
wxString wxEmptyString
virtual void Clear(const cbStackFrame &frame)=0
virtual void ParseOutput(const wxString &output)
Parse debugger&#39;s output.
Definition: gdb_driver.cpp:691
DebuggerConfiguration & GetActiveConfigEx()
MacrosManager * GetMacrosManager() const
Definition: manager.cpp:454
void EnableCatchingThrow(bool enable)
Definition: gdb_driver.cpp:565
void InfoSignals()
Definition: gdb_driver.cpp:560
virtual void AddBreakpoint(cb::shared_ptr< DebuggerBreakpoint > bp)
Add a breakpoint.
Definition: gdb_driver.cpp:584
const wxString & _(const wxString &string)
bool m_attachedToProcess
Definition: gdb_driver.h:106
virtual void Disassemble()
Definition: gdb_driver.cpp:498
void ReplaceMacros(wxString &buffer, ProjectBuildTarget *target=nullptr, bool subrequest=false)
bool IsOk() const
void InfoFrame()
Definition: gdb_driver.cpp:537
virtual void Prepare(bool isConsole, int printElements)
Prepares the debugging process by setting up search dirs etc.
Definition: gdb_driver.cpp:132
bool m_needsUpdate
Definition: gdb_driver.h:98
void InfoDLL()
Definition: gdb_driver.cpp:542
virtual void UpdateWatchLocalsArgs(cb::shared_ptr< GDBWatch > const &watch, bool locals)
Definition: gdb_driver.cpp:672
virtual void Continue()
Definition: gdb_driver.cpp:436
int First(wxUniChar ch) const
bool m_forceUpdate
Definition: gdb_driver.h:99
virtual void StepOut()
Definition: gdb_driver.cpp:480
virtual void Step()
Definition: gdb_driver.cpp:456
static wxRegEx reChildPid1(_T("Thread[ \+[xA-Fa-f0-9-]+[ \+\LWP ([0-9]+)\]"))
bool ToLong(long *val, int base=10) const
wxString function
Definition: debugger_defs.h:31
GDB_driver(DebuggerGDB *plugin)
Definition: gdb_driver.cpp:80
static wxRegEx reThreadSwitch2(_T("^\Switching to thread .*\#0[ \+(0x[A-Fa-f0-9]+) in (.*) from (.*):([0-9]+)"))
virtual bool UseDebugBreakProcess()
Ask the driver if the debugger should be interrupted with DebugBreakProcess or Ctrl+C event...
Definition: gdb_driver.cpp:376
Command to the attach to a process.
Definition: gdb_commands.h:318
virtual wxString GetDisassemblyFlavour(void)
Definition: gdb_driver.cpp:384
bool IsEmpty() const
void Clear()
size_t Len() const
cbBreakpointsDlg * GetBreakpointDialog()
Returns a pointer to the breakpoints dialog.
virtual void ParseOutput(const wxString &output)
Parses the command&#39;s output.
wxString CleanStringValue(wxString value)
RemoteDebuggingMap & GetRemoteDebuggingMap(cbProject *project=0)
static wxRegEx reTempBreakFound(wxT("^[Tt]emporary[ \breakpoint[ \([0-9]+),.*"))
bool m_ManualBreakOnEntry
Definition: gdb_driver.h:92
bool EndsWith(const wxString &suffix, wxString *rest=NULL) const
#define GDB_PROMPT
Definition: gdb_driver.cpp:32
virtual void RemoveBreakpoint(cb::shared_ptr< DebuggerBreakpoint > bp)
Remove a breakpoint.
Definition: gdb_driver.cpp:617
bool m_CygwinPresent
Definition: gdb_driver.h:83
Command to examine a memory region.
bool StartsWith(const wxString &prefix, wxString *rest=NULL) const
wxString additionalShellCmdsBefore
shell commands before establishing remote connection
Represents a Code::Blocks project build target.
wxString file
Definition: debugger_defs.h:29
virtual void UpdateWatches(cb::shared_ptr< GDBWatch > localsWatch, cb::shared_ptr< GDBWatch > funcArgsWatch, WatchesContainer &watches)
Update watches.
Definition: gdb_driver.cpp:628
size_t GetCount() const
Command to obtain register info.
DebuggerCmd * CurrentCommand()
returns the currently executing command
wxUniChar GetChar(size_t n) const
wxUniChar Last() const
wxString address
Definition: debugger_defs.h:30
DebuggerCommands m_DCmds
virtual void SetVarValue(const wxString &var, const wxString &value)
Definition: gdb_driver.cpp:520
virtual void DetermineLanguage()
Determine language is debugged.
static wxRegEx rePendingFound(_T("^Pending[ \+breakpoint[ \+[\+([A-Za-z]:)([^:]+):([0-9]+)\*"))
ProjectBuildTarget * m_pTarget
Definition: gdb_driver.h:109
Command to the detach from the process.
Definition: gdb_commands.h:358
void MergeWith(const RemoteDebugging &other)
virtual ~GDB_driver()
Definition: gdb_driver.cpp:96
Basic interface for debugger commands.
Definition: debugger_defs.h:49
#define NULL
Definition: prefix.cpp:59
static wxString Format(const wxString &format,...)
ConnectionType connType
virtual void SetTarget(ProjectBuildTarget *target)
Sets the target.
Definition: gdb_driver.cpp:126
void HandleMainBreakPoint(const wxRegEx &reBreak, wxString line)
void DebugLog(const wxString &msg, Logger::level level=Logger::info)
Definition: cbplugin.cpp:540
virtual void Stop()
Stop debugging.
Definition: gdb_driver.cpp:426
static wxRegEx reBreak2(_T("^(0x[A-Fa-f0-9]+) in (.*) from (.*)"))
cb::shared_ptr< DebuggerBreakpoint > GetBreakpoint(int idx)
void InfoFiles()
Definition: gdb_driver.cpp:550
virtual void UpdateWatch(const cb::shared_ptr< GDBWatch > &watch)
Definition: gdb_driver.cpp:666