~ubuntu-branches/ubuntu/hardy/codeblocks/hardy-backports

« back to all changes in this revision

Viewing changes to src/plugins/debuggergdb/debuggerstate.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michael Casadevall
  • Date: 2008-07-17 04:39:23 UTC
  • Revision ID: james.westby@ubuntu.com-20080717043923-gmsy5cwkdjswghkm
Tags: upstream-8.02
ImportĀ upstreamĀ versionĀ 8.02

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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: 4909 $
 
6
 * $Id: debuggerstate.cpp 4909 2008-02-27 13:15:26Z mortenmacfly $
 
7
 * $HeadURL: svn://svn.berlios.de/codeblocks/tags/8.02/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 "projectbuildtarget.h"
 
16
#include "cdb_driver.h"
 
17
#include "gdb_driver.h"
 
18
#include "manager.h"
 
19
#include "projectmanager.h"
 
20
 
 
21
#ifndef CB_PRECOMP
 
22
    #include "cbproject.h"
 
23
#endif
 
24
 
 
25
DebuggerState::DebuggerState(DebuggerGDB* plugin)
 
26
    : m_pPlugin(plugin),
 
27
    m_pDriver(0),
 
28
    m_BpAutoIndex(0)
 
29
{
 
30
}
 
31
 
 
32
DebuggerState::~DebuggerState()
 
33
{
 
34
}
 
35
 
 
36
bool DebuggerState::StartDriver(ProjectBuildTarget* target)
 
37
{
 
38
    StopDriver();
 
39
    SetupBreakpointIndices();
 
40
    wxString idx = target ? target->GetCompilerID() : CompilerFactory::GetDefaultCompilerID();
 
41
    if (CompilerFactory::CompilerInheritsFrom(idx, _T("msvc*"))) // MSVC
 
42
        m_pDriver = new CDB_driver(m_pPlugin);
 
43
    else
 
44
        m_pDriver = new GDB_driver(m_pPlugin);
 
45
    return true;
 
46
}
 
47
 
 
48
void DebuggerState::StopDriver()
 
49
{
 
50
    if (m_pDriver)
 
51
        delete m_pDriver;
 
52
    m_pDriver = 0;
 
53
}
 
54
 
 
55
bool DebuggerState::HasDriver()
 
56
{
 
57
        return m_pDriver != NULL;
 
58
}
 
59
 
 
60
DebuggerDriver* DebuggerState::GetDriver()
 
61
{
 
62
        cbAssert(m_pDriver != NULL);
 
63
        return m_pDriver;
 
64
}
 
65
 
 
66
void DebuggerState::CleanUp()
 
67
{
 
68
    if (m_pDriver)
 
69
        m_pDriver->RemoveBreakpoint(0);
 
70
    StopDriver();
 
71
 
 
72
    for (unsigned int i = 0; i < m_Breakpoints.GetCount(); ++i)
 
73
    {
 
74
        DebuggerBreakpoint* bp = m_Breakpoints[i];
 
75
        delete bp;
 
76
    }
 
77
    m_Breakpoints.Clear();
 
78
}
 
79
 
 
80
// Re-number indices. Called before starting the debugging session
 
81
void DebuggerState::SetupBreakpointIndices()
 
82
{
 
83
    m_BpAutoIndex = 0;
 
84
    for (unsigned int i = 0; i < m_Breakpoints.GetCount(); ++i)
 
85
    {
 
86
        DebuggerBreakpoint* bp = m_Breakpoints[i];
 
87
        bp->index = ++m_BpAutoIndex;
 
88
    }
 
89
}
 
90
 
 
91
// The compiler now uses absolute paths to source files so we don't need
 
92
// any absolute->relative filename conversions here anymore.
 
93
// Just adjust the path separators...
 
94
wxString DebuggerState::ConvertToValidFilename(const wxString& filename)
 
