Code::Blocks  SVN r11506
debuggergdb.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: debuggergdb.cpp 11490 2018-10-03 14:27:48Z mortenmacfly $
7  * $HeadURL: https://svn.code.sf.net/p/codeblocks/code/trunk/src/plugins/debuggergdb/debuggergdb.cpp $
8  */
9 
10 #include <sdk.h>
11 #include <algorithm> // std::remove_if
12 
13 #ifndef CB_PRECOMP
14  #include <wx/app.h>
15  #include <wx/txtstrm.h>
16  #include <wx/regex.h>
17  #include <wx/msgdlg.h>
18  #include <wx/frame.h> // GetMenuBar
19  #include <wx/menu.h>
20  #include <wx/filedlg.h>
21 
22  #include "cbproject.h"
23  #include "manager.h"
24  #include "configmanager.h"
25  #include "logmanager.h" // for F
26  #include "projectmanager.h"
27  #include "pluginmanager.h"
28  #include "editormanager.h"
29  #include "macrosmanager.h"
30  #include "cbeditor.h"
31  #include "projectbuildtarget.h"
32  #include "sdk_events.h"
33  #include "compilerfactory.h"
34  #include "xtra_res.h"
35 
36  #include "scrollingdialog.h"
37  #include "globals.h"
38 #endif
39 
40 #include <wx/tokenzr.h>
41 #include "editarraystringdlg.h"
42 #include "projectloader_hooks.h"
43 #include "annoyingdialog.h"
44 #include "cbstyledtextctrl.h"
46 
47 #include <cbdebugger_interfaces.h>
48 #include "editbreakpointdlg.h"
49 
50 #include "databreakpointdlg.h"
51 #include "debuggerdriver.h"
52 #include "debuggergdb.h"
53 #include "debuggeroptionsdlg.h"
54 #include "debuggeroptionsprjdlg.h"
55 #include "editwatchdlg.h"
56 
57 
58 #define implement_debugger_toolbar
59 
60 // function pointer to DebugBreakProcess under windows (XP+)
61 #if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501)
62 #include "Tlhelp32.h"
63 typedef BOOL WINAPI (*DebugBreakProcessApiCall) (HANDLE);
64 typedef HANDLE WINAPI (*CreateToolhelp32SnapshotApiCall)(DWORD dwFlags, DWORD th32ProcessID);
65 typedef BOOL WINAPI (*Process32FirstApiCall) (HANDLE hSnapshot, LPPROCESSENTRY32W lppe);
66 typedef BOOL WINAPI (*Process32NextApiCall) (HANDLE hSnapshot, LPPROCESSENTRY32W lppe);
67 
68 DebugBreakProcessApiCall DebugBreakProcessFunc = 0;
69 CreateToolhelp32SnapshotApiCall CreateToolhelp32SnapshotFunc = 0;
70 Process32FirstApiCall Process32FirstFunc = 0;
71 Process32NextApiCall Process32NextFunc = 0;
72 
73 HINSTANCE kernelLib = 0;
74 
75 #endif
76 
77 #ifdef __WXMSW__
78 // disable the CTRL_C event
79 inline BOOL WINAPI HandlerRoutine(cb_unused DWORD dwCtrlType)
80 {
81  return TRUE;
82 }
83 #endif
84 
85 // valid debugger command constants
87 {
100 };
101 
102 const wxString g_EscapeChar = wxChar(26);
103 
104 namespace
105 {
106 long idMenuInfoFrame = wxNewId();
107 long idMenuInfoDLL = wxNewId();
108 long idMenuInfoFiles = wxNewId();
109 long idMenuInfoFPU = wxNewId();
110 long idMenuInfoSignals = wxNewId();
111 
112 long idMenuInfoPrintElementsUnlimited = wxNewId();
113 long idMenuInfoPrintElements20 = wxNewId();
114 long idMenuInfoPrintElements50 = wxNewId();
115 long idMenuInfoPrintElements100 = wxNewId();
116 long idMenuInfoPrintElements200 = wxNewId();
117 
118 long idMenuInfoCatchThrow = wxNewId();
119 
120 long idGDBProcess = wxNewId();
121 long idTimerPollDebugger = wxNewId();
122 
123 long idMenuWatchDereference = wxNewId();
124 
125 // this auto-registers the plugin
126 PluginRegistrant<DebuggerGDB> reg(_T("Debugger"));
127 }
128 
129 BEGIN_EVENT_TABLE(DebuggerGDB, cbDebuggerPlugin)
130  EVT_MENU(idMenuInfoFrame, DebuggerGDB::OnInfoFrame)
131  EVT_MENU(idMenuInfoDLL, DebuggerGDB::OnInfoDLL)
132  EVT_MENU(idMenuInfoFiles, DebuggerGDB::OnInfoFiles)
133  EVT_MENU(idMenuInfoFPU, DebuggerGDB::OnInfoFPU)
134  EVT_MENU(idMenuInfoSignals, DebuggerGDB::OnInfoSignals)
135 
136  EVT_MENU(idMenuWatchDereference, DebuggerGDB::OnMenuWatchDereference)
137 
141 
142  EVT_IDLE(DebuggerGDB::OnIdle)
143  EVT_TIMER(idTimerPollDebugger, DebuggerGDB::OnTimer)
144 
147 
148  EVT_UPDATE_UI(idMenuInfoPrintElementsUnlimited, DebuggerGDB::OnUpdateTools)
149  EVT_UPDATE_UI(idMenuInfoPrintElements20, DebuggerGDB::OnUpdateTools)
150  EVT_UPDATE_UI(idMenuInfoPrintElements50, DebuggerGDB::OnUpdateTools)
151  EVT_UPDATE_UI(idMenuInfoPrintElements100, DebuggerGDB::OnUpdateTools)
152  EVT_UPDATE_UI(idMenuInfoPrintElements200, DebuggerGDB::OnUpdateTools)
153 
154  EVT_MENU(idMenuInfoPrintElementsUnlimited, DebuggerGDB::OnPrintElements)
155  EVT_MENU(idMenuInfoPrintElements20, DebuggerGDB::OnPrintElements)
156  EVT_MENU(idMenuInfoPrintElements50, DebuggerGDB::OnPrintElements)
157  EVT_MENU(idMenuInfoPrintElements100, DebuggerGDB::OnPrintElements)
158  EVT_MENU(idMenuInfoPrintElements200, DebuggerGDB::OnPrintElements)
159 
160  EVT_UPDATE_UI(idMenuInfoCatchThrow, DebuggerGDB::OnUpdateCatchThrow)
161  EVT_MENU(idMenuInfoCatchThrow, DebuggerGDB::OnCatchThrow)
162 END_EVENT_TABLE()
163 
165  cbDebuggerPlugin(wxT("GDB/CDB debugger"), wxT("gdb_debugger")),
166  m_State(this),
167  m_pProcess(0L),
168  m_LastExitCode(0),
169  m_Pid(0),
170  m_PidToAttach(0),
171  m_NoDebugInfo(false),
172  m_StoppedOnSignal(false),
173  m_pProject(0),
174  m_bIsConsole(false),
175  m_stopDebuggerConsoleClosed(false),
176  m_nConsolePid(0),
177  m_TemporaryBreak(false),
178  m_printElements(200)
179 {
180  if (!Manager::LoadResource(_T("debugger.zip")))
181  {
182  NotifyMissingFile(_T("debugger.zip"));
183  }
184 
185  // get a function pointer to DebugBreakProcess under windows (XP+)
186  #if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501)
187  kernelLib = LoadLibrary(TEXT("kernel32.dll"));
188  if (kernelLib)
189  {
190  DebugBreakProcessFunc = (DebugBreakProcessApiCall)GetProcAddress(kernelLib, "DebugBreakProcess");
191  //Windows XP
192  CreateToolhelp32SnapshotFunc = (CreateToolhelp32SnapshotApiCall)GetProcAddress(kernelLib, "CreateToolhelp32Snapshot");
193  Process32FirstFunc = (Process32FirstApiCall)GetProcAddress(kernelLib, "Process32First");
194  Process32NextFunc = (Process32NextApiCall)GetProcAddress(kernelLib, "Process32Next");
195  }
196  #endif
197 }
198 
200 {
201  #if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501)
202  if (kernelLib)
203  FreeLibrary(kernelLib);
204  #endif
205 }
206 
208 {
209  m_TimerPollDebugger.SetOwner(this, idTimerPollDebugger);
210 
211  // hook to project loading procedure
214 
215  // register event sink
217 }
218 
219 void DebuggerGDB::OnReleaseReal(cb_unused bool appShutDown)
220 {
222 
223  //Close debug session when appShutDown
224  if (m_State.HasDriver())
225  {
226  Stop();
227  wxYieldIfNeeded();
228  }
229 
230  m_State.CleanUp();
231  KillConsole();
232 }
233 
235 {
237 
238  if (config.IsGDB())
239  {
240  switch (flag)
241  {
252  return true;
253  default:
254  return false;
255  }
256  }
257  else
258  {
259  switch (flag)
260  {
267  return true;
272  default:
273  return false;
274  }
275  }
276 
277  return false;
278 }
279 
281 {
282  return new DebuggerConfiguration(config);
283 }
284 
286 {
287  return static_cast<DebuggerConfiguration&>(GetActiveConfig());
288 }
289 
291 {
292  DebuggerOptionsProjectDlg* dlg = new DebuggerOptionsProjectDlg(parent, this, project);
293  return dlg;
294 }
295 
296 void DebuggerGDB::OnConfigurationChange(cb_unused bool isActive)
297 {
299  bool locals = config.GetFlag(DebuggerConfiguration::WatchLocals);
300  bool funcArgs = config.GetFlag(DebuggerConfiguration::WatchFuncArgs);
301 
303  bool update = false;
304 
305  if (!locals)
306  {
307  if (m_localsWatch)
308  {
309  watchesDialog->RemoveWatch(m_localsWatch);
310  m_localsWatch = cb::shared_ptr<GDBWatch>();
311  }
312  }
313  else if (!m_localsWatch)
314  update = true;
315 
316  if (!funcArgs)
317  {
318  if (m_funcArgsWatch)
319  {
320  watchesDialog->RemoveWatch(m_funcArgsWatch);
321  m_funcArgsWatch = cb::shared_ptr<GDBWatch>();
322  }
323  }
324  else if (!m_funcArgsWatch)
325  update = true;
326 
327  if (update)
329 }
330 
332 {
333  SearchDirsMap::iterator it = m_SearchDirs.find(prj);
334  if (it == m_SearchDirs.end()) // create an empty set for this project
335  it = m_SearchDirs.insert(m_SearchDirs.begin(), std::make_pair(prj, wxArrayString()));
336 
337  return it->second;
338 }
339 
341 {
342  if (!project)
343  project = m_pProject;
344 
345  ProjectRemoteDebuggingMap::iterator it = m_RemoteDebugging.find(project);
346  if (it == m_RemoteDebugging.end()) // create an empty set for this project
347  it = m_RemoteDebugging.insert(m_RemoteDebugging.begin(), std::make_pair(project, RemoteDebuggingMap()));
348 
349  return it->second;
350 }
351 
352 
353 void DebuggerGDB::OnProjectLoadingHook(cbProject* project, TiXmlElement* elem, bool loading)
354 {
355  wxArrayString& pdirs = GetSearchDirs(project);
356  RemoteDebuggingMap& rdprj = GetRemoteDebuggingMap(project);
357 
358  if (loading)
359  {
360  rdprj.clear();
361 
362  // Hook called when loading project file.
363  TiXmlElement* conf = elem->FirstChildElement("debugger");
364  if (conf)
365  {
366  TiXmlElement* pathsElem = conf->FirstChildElement("search_path");
367  while (pathsElem)
368  {
369  if (pathsElem->Attribute("add"))
370  {
371  wxString dir = cbC2U(pathsElem->Attribute("add"));
372  if (pdirs.Index(dir) == wxNOT_FOUND)
373  pdirs.Add(dir);
374  }
375 
376  pathsElem = pathsElem->NextSiblingElement("search_path");
377  }
378 
379  TiXmlElement* rdElem = conf->FirstChildElement("remote_debugging");
380  while (rdElem)
381  {
382  wxString targetName = cbC2U(rdElem->Attribute("target"));
383  ProjectBuildTarget* bt = project->GetBuildTarget(targetName);
384 
385  TiXmlElement* rdOpt = rdElem->FirstChildElement("options");
386 
387  if (rdOpt)
388  {
389  RemoteDebugging rd;
390 
391  if (rdOpt->Attribute("conn_type"))
392  rd.connType = (RemoteDebugging::ConnectionType)atol(rdOpt->Attribute("conn_type"));
393  if (rdOpt->Attribute("serial_port"))
394  rd.serialPort = cbC2U(rdOpt->Attribute("serial_port"));
395  if (rdOpt->Attribute("serial_baud"))
396  rd.serialBaud = cbC2U(rdOpt->Attribute("serial_baud"));
397  if (rdOpt->Attribute("ip_address"))
398  rd.ip = cbC2U(rdOpt->Attribute("ip_address"));
399  if (rdOpt->Attribute("ip_port"))
400  rd.ipPort = cbC2U(rdOpt->Attribute("ip_port"));
401  if (rdOpt->Attribute("additional_cmds"))
402  rd.additionalCmds = cbC2U(rdOpt->Attribute("additional_cmds"));
403  if (rdOpt->Attribute("additional_cmds_before"))
404  rd.additionalCmdsBefore = cbC2U(rdOpt->Attribute("additional_cmds_before"));
405  if (rdOpt->Attribute("skip_ld_path"))
406  rd.skipLDpath = cbC2U(rdOpt->Attribute("skip_ld_path")) != _T("0");
407  if (rdOpt->Attribute("extended_remote"))
408  rd.extendedRemote = cbC2U(rdOpt->Attribute("extended_remote")) != _T("0");
409  if (rdOpt->Attribute("additional_shell_cmds_after"))
410  rd.additionalShellCmdsAfter = cbC2U(rdOpt->Attribute("additional_shell_cmds_after"));
411  if (rdOpt->Attribute("additional_shell_cmds_before"))
412  rd.additionalShellCmdsBefore = cbC2U(rdOpt->Attribute("additional_shell_cmds_before"));
413 
414  rdprj.insert(rdprj.end(), std::make_pair(bt, rd));
415  }
416 
417  rdElem = rdElem->NextSiblingElement("remote_debugging");
418  }
419  }
420  }
421  else
422  {
423  // Hook called when saving project file.
424 
425  // since rev4332, the project keeps a copy of the <Extensions> element
426  // and re-uses it when saving the project (so to avoid losing entries in it
427  // if plugins that use that element are not loaded atm).
428  // so, instead of blindly inserting the element, we must first check it's
429  // not already there (and if it is, clear its contents)
430  TiXmlElement* node = elem->FirstChildElement("debugger");
431  if (!node)
432  node = elem->InsertEndChild(TiXmlElement("debugger"))->ToElement();
433  node->Clear();
434 
435  if (pdirs.GetCount() > 0)
436  {
437  for (size_t i = 0; i < pdirs.GetCount(); ++i)
438  {
439  TiXmlElement* path = node->InsertEndChild(TiXmlElement("search_path"))->ToElement();
440  path->SetAttribute("add", cbU2C(pdirs[i]));
441  }
442  }
443 
444  if (rdprj.size())
445  {
446  for (RemoteDebuggingMap::iterator it = rdprj.begin(); it != rdprj.end(); ++it)
447  {
448 // // valid targets only
449 // if (!it->first)
450 // continue;
451 
452  RemoteDebugging& rd = it->second;
453 
454  // if no different than defaults, skip it
455  if (rd.serialPort.IsEmpty() && rd.ip.IsEmpty() &&
457  !rd.skipLDpath && !rd.extendedRemote)
458  {
459  continue;
460  }
461 
462  TiXmlElement* rdnode = node->InsertEndChild(TiXmlElement("remote_debugging"))->ToElement();
463  if (it->first)
464  rdnode->SetAttribute("target", cbU2C(it->first->GetTitle()));
465 
466  TiXmlElement* tgtnode = rdnode->InsertEndChild(TiXmlElement("options"))->ToElement();
467  tgtnode->SetAttribute("conn_type", (int)rd.connType);
468  if (!rd.serialPort.IsEmpty())
469  tgtnode->SetAttribute("serial_port", cbU2C(rd.serialPort));
470  if (!rd.serialBaud.IsEmpty())
471  tgtnode->SetAttribute("serial_baud", cbU2C(rd.serialBaud));
472  if (!rd.ip.IsEmpty())
473  tgtnode->SetAttribute("ip_address", cbU2C(rd.ip));
474  if (!rd.ipPort.IsEmpty())
475  tgtnode->SetAttribute("ip_port", cbU2C(rd.ipPort));
476  if (!rd.additionalCmds.IsEmpty())
477  tgtnode->SetAttribute("additional_cmds", cbU2C(rd.additionalCmds));
478  if (!rd.additionalCmdsBefore.IsEmpty())
479  tgtnode->SetAttribute("additional_cmds_before", cbU2C(rd.additionalCmdsBefore));
480  if (rd.skipLDpath)
481  tgtnode->SetAttribute("skip_ld_path", "1");
482  if (rd.extendedRemote)
483  tgtnode->SetAttribute("extended_remote", "1");
485  tgtnode->SetAttribute("additional_shell_cmds_after", cbU2C(rd.additionalShellCmdsAfter));
487  tgtnode->SetAttribute("additional_shell_cmds_before", cbU2C(rd.additionalShellCmdsBefore));
488  }
489  }
490  }
491 }
492 
494 {
495  if (!m_pProcess)
496  return;
497 
499 
500  bool locals = config.GetFlag(DebuggerConfiguration::WatchLocals);
501  bool funcArgs = config.GetFlag(DebuggerConfiguration::WatchFuncArgs);
502 
503 
504  if (locals)
505  {
506  if (m_localsWatch == nullptr)
507  {
508  m_localsWatch = cb::shared_ptr<GDBWatch>(new GDBWatch(wxT("Locals")));
509  m_localsWatch->Expand(true);
510  m_localsWatch->MarkAsChanged(false);
512  watchesDialog->AddSpecialWatch(m_localsWatch, true);
513  }
514  }
515 
516  if (funcArgs)
517  {
518  if (m_funcArgsWatch == nullptr)
519  {
520  m_funcArgsWatch = cb::shared_ptr<GDBWatch>(new GDBWatch(wxT("Function arguments")));
521  m_funcArgsWatch->Expand(true);
522  m_funcArgsWatch->MarkAsChanged(false);
524  watchesDialog->AddSpecialWatch(m_funcArgsWatch, true);
525  }
526  }
527 
529 }
530 
532 {
533  if (platform::windows)
534  return wxEmptyString;
535  wxString shell = Manager::Get()->GetConfigManager(_T("app"))->Read(_T("/console_shell"),
537  // GDB expects the SHELL variable's value to be a path to the shell's executable, so we need to
538  // remove all parameters and do some trimming.
539  shell.Trim(false);
540  wxString::size_type pos = shell.find(wxT(' '));
541  if (pos != wxString::npos)
542  shell.erase(pos);
543  shell.Trim();
544  return shell;
545 }
546 
548  const wxString &cwd)
549 {
550  wxString shell = GetShellString();
551 #if wxCHECK_VERSION(3, 0, 0)
552  wxExecuteEnv execEnv;
553  execEnv.cwd = cwd;
554  // Read the current environment variables and then make changes to them.
555  wxGetEnvMap(&execEnv.env);
556  if (!shell.empty())
557  {
558  Log(wxString::Format(wxT("Setting SHELL to '%s'"), shell.wx_str()));
559  execEnv.env["SHELL"] = shell;
560  }
561  return wxExecute(cmd, wxEXEC_ASYNC, process, &execEnv);
562 #else
563  if (!shell.empty())
564  {
565  Log(wxString::Format(wxT("Setting SHELL to '%s'"), shell.wx_str()));
566  wxSetEnv(wxT("SHELL"), shell);
567  }
568  (void)cwd;
569  return wxExecute(cmd, wxEXEC_ASYNC, process);
570 #endif // !wxCHECK_VERSION(3, 0, 0)
571 }
572 
573 int DebuggerGDB::LaunchProcess(const wxString& cmd, const wxString& cwd)
574 {
575  if (m_pProcess)
576  return -1;
577 
578  // start the gdb process
579  m_pProcess = new PipedProcess(&m_pProcess, this, idGDBProcess, true, cwd);
580  Log(_("Starting debugger: ") + cmd);
582 
583 #ifdef __WXMAC__
584  if (m_Pid == -1)
585  {
586  // Great! We got a fake PID. Time to Go Fish with our "ps" rod:
587 
588  m_Pid = 0;
589  pid_t mypid = getpid();
590  wxString mypidStr;
591  mypidStr << mypid;
592 
593  long pspid = 0;
594  wxString psCmd;
595  wxArrayString psOutput;
596  wxArrayString psErrors;
597 
598  psCmd << wxT("/bin/ps -o ppid,pid,command");
599  DebugLog(wxString::Format( _("Executing: %s"), psCmd.wx_str()) );
600  int result = wxExecute(psCmd, psOutput, psErrors, wxEXEC_SYNC);
601 
602  mypidStr << wxT(" ");
603 
604  for (int i = 0; i < psOutput.GetCount(); ++i)
605  { // PPID PID COMMAND
606  wxString psLine = psOutput.Item(i);
607  if (psLine.StartsWith(mypidStr) && psLine.Contains(wxT("gdb")))
608  {
609  wxString pidStr = psLine.Mid(mypidStr.Length());
610  pidStr = pidStr.BeforeFirst(' ');
611  if (pidStr.ToLong(&pspid))
612  {
613  m_Pid = pspid;
614  break;
615  }
616  }
617  }
618 
619  for (int i = 0; i < psErrors.GetCount(); ++i)
620  DebugLog(wxString::Format( _("PS Error:%s"), psErrors.Item(i).wx_str()) );
621  }
622 #endif
623 
624  if (!m_Pid)
625  {
626  delete m_pProcess;
627  m_pProcess = 0;
628  Log(_("failed"), Logger::error);
629  return -1;
630  }
631  else if (!m_pProcess->GetOutputStream())
632  {
633  delete m_pProcess;
634  m_pProcess = 0;
635  Log(_("failed (to get debugger's stdin)"), Logger::error);
636  return -2;
637  }
638  else if (!m_pProcess->GetInputStream())
639  {
640  delete m_pProcess;
641  m_pProcess = 0;
642  Log(_("failed (to get debugger's stdout)"), Logger::error);
643  return -2;
644  }
645  else if (!m_pProcess->GetErrorStream())
646  {
647  delete m_pProcess;
648  m_pProcess = 0;
649  Log(_("failed (to get debugger's stderr)"), Logger::error);
650  return -2;
651  }
652  Log(_("done"));
653  return 0;
654 }
655 
657 {
659 }
660 
662 {
663  return m_State.HasDriver() && m_State.GetDriver()->IsQueueBusy();
664 }
665 
666 
667 bool DebuggerGDB::Debug(bool breakOnEntry)
668 {
669  // if already running, return
671  return false;
672 
673  m_pProject = 0;
674  m_NoDebugInfo = false;
675 
676  // can only debug projects or attach to processes
678  cbProject* project = prjMan->GetActiveProject();
679  if (!project && m_PidToAttach == 0)
680  return false;
681 
682  m_pProject = project;
685 
686  m_Canceled = false;
687  if (!EnsureBuildUpToDate(breakOnEntry ? StartTypeStepInto : StartTypeRun))
688  return false;
689 
690  // if not waiting for the compiler, start debugging now
691  // but first check if the driver has already been started:
692  // if the build process was ultra-fast (i.e. nothing to be done),
693  // it may have already called DoDebug() and m_WaitingCompilerToFinish
694  // would already be set to false
695  // by checking the driver availability, we avoid calling DoDebug
696  // a second consecutive time...
697  // the same applies for m_Canceled: it is true if DoDebug() was launched but
698  // returned an error
700  {
701  return DoDebug(breakOnEntry) == 0;
702  }
703 
704  return true;
705 }
706 
707 int DebuggerGDB::DoDebug(bool breakOnEntry)
708 {
709  // set this to true before every error exit point in this function
710  m_Canceled = false;
711  // Init these just in case.
712  m_bIsConsole = false;
713  m_nConsolePid = 0;
715 
716  // select the build target to debug
717  ProjectBuildTarget* target = 0;
718  Compiler* actualCompiler = 0;
719  if ( (m_PidToAttach == 0) && m_pProject)
720  {
721  Log(_("Selecting target: "));
723  {
724  int tgtIdx = m_pProject->SelectTarget();
725  if (tgtIdx == -1)
726  {
727  Log(_("canceled"));
728  m_Canceled = true;
729  return 3;
730  }
731  target = m_pProject->GetBuildTarget(tgtIdx);
732  m_ActiveBuildTarget = (target ? target->GetTitle() : wxString(wxEmptyString));
733  }
734  else
736 
737  // make sure it's not a commands-only target
738  if (target && target->GetTargetType() == ttCommandsOnly)
739  {
740  cbMessageBox(_("The selected target is only running pre/post build step commands\n"
741  "Can't debug such a target..."), _("Information"), wxICON_INFORMATION);
742  Log(_("aborted"));
743  return 3;
744  }
745  if (target) Log(target->GetTitle());
746 
747  // find the target's compiler (to see which debugger to use)
748  actualCompiler = CompilerFactory::GetCompiler(target ? target->GetCompilerID()
750  }
751  else
752  actualCompiler = CompilerFactory::GetDefaultCompiler();
753 
754  if (!actualCompiler)
755  {
756  wxString msg;
757  msg.Printf(_("This %s is configured to use an invalid debugger.\nThe operation failed..."), target ? _("target") : _("project"));
758  cbMessageBox(msg, _("Error"), wxICON_ERROR);
759  m_Canceled = true;
760  return 9;
761  }
762 
763  // is gdb accessible, i.e. can we find it?
764  wxString cmdexe;
766  cmdexe.Trim();
767  cmdexe.Trim(true);
768  if (cmdexe.IsEmpty())
769  {
770  Log(_("ERROR: You need to specify a debugger program in the debuggers's settings."), Logger::error);
771 
772  if (platform::windows)
773  {
774  Log(_("(For MinGW compilers, it's 'gdb.exe' (without the quotes))"), Logger::error);
775  Log(_("(For MSVC compilers, it's 'cdb.exe' (without the quotes))"), Logger::error);
776  }
777  else
778  {
779  Log(_("(For GCC compilers, it's 'gdb' (without the quotes))"), Logger::error);
780  }
781 
782  m_Canceled = true;
783  return -1;
784  }
785 
786  // start debugger driver based on target compiler, or default compiler if no target
787  if (!m_State.StartDriver(target))
788  {
789  cbMessageBox(_T("Could not decide which debugger to use!"), _T("Error"), wxICON_ERROR);
790  m_Canceled = true;
791  return -1;
792  }
793 
794  // Notify debugger plugins so they could start a GDB server process
797  plm->NotifyPlugins(evt);
798  int nRet = evt.GetInt();
799  if (nRet < 0)
800  {
801  cbMessageBox(_T("A plugin interrupted the debug process."));
802  Log(_("Aborted by plugin"));
803  m_Canceled = true;
804  return -1;
805  }
806  // Continue
807 
808  // create gdb launch command
809  wxString cmd;
810 
811  // prepare the driver
812  wxString cmdline;
813  if (m_PidToAttach == 0)
814  {
816  // add other open projects dirs as search dirs (only if option is enabled)
818  {
819  // add as include dirs all open project base dirs
820  ProjectsArray* projects = prjMan->GetProjects();
821  for (unsigned int i = 0; i < projects->GetCount(); ++i)
822  {
823  cbProject* it = projects->Item(i);
824  // skip if it's THE project (added last)
825  if (it == m_pProject)
826  continue;
827  AddSourceDir(it->GetBasePath());
829  }
830  }
831  // now add all per-project user-set search dirs
833  for (size_t i = 0; i < pdirs.GetCount(); ++i)
834  AddSourceDir(pdirs[i]);
835 
836  // lastly, add THE project as source dir
837  if (m_pProject)
838  {
841  }
842 
843  // set the file to debug (depends on the target type)
844  wxString debuggee, path;
845  if ( !GetDebuggee(debuggee, path, target) )
846  {
847  m_Canceled = true;
848  return -3;
849  }
850 
851  if (!path.empty())
852  {
853  ConvertToGDBDirectory(path);
854  if (path != _T(".")) // avoid silly message "changing to ."
855  {
856  Log(_("Changing directory to: ") + path);
858  }
859  }
860 
861  if (target && !target->GetExecutionParameters().IsEmpty())
863 
864  cmdline = m_State.GetDriver()->GetCommandLine(cmdexe, debuggee, GetActiveConfigEx().GetUserArguments());
865  }
866  else // m_PidToAttach != 0
867  cmdline = m_State.GetDriver()->GetCommandLine(cmdexe, m_PidToAttach, GetActiveConfigEx().GetUserArguments());
868 
870  RemoteDebugging rd = rdprj[0]; // project settings
871  RemoteDebuggingMap::iterator it = rdprj.find(target); // target settings
872  if (it != rdprj.end())
873  rd.MergeWith(it->second);
875  wxString oldLibPath; // keep old PATH/LD_LIBRARY_PATH contents
876  if (!rd.skipLDpath)
877  {
878  wxGetEnv(CB_LIBRARY_ENVVAR, &oldLibPath);
879 
880  // setup dynamic linker path
881  if (actualCompiler && target)
882  {
883  wxString newLibPath;
884  const wxString libPathSep = platform::windows ? _T(";") : _T(":");
885  newLibPath << _T(".") << libPathSep;
886 
887  CompilerCommandGenerator *generator = actualCompiler->GetCommandGenerator(m_pProject);
888  newLibPath << GetStringFromArray(generator->GetLinkerSearchDirs(target), libPathSep);
889  delete generator;
890 
891  if (newLibPath.Mid(newLibPath.Length() - 1, 1) != libPathSep)
892  newLibPath << libPathSep;
893  newLibPath << oldLibPath;
894  wxSetEnv(CB_LIBRARY_ENVVAR, newLibPath);
895  Log(wxString(_("Set variable: ")) + CB_LIBRARY_ENVVAR wxT("=") + newLibPath);
896  }
897  }
898 
899  #ifdef __WXMSW__
901  {
902  AllocConsole();
903  SetConsoleTitleA("Codeblocks debug console - DO NOT CLOSE!");
904  SetConsoleCtrlHandler(HandlerRoutine, TRUE);
905  m_bIsConsole = true;
906 
907  HWND windowHandle = GetConsoleWindow();
908  if (windowHandle)
909  ShowWindow(windowHandle, SW_HIDE);
910  }
911  #endif
912  // start the gdb process
914  if (wdir.empty())
915  wdir = m_pProject ? m_pProject->GetBasePath() : _T(".");
916  DebugLog(_T("Command-line: ") + cmdline);
917  DebugLog(_T("Working dir : ") + wdir);
918  int ret = LaunchProcess(cmdline, wdir);
919 
920  if (!rd.skipLDpath)
921  {
922  // restore dynamic linker path
923  wxSetEnv(CB_LIBRARY_ENVVAR, oldLibPath);
924  }
925 
926  if (ret != 0)
927  {
928  m_Canceled = true;
929  return ret;
930  }
931 
932  wxString out;
933  // start polling gdb's output
935 
936  // although I don't really like these do-nothing loops, we must wait a small amount of time
937  // for gdb to see if it really started: it may fail to load shared libs or whatever
938  // the reason this is added is because I had a case where gdb would error and bail out
939  // *while* the driver->Prepare() call was running below and hell broke loose...
940  int i = 50;
941  while (i)
942  {
943  wxMilliSleep(1);
944  Manager::Yield();
945  --i;
946  }
947  if (!m_State.HasDriver())
948  return -1;
949 
950  bool isConsole = (target && target->GetTargetType() == ttConsoleOnly);
951  m_State.GetDriver()->Prepare(isConsole, m_printElements);
953 
954  #ifndef __WXMSW__
955  // create xterm and issue tty "/dev/pts/#" to GDB where
956  // # is the tty for the newly created xterm
957  m_bIsConsole = target && target->GetUseConsoleRunner();
958  if (m_bIsConsole)
959  {
960  wxString consoleTty;
961  m_nConsolePid = RunNixConsole(consoleTty);
962  if (m_nConsolePid > 0)
963  {
965  wxString gdbTtyCmd;
966  gdbTtyCmd << wxT("tty ") << consoleTty;
967  m_State.GetDriver()->QueueCommand(new DebuggerCmd(m_State.GetDriver(), gdbTtyCmd, true));
968  DebugLog(wxString::Format( _("Queued:[%s]"), gdbTtyCmd.wx_str()) );
969  }
970  }//if
971  #endif//ndef __WXMSW__
972 
973  // Don't issue 'run' if attaching to a process (Bug #1391904)
974  if (m_PidToAttach == 0)
975  m_State.GetDriver()->Start(breakOnEntry);
976  else
978 
979  // switch to the user-defined layout for debugging
980  if (m_pProcess)
982 
983  return 0;
984 } // Debug
985 
987 {
988  if (!m_State.HasDriver() || dir.IsEmpty())
989  return;
990  wxString filename = dir;
991  Manager::Get()->GetMacrosManager()->ReplaceEnvVars(filename); // apply env vars
992  Log(_("Adding source dir: ") + filename);
993  ConvertToGDBDirectory(filename, _T(""), false);
994  m_State.GetDriver()->AddDirectory(filename);
995 }
996 
997 // static
999 {
1000  if (str.GetChar(0) == _T('\"') && str.GetChar(str.Length() - 1) == _T('\"'))
1001  str = str.Mid(1, str.Length() - 2);
1002 }
1003 
1004 // static
1006 {
1007  if (str.IsEmpty())
1008  return;
1009 
1010  str = UnixFilename(str);
1011  while (str.Replace(_T("\\"), _T("/")))
1012  ;
1013  while (str.Replace(_T("//"), _T("/")))
1014  ;
1015  if (str.Find(_T(' ')) != -1 && str.GetChar(0) != _T('"'))
1016  str = _T("\"") + str + _T("\"");
1017 }
1018 
1019 // static
1021 {
1022  wxFileName fname = str;
1023  str = fname.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
1025  str << fname.GetFullName();
1026 }
1027 
1028 void DebuggerGDB::ConvertDirectory(wxString& str, wxString base, bool relative)
1029 {
1030  ConvertToGDBDirectory(str, base, relative);
1031 }
1032 
1033 // static
1034 //if relative == false, try to leave as an absolute path
1036 {
1037  if (str.IsEmpty())
1038  return;
1039 
1040  ConvertToGDBFriendly(str);
1041  ConvertToGDBFriendly(base);
1042  StripQuotes(str);
1043  StripQuotes(base);
1044 
1045  if (platform::windows)
1046  {
1047  int ColonLocation = str.Find(_T(':'));
1048  bool convert_path_83 = false;
1049  if (ColonLocation != wxNOT_FOUND)
1050  convert_path_83 = true;
1051  else if (!base.IsEmpty() && str.GetChar(0) != _T('/'))
1052  {
1053  if (base.GetChar(base.Length()) == _T('/'))
1054  base = base.Mid(0, base.Length() - 2);
1055 
1056  while (!str.IsEmpty())
1057  {
1058  base += _T("/") + str.BeforeFirst(_T('/'));
1059  if (str.Find(_T('/')) != wxNOT_FOUND) str = str.AfterFirst(_T('/'));
1060  else str.Clear();
1061  }
1062  convert_path_83 = true;
1063  }
1064 
1065  // If can, get 8.3 name for path (Windows only)
1066  if (convert_path_83 && str.Contains(_T(' '))) // only if has spaces
1067  {
1068  wxFileName fn(str); // might contain a file name, too
1069  wxString path_83 = fn.GetShortPath();
1070  if (!path_83.IsEmpty())
1071  str = path_83; // construct filename again
1072  }
1073 
1074  if (ColonLocation == wxNOT_FOUND || base.IsEmpty())
1075  relative = false; // Can't do it
1076  }
1077  else
1078  {
1079  if ((str.GetChar(0) != _T('/') && str.GetChar(0) != _T('~')) || base.IsEmpty())
1080  relative = false;
1081  }
1082 
1083  if (relative)
1084  {
1085  if (platform::windows)
1086  {
1087  if (str.Find(_T(':')) != wxNOT_FOUND)
1088  str = str.Mid(str.Find(_T(':')) + 2, str.Length());
1089  if (base.Find(_T(':')) != wxNOT_FOUND)
1090  base = base.Mid(base.Find(_T(':')) + 2, base.Length());
1091  }
1092  else
1093  {
1094  if (str.GetChar(0) == _T('/')) str = str.Mid(1, str.Length());
1095  else if (str.GetChar(0) == _T('~')) str = str.Mid(2, str.Length());
1096 
1097  if (base.GetChar(0) == _T('/')) base = base.Mid(1, base.Length());
1098  else if (base.GetChar(0) == _T('~')) base = base.Mid(2, base.Length());
1099  }
1100 
1101  while (!base.IsEmpty() && !str.IsEmpty())
1102  {
1103  if (str.BeforeFirst(_T('/')) == base.BeforeFirst(_T('/')))
1104  {
1105  if (str.Find(_T('/')) == wxNOT_FOUND) str.Clear();
1106  else str = str.AfterFirst(_T('/'));
1107 
1108  if (base.Find(_T('/')) == wxNOT_FOUND) base.Clear();
1109  else base = base.AfterFirst(_T('/'));
1110  }
1111  else break;
1112  }
1113  while (!base.IsEmpty())
1114  {
1115  str = _T("../") + str;
1116  if (base.Find(_T('/')) == wxNOT_FOUND) base.Clear();
1117  else base = base.AfterFirst(_T('/'));
1118  }
1119  }
1120  ConvertToGDBFriendly(str);
1121 }
1122 
1123 void DebuggerGDB::SendCommand(const wxString& cmd, bool debugLog)
1124 {
1125  const wxString &cleandCmd = CleanStringValue(cmd);
1126  if (!debugLog)
1127  Log(_T("> ") + cleandCmd);
1128 
1129  if (debugLog)
1130  DoSendCommand(cleandCmd);
1131  else if (m_State.HasDriver())
1132  m_State.GetDriver()->QueueCommand(new DebuggerCmd(m_State.GetDriver(), cleandCmd, true));
1133 }
1134 
1136 {
1137  if (!m_pProcess || !IsStopped())
1138  return;
1139 
1140  if (HasDebugLog())
1141  DebugLog(wxT("> ") + cmd);
1142 
1143  m_pProcess->SendString(cmd);
1144 }
1145 
1147 {
1148  switch (window)
1149  {
1150  case Backtrace:
1152  break;
1153  case CPURegisters:
1155  break;
1156  case Disassembly:
1158  break;
1159  case ExamineMemory:
1161  break;
1162  case Threads:
1164  break;
1165  case Watches:
1166  if (IsWindowReallyShown(Manager::Get()->GetDebuggerManager()->GetWatchesDialog()->GetWindow()))
1167  DoWatches();
1168  break;
1169  default:
1170  break;
1171  }
1172 }
1173 
1175 {
1176  // just check for the process
1177  if (!m_pProcess)
1178  return;
1179 
1180  switch (cmd)
1181  {
1182  case CMD_CONTINUE:
1183  {
1185  if (m_State.HasDriver())
1186  {
1187  Log(_("Continuing..."));
1188  m_State.GetDriver()->Continue();
1190  }
1191  break;
1192  }
1193 
1194  case CMD_STEP:
1195  {
1197  if (m_State.HasDriver())
1198  {
1199  m_State.GetDriver()->Step();
1201  }
1202  break;
1203  }
1204 
1205  case CMD_STEP_INSTR:
1206  {
1208  if (!Manager::Get()->GetDebuggerManager()->UpdateDisassembly())
1209  {
1210  // first time users should have some help from us ;)
1212  }
1213  if (m_State.HasDriver())
1214  {
1218  }
1219  break;
1220  }
1221 
1222  case CMD_STEP_INTO_INSTR:
1223  {
1225  if (!Manager::Get()->GetDebuggerManager()->UpdateDisassembly())
1226  {
1227  // first time users should have some help from us ;)
1229  }
1230  if (m_State.HasDriver())
1231  {
1235  }
1236  break;
1237  }
1238 
1239  case CMD_STEPIN:
1240  {
1242  if (m_State.HasDriver())
1243  {
1244  m_State.GetDriver()->StepIn();
1246  }
1247  break;
1248  }
1249 
1250  case CMD_STEPOUT:
1251  {
1253  if (m_State.HasDriver())
1254  {
1255  m_State.GetDriver()->StepOut();
1257  }
1258  break;
1259  }
1260 
1261  case CMD_STOP:
1262  {
1264  if (m_State.HasDriver())
1265  {
1266  m_State.GetDriver()->Stop();
1268  MarkAsStopped();
1269  }
1270  break;
1271  }
1272 
1273  case CMD_BACKTRACE:
1274  {
1275  if (m_State.HasDriver())
1277  break;
1278  }
1279 
1280  case CMD_DISASSEMBLE:
1281  {
1282  if (m_State.HasDriver())
1284  break;
1285  }
1286 
1287  case CMD_REGISTERS:
1288  {
1289  if (m_State.HasDriver())
1291  break;
1292  }
1293 
1294  case CMD_MEMORYDUMP:
1295  {
1296  if (m_State.HasDriver())
1298  break;
1299  }
1300 
1301  case CMD_RUNNINGTHREADS:
1302  {
1303  if (m_State.HasDriver())
1305  break;
1306  }
1307 
1308  default: break;
1309  }
1310 }
1311 
1313 {
1314  return m_State.GetDriver()->GetStackFrames().size();
1315 }
1316 
1317 cb::shared_ptr<const cbStackFrame> DebuggerGDB::GetStackFrame(int index) const
1318 {
1319  return m_State.GetDriver()->GetStackFrames()[index];
1320 }
1321 
1323 {
1324  if (m_State.HasDriver())
1325  {
1326  m_State.GetDriver()->SetCurrentFrame(number, true);
1327  m_State.GetDriver()->SwitchToFrame(number);
1328 
1329  if (Manager::Get()->GetDebuggerManager()->UpdateBacktrace())
1331  }
1332 }
1333 
1335 {
1336  return m_State.HasDriver() ? m_State.GetDriver()->GetCurrentFrame() : 0;
1337 }
1338 
1340 {
1341  if (!m_State.HasDriver())
1342  return 0;
1343  else
1344  return m_State.GetDriver()->GetThreads().size();
1345 }
1346 
1347 cb::shared_ptr<const cbThread> DebuggerGDB::GetThread(int index) const
1348 {
1349  return m_State.GetDriver()->GetThreads()[index];
1350 }
1351 
1352 bool DebuggerGDB::SwitchToThread(int thread_number)
1353 {
1354  if (!m_State.HasDriver())
1355  return false;
1356  DebuggerDriver *driver = m_State.GetDriver();
1357  DebuggerDriver::ThreadsContainer const &threads = driver->GetThreads();
1358 
1359  for (DebuggerDriver::ThreadsContainer::const_iterator it = threads.begin(); it != threads.end(); ++it)
1360  {
1361  if ((*it)->GetNumber() == thread_number)
1362  {
1363  if (!(*it)->IsActive())
1364  driver->SwitchThread(thread_number);
1365  return true;
1366  }
1367  }
1368  return false;
1369 }
1370 
1371 cb::shared_ptr<cbBreakpoint> DebuggerGDB::AddBreakpoint(const wxString& filename, int line)
1372 {
1373  bool debuggerIsRunning = !IsStopped();
1374  if (debuggerIsRunning)
1375  DoBreak(true);
1376 
1377  cb::shared_ptr<DebuggerBreakpoint> bp = m_State.AddBreakpoint(filename, line, false);
1378 
1379  if (debuggerIsRunning)
1380  Continue();
1381 
1382  return bp;
1383 }
1384 
1385 cb::shared_ptr<cbBreakpoint> DebuggerGDB::AddDataBreakpoint(const wxString& dataExpression)
1386 {
1387  DataBreakpointDlg dlg(Manager::Get()->GetAppWindow(), dataExpression, true, 1);
1388  PlaceWindow(&dlg);
1389  if (dlg.ShowModal() == wxID_OK)
1390  {
1391  const wxString& newDataExpression = dlg.GetDataExpression();
1392  int sel = dlg.GetSelection();
1393  cb::shared_ptr<DebuggerBreakpoint> bp = m_State.AddBreakpoint(newDataExpression, sel != 1, sel != 0);
1394  return bp;
1395  }
1396  else
1397  return cb::shared_ptr<cbBreakpoint>();
1398 }
1399 
1401 {
1402  return m_State.GetBreakpoints().size();
1403 }
1404 
1405 cb::shared_ptr<cbBreakpoint> DebuggerGDB::GetBreakpoint(int index)
1406 {
1407  BreakpointsList::const_iterator it = m_State.GetBreakpoints().begin();
1408  std::advance(it, index);
1409  cbAssert(it != m_State.GetBreakpoints().end());
1410  return *it;
1411 }
1412 
1413 cb::shared_ptr<const cbBreakpoint> DebuggerGDB::GetBreakpoint(int index) const
1414 {
1415  BreakpointsList::const_iterator it = m_State.GetBreakpoints().begin();
1416  std::advance(it, index);
1417  cbAssert(it != m_State.GetBreakpoints().end());
1418  return *it;
1419 }
1420 
1421 void DebuggerGDB::UpdateBreakpoint(cb::shared_ptr<cbBreakpoint> breakpoint)
1422 {
1423  const BreakpointsList &breakpoints = m_State.GetBreakpoints();
1424  BreakpointsList::const_iterator it = std::find(breakpoints.begin(), breakpoints.end(), breakpoint);
1425  if (it == breakpoints.end())
1426  return;
1427  cb::shared_ptr<DebuggerBreakpoint> bp = cb::static_pointer_cast<DebuggerBreakpoint>(breakpoint);
1428  bool reset = false;
1429  switch (bp->type)
1430  {
1432  {
1433  EditBreakpointDlg dlg(*bp, Manager::Get()->GetAppWindow());
1434  PlaceWindow(&dlg);
1435  if (dlg.ShowModal() == wxID_OK)
1436  {
1437  *bp = dlg.GetBreakpoint();
1438  reset = true;
1439  }
1440  break;
1441  }
1443  {
1444  int old_sel = 0;
1445  if (bp->breakOnRead && bp->breakOnWrite)
1446  old_sel = 2;
1447  else if (!bp->breakOnRead && bp->breakOnWrite)
1448  old_sel = 1;
1449  DataBreakpointDlg dlg(Manager::Get()->GetAppWindow(), bp->breakAddress, bp->enabled, old_sel);
1450  PlaceWindow(&dlg);
1451  if (dlg.ShowModal() == wxID_OK)
1452  {
1453  bp->enabled = dlg.IsEnabled();
1454  bp->breakOnRead = dlg.GetSelection() != 1;
1455  bp->breakOnWrite = dlg.GetSelection() != 0;
1456  bp->breakAddress = dlg.GetDataExpression();
1457  reset = true;
1458  }
1459  break;
1460  }
1462  default:
1463  return;
1464  }
1465 
1466  if (reset)
1467  {
1468  bool debuggerIsRunning = !IsStopped();
1469  if (debuggerIsRunning)
1470  DoBreak(true);
1471 
1473 
1474  if (debuggerIsRunning)
1475  Continue();
1476  }
1477 }
1478 
1479 void DebuggerGDB::DeleteBreakpoint(cb::shared_ptr<cbBreakpoint> breakpoint)
1480 {
1481  bool debuggerIsRunning = !IsStopped();
1482  if (debuggerIsRunning)
1483  DoBreak(true);
1484 
1485  m_State.RemoveBreakpoint(cb::static_pointer_cast<DebuggerBreakpoint>(breakpoint));
1486 
1487  if (debuggerIsRunning)
1488  Continue();
1489 }
1490 
1492 {
1493  bool debuggerIsRunning = !IsStopped();
1494  if (debuggerIsRunning)
1495  DoBreak(true);
1497 
1498  if (debuggerIsRunning)
1499  Continue();
1500 }
1501 
1502 void DebuggerGDB::ShiftBreakpoint(int index, int lines_to_shift)
1503 {
1504  BreakpointsList breakpoints = m_State.GetBreakpoints();
1505  BreakpointsList::iterator it = breakpoints.begin();
1506  std::advance(it, index);
1507  if (it != breakpoints.end())
1508  m_State.ShiftBreakpoint(*it, lines_to_shift);
1509 }
1510 
1511 void DebuggerGDB::EnableBreakpoint(cb::shared_ptr<cbBreakpoint> breakpoint, bool enable)
1512 {
1513  bool debuggerIsRunning = !IsStopped();
1514  DebugLog(wxString::Format(wxT("DebuggerGDB::EnableBreakpoint(running=%d);"), debuggerIsRunning?1:0));
1515  if (debuggerIsRunning)
1516  DoBreak(true);
1517 
1518  cb::shared_ptr<DebuggerBreakpoint> bp = cb::static_pointer_cast<DebuggerBreakpoint>(breakpoint);
1519  bp->enabled = enable;
1521 
1522  if (debuggerIsRunning)
1523  Continue();
1524 }
1525 
1527 {
1529 }
1530 
1532 {
1534 }
1535 
1537 {
1539 }
1540 
1542 {
1544 }
1545 
1547 {
1549 }
1550 
1552 {
1554 }
1555 
1556 bool DebuggerGDB::Validate(const wxString& line, const char cb)
1557 {
1558  bool bResult = false;
1559 
1560  int bep = line.Find(cb)+1;
1561  int scs = line.Find(_T('\''))+1;
1562  int sce = line.Find(_T('\''),true)+1;
1563  int dcs = line.Find(_T('"'))+1;
1564  int dce = line.Find(_T('"'),true)+1;
1565  //No single and double quote
1566  if (!scs && !sce && !dcs && !dce) bResult = true;
1567  //No single/double quote in pair
1568  if (!(sce-scs) && !(dce-dcs)) bResult = true;
1569  //Outside of single quote
1570  if ((sce-scs) && ((bep < scs)||(bep >sce))) bResult = true;
1571  //Outside of double quote
1572  if ((dce-dcs) && ((bep < dcs)||(bep >dce))) bResult = true;
1573 
1574  return bResult;
1575 }
1576 
1578 {
1580 }
1581 
1582 bool DebuggerGDB::RunToCursor(const wxString& filename, int line, const wxString& line_text)
1583 {
1584  if (m_pProcess)
1585  {
1586  m_State.AddBreakpoint(filename, line, true, line_text);
1588  Continue();
1589  return true;
1590  }
1591  else
1592  {
1594  {
1595  m_State.AddBreakpoint(filename, line, true, line_text);
1597  }
1598  return Debug(false);
1599  }
1600 }
1601 
1602 void DebuggerGDB::SetNextStatement(const wxString& filename, int line)
1603 {
1604  if (m_State.HasDriver() && IsStopped())
1605  {
1606  m_State.GetDriver()->SetNextStatement(filename, line);
1607  }
1608 }
1609 
1611 {
1612  DoBreak(false);
1613 }
1614 
1615 void DebuggerGDB::DoBreak(bool temporary)
1616 {
1617  m_TemporaryBreak = temporary;
1618 
1619  // m_Process is PipedProcess I/O; m_Pid is debugger pid
1620  if (m_pProcess && m_Pid && !IsStopped())
1621  {
1622  long childPid = m_State.GetDriver()->GetChildPID();
1623  long pid = childPid;
1624  #ifndef __WXMSW__
1625  if (pid > 0 && !wxProcess::Exists(pid))
1626  {
1627  DebugLog(wxString::Format(_("Child process (pid:%ld) doesn't exists"), pid), Logger::warning);
1628  pid = 0;
1629  }
1630  if (pid <= 0)
1631  pid = m_Pid; // try poking gdb directly
1632  // non-windows gdb can interrupt the running process. yay!
1633  if (pid <= 0) // look out for the "fake" PIDs (killall)
1634  cbMessageBox(_("Unable to stop the debug process!"), _("Error"), wxOK | wxICON_WARNING);
1635  else
1636  {
1637  if (!wxProcess::Exists(pid))
1638  DebugLog(wxString::Format(_("GDB process (pid:%ld) doesn't exists"), pid), Logger::error);
1639 
1640  Log(F(_("Trying to interrupt process with pid: %ld; child pid: %ld gdb pid: %ld"),
1641  pid, childPid, static_cast<long>(m_Pid)));
1642  wxKillError error;
1643  if (wxKill(pid, wxSIGINT, &error) != 0)
1644  DebugLog(wxString::Format(_("Can't kill process (%ld) %d"), pid, (int)(error)));
1645  }
1646  #else
1647  // windows gdb can interrupt the running process too. yay!
1648  if ( (pid <=0)
1649  && (CreateToolhelp32SnapshotFunc!=NULL)
1650  && (Process32FirstFunc!=NULL)
1651  && (Process32NextFunc!=NULL) )
1652  {
1653  HANDLE snap = CreateToolhelp32SnapshotFunc(TH32CS_SNAPALL,0);
1654  if (snap!=INVALID_HANDLE_VALUE)
1655  {
1656  PROCESSENTRY32 lppe;
1657  lppe.dwSize = sizeof(PROCESSENTRY32);
1658  BOOL ok = Process32FirstFunc(snap, &lppe);
1659  while ( ok == TRUE)
1660  {
1661  if (static_cast<int>(lppe.th32ParentProcessID) == m_Pid) // Have my Child...
1662  {
1663  pid = lppe.th32ProcessID;
1664  DebugLog(F(_("Found child: %ld"), pid));
1665  }
1666  lppe.dwSize = sizeof(PROCESSENTRY32);
1667  ok = Process32NextFunc(snap, &lppe);
1668  }
1669  CloseHandle(snap);
1670  }
1671  else
1672  Log(_("No handle created. Trying to pause directly with cbd.exe..."), Logger::warning);
1673  }
1674 
1676  {
1677  if (!DebugBreakProcessFunc)
1678  Log(_("DebugBreakProcess is not supported, you need Windows XP or newer..."), Logger::error);
1679  else if (pid > 0)
1680  {
1681  Log(F(_("Trying to interrupt process with pid: %ld; child pid: %ld gdb pid: %ld"),
1682  pid, childPid, static_cast<long>(m_Pid)));
1683  HANDLE proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
1684  if (proc)
1685  {
1686  DebugBreakProcessFunc(proc); // yay!
1687  CloseHandle(proc);
1688  }
1689  else
1690  Log(wxT("Interrupting debugger failed :("), Logger::error);
1691  }
1692  }
1693  else
1694  {
1695  if (m_Pid > 0)
1696  {
1697  Log(_("Trying to interrupt the process by sending CTRL-C event to the console!"));
1698  if (GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0) == 0)
1699  {
1700  Log(wxT("Interrupting debugger failed :("), Logger::error);
1701  return;
1702  }
1703  }
1704  }
1705  #endif
1706  // Notify debugger plugins for end of debug session
1709  plm->NotifyPlugins(evt);
1710  }
1711 }
1712 
1714 {
1715  // m_Process is PipedProcess I/O; m_Pid is debugger pid
1716  if (m_pProcess && m_Pid)
1717  {
1718  if (!IsStopped())
1719  {
1720  // TODO (obfuscated#): Check if this can be implemented on Windows
1721 #ifdef __WXGTK__
1722  int childPID=m_State.GetDriver()->GetChildPID();
1723  if (childPID == 0)
1724  {
1725  DebugLog(_("Child pid is 0, so we will terminate GDB directly"));
1727  return;
1728  }
1729 #endif
1730  Break();
1731  }
1733  }
1734 }
1735 
1737 {
1738  if (!output.IsEmpty() && m_State.HasDriver())
1739  {
1740  m_State.GetDriver()->ParseOutput(output);
1741  }
1742 }
1743 
1744 void DebuggerGDB::GetCurrentPosition(wxString &filename, int &line)
1745 {
1746  if (m_State.HasDriver())
1747  {
1748  const Cursor& cursor = m_State.GetDriver()->GetCursor();
1749  filename = cursor.file;
1750  line = cursor.line;
1751  }
1752  else
1753  {
1754  filename = wxEmptyString;
1755  line = -1;
1756  }
1757 }
1758 
1759 // TODO: should reimplement
1761 {
1762  wxString file = wxFileSelector(_("Choose file to read symbols from"),
1763  _T(""),
1764  _T(""),
1765  _T(""),
1766  _("Executables and libraries|*.exe;*.dll"),
1767  wxFD_OPEN | wxFD_FILE_MUST_EXIST | compatibility::wxHideReadonly);
1768  if (file.IsEmpty())
1769  return;
1770 // Manager::Get()->GetLogManager()->Log(m_PageIndex, _("Adding symbol file: %s"), file.wx_str());
1771  ConvertToGDBDirectory(file);
1772 // QueueCommand(new DbgCmd_AddSymbolFile(this, file));
1773 }
1774 
1776 {
1777  if (!GetActiveConfigEx().IsGDB())
1778  return;
1779  menu.Append(idMenuInfoFrame, _("Current stack frame"), _("Displays info about the current (selected) stack frame"));
1780  menu.Append(idMenuInfoDLL, _("Loaded libraries"), _("List dynamically loaded libraries (DLL/SO)"));
1781  menu.Append(idMenuInfoFiles, _("Targets and files"), _("Displays info on the targets and files being debugged"));
1782  menu.Append(idMenuInfoFPU, _("FPU status"), _("Displays the status of the floating point unit"));
1783  menu.Append(idMenuInfoSignals, _("Signal handling"), _("Displays how the debugger handles various signals"));
1784  menu.AppendSeparator();
1785 
1786  wxMenu *menuPrint = new wxMenu;
1787  menuPrint->AppendRadioItem(idMenuInfoPrintElementsUnlimited, _("Unlimited"),
1788  _("The full arrays are printed (could lead to lock-ups if uninitialised data is printed)"));
1789  menuPrint->AppendRadioItem(idMenuInfoPrintElements20, _("20"));
1790  menuPrint->AppendRadioItem(idMenuInfoPrintElements50, _("50"));
1791  menuPrint->AppendRadioItem(idMenuInfoPrintElements100, _("100"));
1792  menuPrint->AppendRadioItem(idMenuInfoPrintElements200, _("200 (default)"));
1793  menu.AppendSubMenu(menuPrint, _("Print Elements"), _("Set limit on string chars or array elements to print"));
1794  menu.AppendCheckItem(idMenuInfoCatchThrow, _("Catch throw"),
1795  _("If enabled the debugger will break when an exception is thronw"));
1796 }
1797 
1799 {
1800  bool checked = (event.GetId() == idMenuInfoPrintElementsUnlimited && m_printElements==0) ||
1801  (event.GetId() == idMenuInfoPrintElements20 && m_printElements==20) ||
1802  (event.GetId() == idMenuInfoPrintElements50 && m_printElements==50) ||
1803  (event.GetId() == idMenuInfoPrintElements100 && m_printElements==100) ||
1804  (event.GetId() == idMenuInfoPrintElements200 && m_printElements==200);
1805  event.Check(checked);
1806  event.Enable(IsRunning() && IsStopped());
1807 }
1808 
1810 {
1811  if (event.GetId() == idMenuInfoPrintElementsUnlimited)
1812  m_printElements = 0;
1813  else if (event.GetId() == idMenuInfoPrintElements20)
1814  m_printElements = 20;
1815  else if (event.GetId() == idMenuInfoPrintElements50)
1816  m_printElements = 50;
1817  else if (event.GetId() == idMenuInfoPrintElements100)
1818  m_printElements = 100;
1819  else if (event.GetId() == idMenuInfoPrintElements200)
1820  m_printElements = 200;
1821  else
1822  return;
1823 
1824  wxString cmd = wxString::Format(wxT("set print elements %d"), m_printElements);
1827 }
1828 
1830 {
1832  event.Enable(config.IsGDB() && IsStopped());
1833  event.Check(config.GetFlag(DebuggerConfiguration::CatchExceptions));
1834 }
1835 
1837 {
1838  bool flag = event.IsChecked();
1841 }
1842 
1844 {
1845  if (m_State.HasDriver())
1847 }
1848 
1850 {
1851  if (m_State.HasDriver())
1852  {
1853  m_State.GetDriver()->InfoDLL();
1854  }
1855 }
1856 
1858 {
1859  if (m_State.HasDriver())
1861 }
1862 
1864 {
1865  if (m_State.HasDriver())
1866  m_State.GetDriver()->InfoFPU();
1867 }
1868 
1870 {
1871  if (m_State.HasDriver())
1873 }
1874 
1876 {
1877  wxString msg = event.GetString();
1878  if (!msg.IsEmpty())
1879  ParseOutput(msg);
1880 }
1881 
1883 {
1884  wxString msg = event.GetString();
1885  if (!msg.IsEmpty())
1886  ParseOutput(msg);
1887 }
1888 
1890 {
1891  m_PidToAttach = 0;
1892 
1894  m_LastExitCode = event.GetInt();
1895  //the process deletes itself
1896 // m_pProcess = 0L;
1897 
1899  m_State.StopDriver();
1902  {
1903  Log(wxString::Format(_("Debugger finished with status %d"), m_LastExitCode));
1904 
1905  if (m_NoDebugInfo)
1906  {
1907  cbMessageBox(_("This project/target has no debugging info."
1908  "Please change this in the project's build options, re-compile and retry..."),
1909  _("Error"), wxICON_STOP);
1910  }
1911  }
1912 
1913  // Notify debugger plugins for end of debug session
1916  plm->NotifyPlugins(evt);
1917 
1918  // switch to the user-defined layout when finished debugging
1921  KillConsole();
1922  MarkAsStopped();
1923 
1925 }
1926 
1928 {
1929 #ifdef __WXMSW__
1930  if (m_bIsConsole)
1931  {
1932  // remove the CTRL_C handler
1933  SetConsoleCtrlHandler(HandlerRoutine, FALSE);
1934  FreeConsole();
1935  m_bIsConsole = false;
1936  }
1937 #else
1938  // kill any linux console
1939  if ( m_bIsConsole && (m_nConsolePid > 0) )
1940  {
1942  m_nConsolePid = 0;
1943  m_bIsConsole = false;
1944  }
1945 #endif
1946 }
1947 
1949 {
1950 #ifndef __WXMSW__
1951  // Detect if the console is closed by the user and if it is stop the session.
1953  {
1954  AnnoyingDialog dialog(_("Terminal/Console closed"),
1955  _("Detected that the Terminal/Console has been closed. "
1956  "Do you want to stop the debugging session?"),
1957  wxART_QUESTION);
1958  if (dialog.ShowModal() == AnnoyingDialog::rtNO)
1960  else
1961  {
1962  Stop();
1963  m_nConsolePid = 0;
1964  }
1965  }
1966 #endif
1967 }
1968 
1970 {
1971  if (!m_pProcess || !IsStopped())
1972  return false;
1973 
1975  return false;
1976 
1978  return false;
1979  if (style != wxSCI_C_DEFAULT && style != wxSCI_C_OPERATOR && style != wxSCI_C_IDENTIFIER &&
1980  style != wxSCI_C_WORD2 && style != wxSCI_C_GLOBALCLASS &&
1981  style != wxSCI_F_IDENTIFIER)
1982  {
1983  return false;
1984  }
1985  return true;
1986 }
1987 
1988 void DebuggerGDB::OnValueTooltip(const wxString &token, const wxRect &evalRect)
1989 {
1990  m_State.GetDriver()->EvaluateSymbol(token, evalRect);
1991 }
1992 
1994 {
1995  // remove all search dirs stored for this project so we don't have conflicts
1996  // if a newly opened project happens to use the same memory address
1997  GetSearchDirs(project).clear();
1998 
1999  // the same for remote debugging
2000  GetRemoteDebuggingMap(project).clear();
2001 
2002  // remove all breakpoints belonging to the closed project
2003  DeleteAllProjectBreakpoints(project);
2004  // FIXME (#obfuscated): Optimize this when multiple projects are closed
2005  // (during workspace close operation for exmaple).
2007  dlg->Reload();
2008 }
2009 
2011 {
2012  if (m_pProcess && ((PipedProcess*)m_pProcess)->HasInput())
2013  event.RequestMore();
2014  else
2015  event.Skip();
2016 }
2017 
2018 void DebuggerGDB::OnTimer(cb_unused wxTimerEvent& event)
2019 {
2020  // send any buffered (previous) output
2022 
2024 
2025  wxWakeUpIdle();
2026 }
2027 
2029 {
2030  SyncEditor(event.GetString(), event.GetInt(), false);
2031 }
2032 
2034 {
2035  m_TemporaryBreak = false;
2036 }
2037 
2039 {
2040  if (m_TemporaryBreak)
2041  return;
2042 
2043  if (m_State.HasDriver())
2044  {
2045  const Cursor& cursor = m_State.GetDriver()->GetCursor();
2046  // checking if driver is stopped is redundant because it would only
2047  // send us this event if it was stopped anyway
2048  if (/*m_State.GetDriver()->IsStopped() &&*/ cursor.changed)
2049  {
2051 
2053 
2054  // if the cursor line is invalid and the auto switch is on,
2055  // we don't sync the editor, because there is no line to sync to
2056  // and also we are going to execute a backtrace command hoping to find a valid frame.
2057  if (!autoSwitch || cursor.line != -1)
2058  SyncEditor(cursor.file, cursor.line);
2059 
2060  BringCBToFront();
2061  if (cursor.line != -1)
2062  Log(wxString::Format(_("At %s:%ld"), cursor.file.wx_str(), cursor.line));
2063  else
2064  Log(wxString::Format(_("In %s (%s)"), cursor.function.wx_str(), cursor.file.wx_str()));
2065 
2066  // update watches
2067  DebuggerManager *dbg_manager = Manager::Get()->GetDebuggerManager();
2068 
2069  if (IsWindowReallyShown(dbg_manager->GetWatchesDialog()->GetWindow()))
2070  DoWatches();
2071 
2072  // update CPU registers
2073  if (dbg_manager->UpdateCPURegisters())
2075 
2076  // update callstack
2077  if (dbg_manager->UpdateBacktrace())
2079  else
2080  {
2081  if (cursor.line == -1 && autoSwitch)
2083  }
2084 
2085  // update disassembly
2086  if (dbg_manager->UpdateDisassembly())
2087  {
2088  uint64_t addr = cbDebuggerStringToAddress(cursor.address);
2089  //if zero addr, don't attempt disassembly
2090  if (addr && !dbg_manager->GetDisassemblyDialog()->SetActiveAddress(addr))
2092  }
2093 
2094  // update memory examiner
2095  if (dbg_manager->UpdateExamineMemory())
2097 
2098  // update running threads
2099  if (dbg_manager->UpdateThreads())
2101  }
2102  }
2103 }
2104 
2105 cb::shared_ptr<cbWatch> DebuggerGDB::AddWatch(const wxString& symbol)
2106 {
2107  cb::shared_ptr<GDBWatch> watch(new GDBWatch(CleanStringValue(symbol)));
2108  m_watches.push_back(watch);
2109 
2110  if (m_pProcess)
2112 
2113  return watch;
2114 }
2115 
2116 void DebuggerGDB::AddWatchNoUpdate(const cb::shared_ptr<GDBWatch> &watch)
2117 {
2118  m_watches.push_back(watch);
2119 }
2120 
2121 void DebuggerGDB::DeleteWatch(cb::shared_ptr<cbWatch> watch)
2122 {
2123  WatchesContainer::iterator it = std::find(m_watches.begin(), m_watches.end(), watch);
2124  if (it != m_watches.end())
2125  m_watches.erase(it);
2126 }
2127 
2128 bool DebuggerGDB::HasWatch(cb::shared_ptr<cbWatch> watch)
2129 {
2130  WatchesContainer::iterator it = std::find(m_watches.begin(), m_watches.end(), watch);
2131  if (it != m_watches.end())
2132  return true;
2133  else
2134  return watch == m_localsWatch || watch == m_funcArgsWatch;
2135 }
2136 
2137 void DebuggerGDB::ShowWatchProperties(cb::shared_ptr<cbWatch> watch)
2138 {
2139  // not supported for child nodes!
2140  if (watch->GetParent())
2141  return;
2142 
2143  cb::shared_ptr<GDBWatch> real_watch = cb::static_pointer_cast<GDBWatch>(watch);
2144  EditWatchDlg dlg(real_watch, nullptr);
2145  if (dlg.ShowModal() == wxID_OK)
2146  DoWatches();
2147 }
2148 
2149 bool DebuggerGDB::SetWatchValue(cb::shared_ptr<cbWatch> watch, const wxString &value)
2150 {
2151  if (!HasWatch(cbGetRootWatch(watch)))
2152  return false;
2153 
2154  if (!m_State.HasDriver())
2155  return false;
2156 
2157  wxString full_symbol;
2158  cb::shared_ptr<cbWatch> temp_watch = watch;
2159  if (g_DebugLanguage == dl_Cpp)
2160  {
2161  while (temp_watch)
2162  {
2163  wxString symbol;
2164  temp_watch->GetSymbol(symbol);
2165  temp_watch = temp_watch->GetParent();
2166 
2167  if (symbol.find(wxT('*')) != wxString::npos || symbol.find(wxT('&')) != wxString::npos)
2168  symbol = wxT('(') + symbol + wxT(')');
2169 
2170  if (full_symbol.empty())
2171  full_symbol = symbol;
2172  else
2173  full_symbol = symbol + wxT('.') + full_symbol;
2174  }
2175  }
2176  else // Fortran language
2177  {
2178  while (temp_watch)
2179  {
2180  wxString symbol;
2181  temp_watch->GetSymbol(symbol);
2182  temp_watch = temp_watch->GetParent();
2183 
2184  if (full_symbol.empty())
2185  full_symbol = symbol;
2186  else
2187  {
2188  if (full_symbol.at(0) == '(' && symbol.at(0) == '(')
2189  {
2190  size_t sec = full_symbol.find(')');
2191  if (sec != wxString::npos && symbol.at(symbol.size()-1) == ')')
2192  {
2193  full_symbol = full_symbol.substr(0,sec) + wxT(',') + symbol.substr(1,symbol.size()-2) +
2194  full_symbol.substr(sec);
2195  }
2196  }
2197  else if (full_symbol.at(0) == '(')
2198  full_symbol = symbol + full_symbol;
2199  else
2200  full_symbol = symbol + wxT('%') + full_symbol;
2201  }
2202  }
2203  }
2204 
2205  DebuggerDriver* driver = m_State.GetDriver();
2206  driver->SetVarValue(full_symbol, value);
2207  DoWatches();
2208  return true;
2209 }
2210 
2211 void DebuggerGDB::ExpandWatch(cb_unused cb::shared_ptr<cbWatch> watch) // TODO: shouldn't this do something?
2212 {
2213 }
2214 
2215 void DebuggerGDB::CollapseWatch(cb_unused cb::shared_ptr<cbWatch> watch)
2216 {
2217 }
2218 
2219 void DebuggerGDB::UpdateWatch(cb::shared_ptr<cbWatch> watch)
2220 {
2221  if (!HasWatch(watch))
2222  return;
2223 
2224  if (!m_State.HasDriver())
2225  return;
2226  cb::shared_ptr<GDBWatch> real_watch = cb::static_pointer_cast<GDBWatch>(watch);
2227  if (real_watch == m_localsWatch)
2228  m_State.GetDriver()->UpdateWatchLocalsArgs(real_watch, true);
2229  else if (real_watch == m_funcArgsWatch)
2230  m_State.GetDriver()->UpdateWatchLocalsArgs(real_watch, false);
2231  else
2232  m_State.GetDriver()->UpdateWatch(real_watch);
2233 }
2234 
2236 {
2237  if (m_localsWatch)
2238  m_localsWatch->MarkAsChangedRecursive(false);
2239  if (m_funcArgsWatch)
2240  m_funcArgsWatch->MarkAsChangedRecursive(false);
2241 
2242  for (WatchesContainer::iterator it = m_watches.begin(); it != m_watches.end(); ++it)
2243  (*it)->MarkAsChangedRecursive(false);
2244 }
2245 
2246 void DebuggerGDB::OnWatchesContextMenu(wxMenu &menu, const cbWatch &watch, wxObject *property, int &disabledMenus)
2247 {
2248  wxString type, symbol;
2249  watch.GetType(type);
2250  watch.GetSymbol(symbol);
2251 
2252  if (IsPointerType(type))
2253  {
2254  menu.InsertSeparator(0);
2255  menu.Insert(0, idMenuWatchDereference, _("Dereference ") + symbol);
2256  m_watchToDereferenceSymbol = symbol;
2257  m_watchToDereferenceProperty = property;
2258  }
2259 
2260  if (watch.GetParent())
2261  {
2262  disabledMenus = WatchesDisabledMenuItems::Rename;
2263  disabledMenus |= WatchesDisabledMenuItems::Properties;
2264  disabledMenus |= WatchesDisabledMenuItems::Delete;
2265  disabledMenus |= WatchesDisabledMenuItems::AddDataBreak;
2266  disabledMenus |= WatchesDisabledMenuItems::ExamineMemory;
2267  }
2268 }
2269 
2271 {
2273  if (!watches)
2274  return;
2275 
2279 }
2280 
2282 {
2283  if (!pid.IsEmpty())
2284  {
2285  pid.ToLong((long*)&m_PidToAttach);
2286  Debug(false);
2287  }
2288 }
2289 
2291 {
2292  m_State.GetDriver()->Detach();
2293  m_PidToAttach = 0;
2294  m_State.GetDriver()->Stop();
2295 }
2296 
2298 {
2299  return m_PidToAttach != 0;
2300 }
2301 
2302 bool DebuggerGDB::CompilerFinished(bool compilerFailed, StartType startType)
2303 {
2304  if (compilerFailed || startType == StartTypeUnknown)
2305  return false;
2306  if (DoDebug(startType == StartTypeStepInto) != 0)
2307  return false;
2308  return true;
2309 }
2310 
2312 {
2313  // verify that the project that sent it, is the one we 're debugging
2314  // and that a project is loaded
2315  if (m_pProject && event.GetProject() == m_pProject)
2317 }
2318 
2320 {
2321  if (m_State.HasDriver())
2323 }
bool m_LastExitCode
Definition: debuggergdb.h:183
void OnWatchesContextMenu(wxMenu &menu, const cbWatch &watch, wxObject *property, int &disabledMenus)
int wxKill(long pid, wxSignal sig=wxSIGTERM, wxKillError *rc=NULL, int flags=wxKILL_NOCHILDREN)
wxString F(const wxChar *msg,...)
sprintf-like function
Definition: logmanager.h:20
C++ or C language.
void ConvertDirectory(wxString &str, wxString base, bool relative)
void AttachToProcess(const wxString &pid)
BOOL WINAPI HandlerRoutine(cb_unused DWORD dwCtrlType)
Definition: debuggergdb.cpp:79
wxArrayString & GetSearchDirs(cbProject *prj)
bool SetWatchValue(cb::shared_ptr< cbWatch > watch, const wxString &value)
virtual void StepIn()=0
DebuggerLanguage g_DebugLanguage
bool wxGetEnv(const wxString &var, wxString *value)
int GetStackFrameCount() const
SearchDirsMap m_SearchDirs
Definition: debuggergdb.h:198
int wxNewId()
PluginManager * GetPluginManager() const
Definition: manager.cpp:444
wxString wxFileSelector(const wxString &message, const wxString &default_path=wxEmptyString, const wxString &default_filename=wxEmptyString, const wxString &default_extension=wxEmptyString, const wxString &wildcard=wxFileSelectorDefaultWildcardStr, int flags=0, wxWindow *parent=NULL, int x=wxDefaultCoord, int y=wxDefaultCoord)
cb::shared_ptr< const cbStackFrame > GetStackFrame(int index) const
void NotifyCursorChanged()
Called by implementations to notify cursor changes.
virtual void UpdateWatchLocalsArgs(cb::shared_ptr< GDBWatch > const &watch, bool locals)=0
virtual bool GetUseConsoleRunner() const
Valid only for targets generating a console executable.
void SetFlag(Flags flag, bool value)
static bool GetFlag(Flags flag)
#define wxICON_WARNING
cb::shared_ptr< cbBreakpoint > AddBreakpoint(const wxString &filename, int line)
Request to add a breakpoint.
static bool LoadResource(const wxString &file)
Definition: manager.cpp:499
#define wxSCI_F_IDENTIFIER
Definition: wxscintilla.h:1270
Generate command-lines needed to produce a build.
ConfigManager * GetConfigManager(const wxString &name_space) const
Definition: manager.cpp:474
virtual void ParseOutput(const wxString &output)=0
Parse debugger&#39;s output.
bool Validate(const wxString &line, const char cb)
void DeleteBreakpoint(cb::shared_ptr< cbBreakpoint > breakpoint)
virtual void UpdateWatches(cb::shared_ptr< GDBWatch > localsWatch, cb::shared_ptr< GDBWatch > funcArgsWatch, WatchesContainer &watches)=0
Update watches.
virtual void AddDirectory(const wxString &dir)
Add a directory in search list.
wxObject * m_watchToDereferenceProperty
Definition: debuggergdb.h:217
Base class for debugger plugins.
Definition: cbplugin.h:397
int AddBreakpoint(cb::shared_ptr< DebuggerBreakpoint > bp)
void DoBreak(bool temporary)
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
wxInputStream * GetInputStream() const
#define wxICON_STOP
wxString substr(size_t nStart=0, size_t nLen=npos) const
void DeleteAllProjectBreakpoints(cbProject *project)
wxMenuItem * InsertSeparator(size_t pos)
void OnProjectLoadingHook(cbProject *project, TiXmlElement *elem, bool loading)
#define wxSCI_C_IDENTIFIER
Definition: wxscintilla.h:640
virtual const wxString & GetExecutionParameters() const
Read the target&#39;s execution parameters.
cbDebuggerConfiguration & GetActiveConfig()
Definition: cbplugin.cpp:266
virtual void Continue()=0
void OnTimer(wxTimerEvent &event)
void DeleteAllBreakpoints()
virtual void GetType(wxString &type) const =0
void DoWatches()
static bool IsAppShuttingDown()
Definition: manager.cpp:333
void OnInfoDLL(wxCommandEvent &event)
void ShiftBreakpoint(cb::shared_ptr< DebuggerBreakpoint > bp, int nroflines)
Debugger breakpoint interface.
wxTimer m_TimerPollDebugger
Definition: debuggergdb.h:187
wxString additionalCmds
commands after remote connection established
void MarkAllWatchesAsUnchanged()
bool IsStopped() const
Is the plugin stopped on breakpoint?
void SwitchToPreviousLayout()
Definition: cbplugin.cpp:600
void MarkAsStopped()
Definition: cbplugin.cpp:908
#define wxICON_ERROR
cb::shared_ptr< cbWatch > AddWatch(const wxString &symbol)
static Compiler * GetDefaultCompiler()
wxString GetDebuggerExecutable(bool expandMacro=true)
wxString GetShortPath() const
bool HasDebugLog() const
Definition: cbplugin.cpp:551
void Stop()
Stop the debugging process (exit debugging).
void CollapseWatch(cb::shared_ptr< cbWatch > watch)
const DebuggerBreakpoint & GetBreakpoint() const
cbProject * m_pProject
Definition: debuggergdb.h:193
wxString m_watchToDereferenceSymbol
Definition: debuggergdb.h:216
wxString additionalShellCmdsAfter
shell commands after remote connection established
void RequestUpdate(DebugWindows window)
void DoSendCommand(const wxString &cmd)
virtual void Reload()=0
void SwitchToFrame(int number)
EVTIMPORT const wxEventType cbEVT_BUILDTARGET_SELECTED
Definition: sdk_events.cpp:119
static void ConvertToGDBFile(wxString &str)
wxKillError
int Index(const wxString &sz, bool bCase=true, bool bFromEnd=false) const
void BringCBToFront()
Definition: cbplugin.cpp:913
void DetachFromProcess()
bool EnsureBuildUpToDate(StartType startType)
Definition: cbplugin.cpp:670
wxString m_ActiveBuildTarget
Definition: debuggergdb.h:194
static void StripQuotes(wxString &str)
size_t Length() const
virtual void StepIntoInstruction()=0
void Next()
Execute the next instruction and return control to the debugger.
#define wxSCI_C_OPERATOR
Definition: wxscintilla.h:639
bool StartDriver(ProjectBuildTarget *target)
wxMenuItem * Append(int id, const wxString &item=wxEmptyString, const wxString &helpString=wxEmptyString, wxItemKind kind=wxITEM_NORMAL)
static Compiler * GetCompiler(size_t index)
void wxWakeUpIdle()
wxString GetDebuggersWorkingDirectory() const
int RunNixConsole(wxString &consoleTty)
Definition: cbplugin.cpp:831
#define _T(string)
bool IsBusy() const
Is the plugin processing something?
void OnMenuWatchDereference(wxCommandEvent &event)
EVTIMPORT const wxEventType cbEVT_DEBUGGER_STARTED
Definition: sdk_events.cpp:157
cbProject * GetProject() const
Definition: sdk_events.h:41
bool IsProgramStopped() const
Is the program stopped?
bool Debug(bool breakOnEntry)
Start a new debugging process.
virtual void SetArguments(const wxString &args)
Set the execution arguments.
void ExpandWatch(cb::shared_ptr< cbWatch > watch)
virtual void Start(bool breakOnEntry)=0
Begin the debugging process by launching a program.
static void ConvertToGDBFriendly(wxString &str)
virtual void SwitchToFrame(size_t number)=0
virtual void UpdateWatch(cb::shared_ptr< GDBWatch > const &watch)=0
virtual void AddSpecialWatch(cb::shared_ptr< cbWatch > watch, bool readonly)=0
void OnCursorChanged(wxCommandEvent &event)
DLLIMPORT wxString GetStringFromArray(const wxArrayString &array, const wxString &separator=DEFAULT_ARRAY_SEP, bool SeparatorAtEnd=true)
Definition: globals.cpp:122
virtual void EvaluateSymbol(const wxString &symbol, const wxRect &tipRect)=0
Evaluate a symbol.
virtual void EnableCatchingThrow(bool enable)=0
void Log(const wxString &msg, Logger::level level=Logger::info)
Definition: cbplugin.cpp:530
SyncEditorResult SyncEditor(const wxString &filename, int line, bool setMarker=true)
Definition: cbplugin.cpp:301
#define wxICON_INFORMATION
virtual void InfoFiles()=0
const ThreadsContainer & GetThreads() const
returns the thread container with the current list of threads
DLLIMPORT HookFunctorBase * UnregisterHook(int id, bool deleteHook=true)
Unregister a previously registered project loading/saving hook.
void KillConsole()
void OnReleaseReal(bool appShutDown)
long int line
If -1, no line info.
Definition: debugger_defs.h:32
void NotifyMissingFile(const wxString &name)
Definition: globals.h:370
#define wxSCI_C_GLOBALCLASS
Definition: wxscintilla.h:648
wxString AfterFirst(wxUniChar ch) const
void RemoveBreakpoint(int idx, bool removeFromDriver=true)
#define wxT(string)
virtual bool Start(int milliseconds=-1, bool oneShot=wxTIMER_CONTINUOUS)
wxDynamicLibrary * LoadLibrary(const wxString &filename)
#define wxNOT_FOUND
bool IsPointerType(wxString type)
std::deque< cb::shared_ptr< DebuggerBreakpoint > > BreakpointsList
bool empty() const
size_t find(const wxString &str, size_t nStart=0) const
A generic Code::Blocks event.
Definition: sdk_events.h:20
bool CompilerFinished(bool compilerFailed, StartType startType)
Called when the compilation has finished.
void ParseOutput(const wxString &output)
virtual void Reload()=0
int GetThreadsCount() const
int GetActiveStackFrame() const
#define wxSCI_C_DEFAULT
Lexical states for SCLEX_CPP, SCLEX_BULLANT, SCLEX_COBOL, SCLEX_TACL, SCLEX_TAL.
Definition: wxscintilla.h:629
void CleanupWhenProjectClosed(cbProject *project)
const StackFrameContainer & GetStackFrames() const
returns the container with the current backtrace
wxString additionalCmdsBefore
commands before establishing remote connection
static void ConvertToGDBDirectory(wxString &str, wxString base=_T(""), bool relative=true)
wxEnvVariableHashMap env
PipedProcess * m_pProcess
Definition: debuggergdb.h:182
void OnUpdateTools(wxUpdateUIEvent &event)
virtual void StepOut()=0
bool WaitingCompilerToFinish() const
Definition: cbplugin.h:627
DLLIMPORT const wxWX2MBbuf cbU2C(const wxString &str)
Return multibyte (C string) representation of the string.
Definition: globals.cpp:743
void RemoveAllBreakpoints()
virtual TargetType GetTargetType() const
Read the target&#39;s type.
virtual void SetWorkingDirectory(const wxString &dir)
Set the working directory.
virtual void DetermineLanguage()
Determine language is debugged.
virtual void GetSymbol(wxString &symbol) const =0
wxUSE_UNICODE_dependent wxChar
cb::shared_ptr< const cbThread > GetThread(int index) const
bool IsAttachedToProcess() const
bool m_bIsConsole
Definition: debuggergdb.h:206
wxString BeforeFirst(wxUniChar ch, wxString *rest=NULL) const
virtual void SendString(const wxString &text)
bool changed
Definition: debugger_defs.h:33
ProjectManager * GetProjectManager() const
Functions returning pointers to the respective sub-manager instances.
Definition: manager.cpp:429
PluginManager manages plugins.
Definition: pluginmanager.h:76
bool Contains(const wxString &str) const
DebuggerManager * GetDebuggerManager() const
Definition: manager.cpp:484
void StepOut()
Execute the next instruction, stepping out of function calls if needed, and return control to the deb...
virtual void SwitchThread(size_t threadIndex)=0
Request to switch to another thread.
bool SupportsFeature(cbDebuggerFeature::Flags flag)
static bool Exists(int pid)
DLLIMPORT wxString UnixFilename(const wxString &filename, wxPathFormat format=wxPATH_NATIVE)
Definition: globals.cpp:228
void GetCurrentPosition(wxString &filename, int &line)
int m_PidToAttach
Definition: debuggergdb.h:185
virtual void Stop()
Event functor class.
Definition: cbfunctor.h:37
Represents a Code::Blocks project.
Definition: cbproject.h:96
void Continue()
Continue running the debugged program.
bool GetDebuggee(wxString &pathToDebuggee, wxString &workingDirectory, ProjectBuildTarget *target)
Definition: cbplugin.cpp:612
void SwitchToDebuggingLayout()
Definition: cbplugin.cpp:566
const wxString & GetActiveBuildTarget() const
Definition: cbproject.cpp:1373
bool extendedRemote
connect with extended remote or not
void DetermineLanguage()
virtual void InfoDLL()=0
void OnCatchThrow(wxCommandEvent &event)
#define wxSCI_C_WORD2
Definition: wxscintilla.h:645
bool IsQueueBusy() const
Is the driver processing some commands?
wxArtID wxART_QUESTION
virtual void SetVarValue(const wxString &var, const wxString &value)=0
virtual bool IsDebuggingStarted() const =0
Is debugging started.
virtual void RunningThreads()=0
int GetBreakpointsCount() const
int m_nConsolePid
Definition: debuggergdb.h:208
wxMenuItem * AppendSubMenu(wxMenu *submenu, const wxString &text, const wxString &help=wxEmptyString)
DLLIMPORT const wxString DEFAULT_CONSOLE_SHELL
Definition: globals.cpp:63
void SendCommand(const wxString &cmd, bool debugLog)
void DebuggeeContinued()
cbDisassemblyDlg * GetDisassemblyDialog()
Returns a pointer to the disassembly dialog.
DLLIMPORT wxString cbC2U(const char *str)
Return str as a proper unicode-compatible string.
Definition: globals.cpp:733
virtual const wxString & GetTitle() const
Read the target&#39;s title.
#define EVT_PIPEDPROCESS_TERMINATED(id, fn)
Definition: sdk_events.h:366
void DeleteWatch(cb::shared_ptr< cbWatch > watch)
wxInputStream * GetErrorStream() const
void CheckIfConsoleIsClosed()
void OnConfigurationChange(bool isActive)
Called when the user clicks OK in Settings -> Debugger...
virtual void Step()=0
ProjectRemoteDebuggingMap m_RemoteDebugging
Definition: debuggergdb.h:201
size_t Replace(const wxString &strOld, const wxString &strNew, bool replaceAll=true)
void Break()
Break the debugging process (stop the debuggee for debugging).
virtual void Backtrace()=0
void ShowWatchProperties(cb::shared_ptr< cbWatch > watch)
virtual void CPURegisters()=0
EVTIMPORT const wxEventType cbEVT_DEBUGGER_PAUSED
Definition: sdk_events.cpp:158
virtual bool SetActiveAddress(uint64_t addr)=0
const int DEBUGGER_CURSOR_CHANGED
wxCommandEvent ID fired when the cursor has changed.
bool BuildTargetValid(const wxString &name, bool virtuals_too=true) const
Is there a build target (virtual or real) by name?
Definition: cbproject.cpp:1335
void OnPrintElements(wxCommandEvent &event)
void UpdateWatch(cb::shared_ptr< cbWatch > watch)
bool wxGetEnvMap(wxEnvVariableHashMap *map)
wxMenuItem * AppendSeparator()
cbWatchesDlg * GetWatchesDialog()
Returns a pointer to the watches dialog.
DLLIMPORT bool IsWindowReallyShown(wxWindow *win)
Finds out if a window is really shown.
Definition: globals.cpp:931
wxString & Item(size_t nIndex)
cbProject * GetActiveProject()
Retrieve the active project.
wxString Read(const wxString &key, const wxString &defaultVal=wxEmptyString)
virtual wxString GetBasePath() const
Read the target&#39;s base path, e.g. if GetFilename() returns "/usr/local/bin/xxx", base path will retur...
DLLIMPORT int RegisterHook(HookFunctorBase *functor)
Register a project loading/saving hook.
void ClearActiveMarkFromAllEditors()
Definition: cbplugin.cpp:290
virtual void InfoFrame()=0
size_t size_type
const wxStringCharType * wx_str() const
void QueueCommand(DebuggerCmd *dcmd, QueuePriority prio=Low)
add a command in the queue. The DebuggerCmd will be deleted automatically when finished.
virtual int ShowModal()
int LaunchProcess(const wxString &cmd, const wxString &cwd)
Function signature breakpoint.
std::vector< cb::shared_ptr< cbThread > > ThreadsContainer
void UpdateBreakpoint(cb::shared_ptr< cbBreakpoint > breakpoint)
virtual void Stop()=0
Stop debugging.
wxString wxEmptyString
virtual void Attach(int pid)=0
Attach to process.
virtual void Detach()=0
Detach from running process.
virtual void ClearDirectories()
Clear directories search list.
#define wxOK
DLLIMPORT uint64_t cbDebuggerStringToAddress(const wxString &address)
Convert a string in hex form to a uint64_t number.
void OnInfoFPU(wxCommandEvent &event)
void OnAddSymbolFile(wxCommandEvent &event)
DebuggerConfiguration & GetActiveConfigEx()
void NotifyPlugins(CodeBlocksEvent &event)
virtual void RenameWatch(wxObject *prop, const wxString &newSymbol)=0
virtual void RemoveWatch(cb::shared_ptr< cbWatch > watch)=0
void AddWatchNoUpdate(const cb::shared_ptr< GDBWatch > &watch)
virtual bool UseDebugBreakProcess()=0
Ask the driver if the debugger should be interrupted with DebugBreakProcess or Ctrl+C event...
EVTIMPORT const wxEventType cbEVT_DEBUGGER_FINISHED
Definition: sdk_events.cpp:159
MacrosManager * GetMacrosManager() const
Definition: manager.cpp:454
virtual void StepInstruction()=0
const int DEBUGGER_SHOW_FILE_LINE
wxCommandEvent ID fired to display a file/line (w/out changing the cursor)
const wxString & _(const wxString &string)
long GetChildPID() const
Get the child&#39;s (debuggee&#39;s) PID.
wxString & Trim(bool fromRight=true)
void OnShowFile(wxCommandEvent &event)
Normal file/line breakpoint.
Base class for plugin configuration panels.
Plugin registration object.
Definition: cbplugin.h:1099
#define cbAssert(expr)
Definition: cbexception.h:48
static void Yield()
Whenever you need to call wxYield(), call Manager::Yield(). It&#39;s safer.
Definition: manager.cpp:221
static wxString GetShellString()
void OnAttachReal()
void RemoveAllProjectBreakpoints(cbProject *prj)
int GetCurrentFrame() const
virtual wxWindow * GetWindow()=0
ProjectBuildTarget * GetBuildTarget(int index)
Access a build target.
Definition: cbproject.cpp:1392
DebuggerDriver * GetDriver()
Will always return a driver, or throw a code assertion error.
virtual void SetNextStatement(const wxString &filename, int line)=0
void ApplyBreakpoints()
bool ToLong(long *val, int base=10) const
Abstract base class for compilers.
Definition: compiler.h:274
void OnGDBError(wxCommandEvent &event)
wxString function
Definition: debugger_defs.h:31
wxString & erase(size_type pos=0, size_type n=npos)
virtual void Disassemble()=0
virtual const wxArrayString & GetLinkerSearchDirs(ProjectBuildTarget *target)
Get the full linker dirs used in the actual command line.
#define EVT_PIPEDPROCESS_STDERR(id, fn)
Definition: sdk_events.h:363
void SetCurrentFrame(int number, bool user_selected)
bool IsEmpty() const
DLLIMPORT void PlaceWindow(wxTopLevelWindow *w, cbPlaceDialogMode mode=pdlBest, bool enforce=false)
Definition: globals.cpp:1177
size_type size() const
void ShiftBreakpoint(int index, int lines_to_shift)
void OnInfoFiles(wxCommandEvent &event)
void Clear()
Debugger cursor info.
Definition: debugger_defs.h:26
wxString GetPath(int flags=wxPATH_GET_VOLUME, wxPathFormat format=wxPATH_NATIVE) const
bool m_stopDebuggerConsoleClosed
Definition: debuggergdb.h:207
bool HasWatch(cb::shared_ptr< cbWatch > watch)
The entry point singleton for working with projects.
virtual const wxString & GetCompilerID() const
Read the target&#39;s compiler.
virtual wxString GetCommandLine(const wxString &debugger, const wxString &debuggee, const wxString &userArguments)=0
Get the command-line to launch the debugger.
void OnInfoFrame(wxCommandEvent &event)
DebugCommandConst
Definition: debuggergdb.cpp:86
static const size_t npos
void ReplaceEnvVars(wxString &buffer)
Definition: macrosmanager.h:32
void OnInfoSignals(wxCommandEvent &event)
Target produces a console executable (without GUI) (distinction between ttExecutable and ttConsoleOnl...
cbBacktraceDlg * GetBacktraceDialog()
int DoDebug(bool breakOnEntry)
cbBreakpointsDlg * GetBreakpointDialog()
Returns a pointer to the breakpoints dialog.
wxString CleanStringValue(wxString value)
bool m_Canceled
Definition: debuggergdb.h:210
RemoteDebuggingMap & GetRemoteDebuggingMap(cbProject *project=0)
wxString GetFullName() const
bool ShowValueTooltip(int style)
#define EVT_PIPEDPROCESS_STDOUT(id, fn)
Definition: sdk_events.h:360
wxString & insert(size_t nPos, const wxString &str)
cbDebuggerConfiguration * LoadConfig(const ConfigManagerWrapper &config)
void AddSourceDir(const wxString &dir)
void wxMilliSleep(unsigned long milliseconds)
wxString GetCommonTopLevelPath() const
Definition: cbproject.cpp:423
int ShowModal() override
bool enabled
Is the breakpoint enabled?
void StepIntoInstruction()
Execute the next instruction and return control to the debugger, if the instruction is a function cal...
const wxString & GetBuildTargetName() const
Definition: sdk_events.h:59
void OnGDBTerminated(wxCommandEvent &event)
int m_printElements
Definition: debuggergdb.h:221
int LaunchProcessWithShell(const wxString &cmd, wxProcess *process, const wxString &cwd)
BreakpointsList const & GetBreakpoints() const
Definition: debuggerstate.h:22
virtual void MemoryDump()=0
cb::shared_ptr< cbWatch > DLLIMPORT cbGetRootWatch(cb::shared_ptr< cbWatch > watch)
void RegisterEventSink(wxEventType eventType, IEventFunctorBase< CodeBlocksEvent > *functor)
Definition: manager.cpp:550
cbConfigurationPanel * GetProjectConfigurationPanel(wxWindow *parent, cbProject *project)
cb::shared_ptr< cbBreakpoint > GetBreakpoint(int index)
size_t Add(const wxString &str, size_t copies=1)
void OnBuildTargetSelected(CodeBlocksEvent &event)
bool StartsWith(const wxString &prefix, wxString *rest=NULL) const
const Cursor & GetCursor() const
Get debugger&#39;s cursor.
void OnIdle(wxIdleEvent &event)
wxString additionalShellCmdsBefore
shell commands before establishing remote connection
Represents a Code::Blocks project build target.
void SetupToolsMenu(wxMenu &menu)
wxString file
Definition: debugger_defs.h:29
bool RunToCursor(const wxString &filename, int line, const wxString &line_text)
Run the debugged program until it reaches the cursor at the current editor.
size_t GetCount() const
bool m_NoDebugInfo
Definition: debuggergdb.h:188
void EnableBreakpoint(cb::shared_ptr< cbBreakpoint > breakpoint, bool enable)
void SetNextStatement(const wxString &filename, int line)
Sets the position of the Program counter to the specified filename:line.
int Find(wxUniChar ch, bool fromEnd=false) const
cb::shared_ptr< cbBreakpoint > AddDataBreakpoint(const wxString &dataExpression)
Request to add a breakpoint based on a data expression.
wxUniChar GetChar(size_t n) const
WatchesContainer m_watches
Definition: debuggergdb.h:214
void OnGDBOutput(wxCommandEvent &event)
ProjectsArray * GetProjects()
Retrieve an array of all the opened projects.
wxMenuItem * AppendRadioItem(int id, const wxString &item, const wxString &help=wxEmptyString)
wxOutputStream * GetOutputStream() const
wxString address
Definition: debugger_defs.h:30
cb::shared_ptr< GDBWatch > m_funcArgsWatch
Definition: debuggergdb.h:215
wxString cwd
void ResetBreakpoint(cb::shared_ptr< DebuggerBreakpoint > bp)
Functor class for use as a project loading/saving hook.
virtual void Prepare(bool isConsole, int printElements)=0
Prepares the debugging process by setting up search dirs etc.
void OnValueTooltip(const wxString &token, const wxRect &evalRect)
wxUniChar at(size_t n) const
wxString GetDataExpression() const
std::map< ProjectBuildTarget *, RemoteDebugging > RemoteDebuggingMap
void MergeWith(const RemoteDebugging &other)
bool wxSetEnv(const wxString &var, const wxString &value)
int Printf(const wxString &pszFormat,...)
cb::shared_ptr< GDBWatch > m_localsWatch
Definition: debuggergdb.h:215
virtual void InfoSignals()=0
void NextInstruction()
Execute the next instruction and return control to the debugger.
Basic interface for debugger commands.
Definition: debugger_defs.h:49
int SelectTarget(int initial=-1, bool evenIfOne=false)
Displays a target selection dialog.
Definition: cbproject.cpp:1130
Abstract base hook functor interface.
#define NULL
Definition: prefix.cpp:59
bool skipLDpath
skip adjusting LD_LIBRARY_PATH before launching debugger
bool HasDriver() const
Check so see if Driver exists before getting it.
void Step()
Execute the next instruction, stepping into function calls if needed, and return control to the debug...
static wxString Format(const wxString &format,...)
cb::shared_ptr< const cbWatch > GetParent() const
ConnectionType connType
wxString Mid(size_t first, size_t nCount=wxString::npos) const
Dialog that contains a "Don&#39;t annoy me" checkbox.
wxMenuItem * Insert(size_t pos, wxMenuItem *menuItem)
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
virtual void InfoFPU()=0
bool m_TemporaryBreak
Definition: debuggergdb.h:212
void DebugLog(const wxString &msg, Logger::level level=Logger::info)
Definition: cbplugin.cpp:540
void SetOwner(wxEvtHandler *owner, int id=-1)
Wrapper class for reading or writing config values, without the need for the full path...
long wxExecute(const wxString &command, int flags=wxEXEC_ASYNC, wxProcess *callback=NULL, const wxExecuteEnv *env=NULL)
void OnUpdateCatchThrow(wxUpdateUIEvent &event)
bool IsRunning() const
Is the plugin currently debugging?
Definition: debuggergdb.h:85
wxMenuItem * AppendCheckItem(int id, const wxString &item, const wxString &help=wxEmptyString)
DebuggerState m_State
Definition: debuggergdb.h:34
Target only runs commands in pre-build and/or post-build steps.
void RunCommand(int cmd)
bool SwitchToThread(int thread_number)