Code::Blocks  SVN r11506
debuggerstate.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: 8543 $
6  * $Id: debuggerstate.cpp 8543 2012-11-10 22:36:18Z thomasdenk $
7  * $HeadURL: https://svn.code.sf.net/p/codeblocks/code/trunk/src/plugins/debuggergdb/debuggerstate.cpp $
8  */
9 
10 #include <sdk.h>
11 #include <cbexception.h>
12 #include "debuggerstate.h"
13 #include <compilerfactory.h>
14 #include "debuggergdb.h"
15 #include "debuggeroptionsdlg.h"
16 #include "projectbuildtarget.h"
17 #include "cdb_driver.h"
18 #include "gdb_driver.h"
19 
20 #ifndef CB_PRECOMP
21  #include <algorithm>
22 
23  #include "cbproject.h"
24  #include "manager.h"
25  #include "projectmanager.h"
26 #endif
27 
29  : m_pPlugin(plugin),
30  m_pDriver(0)
31 {
32 }
33 
35 {
36 }
37 
39 {
40  delete m_pDriver;
41  m_pDriver = nullptr;
42 
45  else
47  m_pDriver->SetTarget(target);
48  return true;
49 }
50 
52 {
53  bool operator()(const cb::shared_ptr<DebuggerBreakpoint> &bp) const
54  {
55  return bp->type == DebuggerBreakpoint::bptData || bp->temporary;
56  }
57 };
58 
60 {
61  delete m_pDriver;
62  m_pDriver = nullptr;
63  m_Breakpoints.erase(std::remove_if(m_Breakpoints.begin(), m_Breakpoints.end(), MatchDataAndTempBreakpoints()),
64  m_Breakpoints.end());
65 }
66 
68 {
69  return m_pDriver != NULL;
70 }
71 
73 {
75  return m_pDriver;
76 }
78 {
80  return m_pDriver;
81 }
82 
84 {
85  // FIXME (obfuscated#): This is not a good API design! Replace with RemoveAllBreakpoints
86  if (m_pDriver)
87  m_pDriver->RemoveBreakpoint(cb::shared_ptr<DebuggerBreakpoint>());
88  StopDriver();
89 
90  m_Breakpoints.clear();
91 }
92 
93 // The compiler now uses absolute paths to source files so we don't need
94 // any absolute->relative filename conversions here anymore.
95 // Just adjust the path separators...
97 {
98  wxString fname = filename;
99  fname.Replace(_T("\\"), _T("/"));
100  return fname;
101 } // end of ConvertToValidFilename
102 
103 cb::shared_ptr<DebuggerBreakpoint> DebuggerState::AddBreakpoint(const wxString& file, int line,
104  bool temp, const wxString& lineText)
105 {
106  wxString bpfile = ConvertToValidFilename(file);
107 
108  // do we have a bp there?
109  int idx = HasBreakpoint(bpfile, line, temp);
110  // if yes, remove old breakpoint first
111  if (idx != -1)
112  RemoveBreakpoint(idx);
113 
114  // create new bp
115 // Manager::Get()->GetLogManager()->DebugLog(F(_T("DebuggerState::AddBreakpoint() : bp: file=%s, bpfile=%s"), file.c_str(), bpfile.c_str()));
116  cb::shared_ptr<DebuggerBreakpoint> bp(new DebuggerBreakpoint);
117  bp->type = DebuggerBreakpoint::bptCode;
118  bp->filename = bpfile;
119  bp->filenameAsPassed = file;
120  bp->line = line;
121  bp->temporary = temp;
122  bp->lineText = lineText;
123  bp->userData = Manager::Get()->GetProjectManager()->FindProjectForFile(file, nullptr, false, false);
124  AddBreakpoint(bp);
125 
126  return bp;
127 }
128 
129 cb::shared_ptr<DebuggerBreakpoint> DebuggerState::AddBreakpoint(const wxString& dataAddr, bool onRead, bool onWrite)
130 {
131  cb::shared_ptr<DebuggerBreakpoint> bp(new DebuggerBreakpoint);
132  bp->type = DebuggerBreakpoint::bptData;
133  bp->breakAddress = dataAddr;
134  bp->breakOnRead = onRead;
135  bp->breakOnWrite = onWrite;
136  AddBreakpoint(bp);
137 
138  return bp;
139 }
140 
141 int DebuggerState::AddBreakpoint(cb::shared_ptr<DebuggerBreakpoint> bp)
142 {
143  if (!bp)
144  return -1;
145 
146  wxString bpfile = ConvertToValidFilename(bp->filename);
147  bp->filename = bpfile;
148  m_Breakpoints.push_back(bp);
149 
150  // notify driver if it is active
151  if (m_pDriver)
153  return bp->index;
154 }
155 
156 void DebuggerState::RemoveBreakpoint(cb::shared_ptr<DebuggerBreakpoint> bp, bool removeFromDriver)
157 {
158  int index = 0;
159  for (BreakpointsList::iterator it = m_Breakpoints.begin(); it != m_Breakpoints.end(); ++it, ++index)
160  {
161  if (*it == bp)
162  {
163  RemoveBreakpoint(index, removeFromDriver);
164  return;
165  }
166  }
167 }
168 
169 void DebuggerState::RemoveBreakpoint(int idx, bool removeFromDriver)
170 {
171  // do we have a valid index?
172  if (idx < 0 || idx >= (int)m_Breakpoints.size())
173  return;
174  // yes, remove it from the list
175  BreakpointsList::iterator it = m_Breakpoints.begin();
176  std::advance(it, idx);
177  cb::shared_ptr<DebuggerBreakpoint> bp = *it;
178  m_Breakpoints.erase(it);
179 
180  // notify driver if it is active
181  if (m_pDriver && removeFromDriver)
183 }
184 
186 {
187  if (m_pDriver)
188  {
189  for (BreakpointsList::iterator it = m_Breakpoints.begin(); it != m_Breakpoints.end(); ++it)
191  }
192  m_Breakpoints.clear();
193 }
194 
196 {
197  MatchProject(cbProject *project_in) : project(project_in) {}
198  bool operator()(const cb::shared_ptr<DebuggerBreakpoint> &bp)
199  {
200  return static_cast<cbProject*>(bp->userData) == project;
201  }
202 private:
204 };
205 
207 {
208  BreakpointsList::iterator start = std::remove_if(m_Breakpoints.begin(), m_Breakpoints.end(), MatchProject(prj));
209  if (m_pDriver)
210  {
211  for (BreakpointsList::iterator it = start; it != m_Breakpoints.end(); ++it)
213  }
214  m_Breakpoints.erase(start, m_Breakpoints.end());
215 }
216 
217 void DebuggerState::ShiftBreakpoint(cb::shared_ptr<DebuggerBreakpoint> bp, int nroflines)
218 {
219  // notify driver if it is active
220  if (m_pDriver)
221  {
223  bp->line += nroflines;
225  }
226  else
227  bp->line += nroflines;
228 }
229 
230 int DebuggerState::HasBreakpoint(const wxString& file, int line, bool temp)
231 {
232  wxString bpfile = ConvertToValidFilename(file);
233  int index = 0;
234  for (BreakpointsList::iterator it = m_Breakpoints.begin(); it != m_Breakpoints.end(); ++it, ++index)
235  {
236  DebuggerBreakpoint* bp = (*it).get();
237  if ((bp->filename == bpfile || bp->filenameAsPassed == file) && bp->line == line && bp->temporary == temp)
238  return index;
239  }
240  return -1;
241 }
242 
243 cb::shared_ptr<DebuggerBreakpoint> DebuggerState::GetBreakpoint(int idx)
244 {
245  if (idx < 0 || idx >= (int)m_Breakpoints.size())
246  return cb::shared_ptr<DebuggerBreakpoint>();
247  return m_Breakpoints[idx];
248 }
249 
250 cb::shared_ptr<DebuggerBreakpoint> DebuggerState::GetBreakpointByNumber(int num)
251 {
252  for (BreakpointsList::iterator it = m_Breakpoints.begin(); it != m_Breakpoints.end(); ++it)
253  {
254  if ((*it)->index == num)
255  return *it;
256  }
257  return cb::shared_ptr<DebuggerBreakpoint>();
258 }
259 
260 const cb::shared_ptr<DebuggerBreakpoint> DebuggerState::GetBreakpointByNumber(int num) const
261 {
262  for (BreakpointsList::const_iterator it = m_Breakpoints.begin(); it != m_Breakpoints.end(); ++it)
263  {
264  if ((*it)->index == num)
265  return *it;
266  }
267  return cb::shared_ptr<DebuggerBreakpoint>();
268 }
269 
270 void DebuggerState::ResetBreakpoint(cb::shared_ptr<DebuggerBreakpoint> bp)
271 {
272  // notify driver if it is active
273  if (m_pDriver)
274  {
277  }
278 }
279 
281 {
282  bool operator()(const cb::shared_ptr<DebuggerBreakpoint> &bp) const
283  {
284  return bp->temporary && bp->alreadySet;
285  }
286 };
287 
289 {
290  if (!m_pDriver)
291  return;
292 
293  m_Breakpoints.erase(std::remove_if(m_Breakpoints.begin(), m_Breakpoints.end(), MatchSetTempBreakpoint()),
294  m_Breakpoints.end());
295 
296  m_pDriver->RemoveBreakpoint(cb::shared_ptr<DebuggerBreakpoint>());
297  m_pPlugin->Log(_("Setting breakpoints"));
298 
299  for (BreakpointsList::const_iterator it = m_Breakpoints.begin(); it != m_Breakpoints.end(); ++it)
300  m_pDriver->AddBreakpoint(*it);
301 }
virtual void RemoveBreakpoint(cb::shared_ptr< DebuggerBreakpoint > bp)=0
Remove a breakpoint.
MatchProject(cbProject *project_in)
bool operator()(const cb::shared_ptr< DebuggerBreakpoint > &bp) const
int AddBreakpoint(cb::shared_ptr< DebuggerBreakpoint > bp)
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
void ShiftBreakpoint(cb::shared_ptr< DebuggerBreakpoint > bp, int nroflines)
Debugger breakpoint interface.
DebuggerGDB * m_pPlugin
Definition: debuggerstate.h:59
bool StartDriver(ProjectBuildTarget *target)
#define _T(string)
bool operator()(const cb::shared_ptr< DebuggerBreakpoint > &bp)
void Log(const wxString &msg, Logger::level level=Logger::info)
Definition: cbplugin.cpp:530
virtual void SetTarget(ProjectBuildTarget *target)=0
Sets the target.
void RemoveBreakpoint(int idx, bool removeFromDriver=true)
wxString filename
The filename for the breakpoint (kept as relative).
int line
The line for the breakpoint.
void RemoveAllBreakpoints()
DebuggerState(DebuggerGDB *plugin)
ProjectManager * GetProjectManager() const
Functions returning pointers to the respective sub-manager instances.
Definition: manager.cpp:429
DebuggerDriver * m_pDriver
Definition: debuggerstate.h:60
Represents a Code::Blocks project.
Definition: cbproject.h:96
cb::shared_ptr< DebuggerBreakpoint > GetBreakpointByNumber(int num)
wxString ConvertToValidFilename(const wxString &filename)
cbProject * project
size_t Replace(const wxString &strOld, const wxString &strNew, bool replaceAll=true)
int HasBreakpoint(const wxString &file, int line, bool temp)
virtual void AddBreakpoint(cb::shared_ptr< DebuggerBreakpoint > bp)=0
Add a breakpoint.
DebuggerConfiguration & GetActiveConfigEx()
const wxString & _(const wxString &string)
Normal file/line breakpoint.
#define cbAssert(expr)
Definition: cbexception.h:48
void RemoveAllProjectBreakpoints(cbProject *prj)
DebuggerDriver * GetDriver()
Will always return a driver, or throw a code assertion error.
void ApplyBreakpoints()
BreakpointsList m_Breakpoints
Definition: debuggerstate.h:61
wxString filenameAsPassed
The filename for the breakpoint as passed to the debugger (i.e. full filename).
cbProject * FindProjectForFile(const wxString &file, ProjectFile **resultFile, bool isRelative, bool isUnixFilename)
Return the project which has the file in it, also return the pointer to the ProjectFile object...
Represents a Code::Blocks project build target.
void ResetBreakpoint(cb::shared_ptr< DebuggerBreakpoint > bp)
#define NULL
Definition: prefix.cpp:59
bool HasDriver() const
Check so see if Driver exists before getting it.
bool temporary
Is this a temporary (one-shot) breakpoint?
bool operator()(const cb::shared_ptr< DebuggerBreakpoint > &bp) const
cb::shared_ptr< DebuggerBreakpoint > GetBreakpoint(int idx)