95
{
 
96
    wxString fname = filename;
 
97
    fname.Replace(_T("\\"), _T("/"));
 
98
    return fname;
 
99
} // end of ConvertToValidFilename
 
100
 
 
101
cbProject* DebuggerState::FindProjectForFile(const wxString& file)
 
102
{
 
103
//    Manager::Get()->GetLogManager()->DebugLog(F(_T("Searching for project containing: ") + file));
 
104
    ProjectsArray* projects = Manager::Get()->GetProjectManager()->GetProjects();
 
105
    for (size_t i = 0; i < projects->GetCount(); ++i)
 
106
    {
 
107
        cbProject* prj = projects->Item(i);
 
108
        if (prj->GetFileByFilename(file, false, false))
 
109
        {
 
110
//            Manager::Get()->GetLogManager()->DebugLog(F(_T("Got it: %s (%p)"), prj->GetTitle().c_str(), prj));
 
111
            return prj;
 
112
        }
 
113
    }
 
114
//    Manager::Get()->GetLogManager()->DebugLog(F(_T("Not found...")));
 
115
    return 0;
 
116
}
 
117
 
 
118
int DebuggerState::AddBreakpoint(const wxString& file, int line, bool temp, const wxString& lineText)
 
119
{
 
120
    wxString bpfile = ConvertToValidFilename(file);
 
121
 
 
122
    // do we have a bp there?
 
123
    int idx = HasBreakpoint(bpfile, line);
 
124
    // if yes, remove old breakpoint first
 
125
    if (idx != -1)
 
126
        RemoveBreakpoint(idx, true);
 
127
    // create new bp
 
128
//    Manager::Get()->GetLogManager()->DebugLog(_T("add bp: file=%s, bpfile=%s"), file.c_str(), bpfile.c_str());
 
129
    DebuggerBreakpoint* bp = new DebuggerBreakpoint;
 
130
    bp->type = DebuggerBreakpoint::bptCode;
 
131
    bp->filename = bpfile;
 
132
    bp->filenameAsPassed = file;
 
133
    bp->line = line;
 
134
    bp->temporary = temp;
 
135
    bp->lineText = lineText;
 
136
    bp->userData = FindProjectForFile(file);
 
137
    return AddBreakpoint(bp);
 
138
}
 
139
 
 
140
int DebuggerState::AddBreakpoint(const wxString& dataAddr, bool onRead, bool onWrite)
 
141
{
 
142
    DebuggerBreakpoint* bp = new DebuggerBreakpoint;
 
143
    bp->type = DebuggerBreakpoint::bptData;
 
144
    bp->breakAddress = dataAddr;
 
145
    bp->breakOnRead = onRead;
 
146
    bp->breakOnWrite = onWrite;
 
147
    return AddBreakpoint(bp);
 
148
}
 
149
 
 
150
int DebuggerState::AddBreakpoint(DebuggerBreakpoint* bp)
 
151
{
 
152
    if (!bp)
 
153
        return -1;
 
154
 
 
155
    wxString bpfile = ConvertToValidFilename(bp->filename);
 
156
    bp->filename = bpfile;
 
157
 
 
158
    bp->index = ++m_BpAutoIndex;
 
159
    m_Breakpoints.Add(bp);
 
160
 
 
161
    // notify driver if it is active
 
162
    if (m_pDriver)
 
163
        m_pDriver->AddBreakpoint(bp);
 
164
    return bp->index;
 
165
}
 
166
 
 
167
DebuggerBreakpoint* DebuggerState::RemoveBreakpoint(DebuggerBreakpoint* bp, bool deleteit)
 
168
{
 
169
    for (unsigned int i = 0; i < m_Breakpoints.GetCount(); ++i)
 
170
    {
 
171
                if (m_Breakpoints[i] == bp)
 
172
                {
 
173
                        return RemoveBreakpoint(i, deleteit);
 
174
                }
 
175
    }
 
176
    return 0;
 
177
}
 
178
 
 
179
DebuggerBreakpoint* DebuggerState::RemoveBreakpoint(const wxString& file, int line, bool deleteit)
 
180
{
 
181
    wxString bpfile = ConvertToValidFilename(file);
 
182
    return RemoveBreakpoint(HasBreakpoint(bpfile, line), deleteit);
 
183
}
 
184
 
 
185
DebuggerBreakpoint* DebuggerState::RemoveBreakpoint(int idx, bool deleteit)
 
186
{
 
187
    // do we have a valid index?
 
188
    if (idx < 0 || idx >= (int)m_Breakpoints.GetCount())
 
189
        return 0;
 
190
    // yes, remove it from the list
 
191
    DebuggerBreakpoint* bp = m_Breakpoints[idx];
 
192
    m_Breakpoints.RemoveAt(idx);
 
193
 
 
194
    // notify driver if it is active
 
195
    if (m_pDriver)
 
196
        m_pDriver->RemoveBreakpoint(bp);
 
197
 
 
198
    if (deleteit)
 
199
    {
 
200
        delete bp;
 
201
        return 0;
 
202
    }
 
203
    return bp;
 
204
}
 
205
 
 
206
void DebuggerState::RemoveAllBreakpoints(const wxString& file, bool deleteit)
 
207
{
 
208
    wxString bpfile = ConvertToValidFilename(file);
 
209
    bool fileonly = !bpfile.IsEmpty();
 
210
    for (int i = m_Breakpoints.GetCount() - 1; i >= 0; --i)
 
211
    {
 
212
        if (fileonly)
 
213
        {
 
214
            DebuggerBreakpoint* bp = m_Breakpoints[i];
 
215
            if (bp->filename != bpfile && bp->filenameAsPassed != file)
 
216
                continue;
 
217
        }
 
218
        RemoveBreakpoint(i, deleteit);
 
219
    }
 
220
}
 
221
 
 
222
int DebuggerState::RemoveBreakpointsRange(const wxString& file, int startline, int endline)
 
223
{
 
224
    int ret = 0;
 
225
    wxString bpfile = ConvertToValidFilename(file);
 
226
    for (int i = m_Breakpoints.GetCount() - 1; i >= 0; --i)
 
227
    {
 
228
        DebuggerBreakpoint* bp = m_Breakpoints[i];
 
229
        if (bp->line >= startline && bp->line <= endline && (bp->filename == bpfile || bp->filenameAsPassed == file))
 
230
        {
 
231
            ++ret;
 
232
            RemoveBreakpoint(i, true);
 
233
        }
 
234
    }
 
235
    return ret;
 
236
}
 
237
 
 
238
void DebuggerState::RemoveAllProjectBreakpoints(cbProject* prj)
 
239
{
 
240
//    Manager::Get()->GetLogManager()->DebugLog(F(_T("Removing all breakpoints of project: %p"), prj));
 
241
    for (int i = m_Breakpoints.GetCount() - 1; i >= 0; --i)
 
242
    {
 
243
        DebuggerBreakpoint* bp = m_Breakpoints[i];
 
244
        if (bp->userData == prj)
 
245
        {
 
246
//            Manager::Get()->GetLogManager()->DebugLog(F(_T("Got one")));
 
247
            RemoveBreakpoint(i, true);
 
248
        }
 
249
    }
 
250
}
 
251
 
 
252
void DebuggerState::ShiftBreakpoints(const wxString& file, int startline, int nroflines)
 
253
{
 
254
    wxString bpfile = ConvertToValidFilename(file);
 
255
    for (int i = m_Breakpoints.GetCount() - 1; i >= 0; --i)
 
256
    {
 
257
        DebuggerBreakpoint* bp = m_Breakpoints[i];
 
258
        if (bp->line >= startline && (bp->filename == bpfile || bp->filenameAsPassed == file))
 
259
        {
 
260
            // notify driver if it is active
 
261
            if (m_pDriver)
 
262
                m_pDriver->RemoveBreakpoint(bp);
 
263
            bp->line += nroflines;
 
264
            // notify driver if it is active
 
265
            if (m_pDriver)
 
266
                m_pDriver->AddBreakpoint(bp);
 
267
        }
 
268
    }
 
269
}
 
270
 
 
271
int DebuggerState::HasBreakpoint(const wxString& file, int line)
 
272
{
 
273
    wxString bpfile = ConvertToValidFilename(file);
 
274
    for (unsigned int i = 0; i < m_Breakpoints.GetCount(); ++i)
 
275
    {
 
276
        DebuggerBreakpoint* bp = m_Breakpoints[i];
 
277
        if ((bp->filename == bpfile || bp->filenameAsPassed == file) && bp->line == line)
 
278
            return i;
 
279
    }
 
280
    return -1;
 
281
}
 
282
 
 
283
int DebuggerState::HasBreakpoint(const wxString& dataAddr)
 
284
{
 
285
    for (unsigned int i = 0; i < m_Breakpoints.GetCount(); ++i)
 
286
    {
 
287
        DebuggerBreakpoint* bp = m_Breakpoints[i];
 
288
        if (bp->breakAddress == dataAddr)
 
289
            return i;
 
290
    }
 
291
    return -1;
 
292
}
 
293
 
 
294
DebuggerBreakpoint* DebuggerState::GetBreakpoint(int idx)
 
295
{
 
296
    if (idx < 0 || idx >= (int)m_Breakpoints.GetCount())
 
297
        return 0;
 
298
    return m_Breakpoints[idx];
 
299
}
 
300
 
 
301
DebuggerBreakpoint* DebuggerState::GetBreakpointByNumber(int num)
 
302
{
 
303
    for (unsigned int i = 0; i < m_Breakpoints.GetCount(); ++i)
 
304
    {
 
305
        DebuggerBreakpoint* bp = m_Breakpoints[i];
 
306
        if (bp->index == num)
 
307
            return bp;
 
308
    }
 
309
    return 0;
 
310
}
 
311
 
 
312
void DebuggerState::ResetBreakpoint(int idx)
 
313
{
 
314
    DebuggerBreakpoint* bp = RemoveBreakpoint(idx, false);
 
315
    AddBreakpoint(bp);
 
316
}
 
317
 
 
318
void DebuggerState::ResetBreakpoint(DebuggerBreakpoint* bp)
 
319
{
 
320
    for (unsigned int i = 0; i < m_Breakpoints.GetCount(); ++i)
 
321
    {
 
322
                if (m_Breakpoints[i] == bp)
 
323
                {
 
324
                        RemoveBreakpoint(i);
 
325
                        AddBreakpoint(bp);
 
326
                        break;
 
327
                }
 
328
    }
 
329
}
 
330
 
 
331
void DebuggerState::ApplyBreakpoints()
 
332
{
 
333
    if (!m_pDriver)
 
334
        return;
 
335
 
 
336
    // remove any previously set temporary breakpoints
 
337
    int i = (int)m_Breakpoints.GetCount() - 1;
 
338
    while (i >= 0)
 
339
    {
 
340
        DebuggerBreakpoint* bp = m_Breakpoints[i];
 
341
        if (bp->temporary && bp->alreadySet)
 
342
            m_Breakpoints.RemoveAt(i);
 
343
        --i;
 
344
    }
 
345
 
 
346
    m_pPlugin->Log(_("Setting breakpoints"));
 
347
    m_pDriver->RemoveBreakpoint(0); // clear all breakpoints
 
348
 
 
349
    i = (int)m_Breakpoints.GetCount() - 1;
 
350
    while (i >= 0)
 
351
    {
 
352
        DebuggerBreakpoint* bp = m_Breakpoints[i];
 
353
        m_pDriver->AddBreakpoint(bp);
 
354
        --i;
 
355
    }
 
356
}