debuggermanager.h 15.6 KB
Newer Older
1
/**************************************************************************
con's avatar
con committed
2
3
4
**
** This file is part of Qt Creator
**
5
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
con's avatar
con committed
6
**
7
** Contact: Nokia Corporation (qt-info@nokia.com)
con's avatar
con committed
8
**
9
** Commercial Usage
10
**
11
12
13
14
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
15
**
16
** GNU Lesser General Public License Usage
17
**
18
19
20
21
22
23
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24
**
25
** If you are unsure which license is appropriate for your use, please
26
** contact the sales department at http://www.qtsoftware.com/contact.
con's avatar
con committed
27
**
28
**************************************************************************/
hjk's avatar
hjk committed
29

con's avatar
con committed
30
31
32
33
34
35
36
#ifndef DEBUGGER_DEBUGGERMANAGER_H
#define DEBUGGER_DEBUGGERMANAGER_H

#include <QtCore/QByteArray>
#include <QtCore/QObject>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
37
#include <QtCore/QSharedPointer>
con's avatar
con committed
38
39
40
41
42

QT_BEGIN_NAMESPACE
class QAction;
class QAbstractItemModel;
class QDockWidget;
43
class QLabel;
con's avatar
con committed
44
class QMainWindow;
45
class QPoint;
46
class QTimer;
con's avatar
con committed
47
class QWidget;
48
class QDebug;
con's avatar
con committed
49
50
QT_END_NAMESPACE

51
namespace Core {
52
53
class IOptionsPage;
} // namespace Core
54

55
namespace TextEditor {
56
class ITextEditor;
57
58
}

con's avatar
con committed
59
60
61
namespace Debugger {
namespace Internal {

62
63
64
65
66
typedef QLatin1Char _c;
typedef QLatin1String __;
inline QString _(const char *s) { return QString::fromLatin1(s); }
inline QString _(const QByteArray &ba) { return QString::fromLatin1(ba, ba.size()); }

con's avatar
con committed
67
class DebuggerOutputWindow;
68
class DebuggerRunControl;
con's avatar
con committed
69
70
71
72
73
74
75
76
77
78
class DebuggerPlugin;
class DebugMode;

class BreakHandler;
class DisassemblerHandler;
class ModulesHandler;
class RegisterHandler;
class StackHandler;
class ThreadsHandler;
class WatchHandler;
79
class SourceFilesWindow;
con's avatar
con committed
80
81
class WatchData;
class BreakpointData;
82
class Symbol;
con's avatar
con committed
83
84
85
86
87
88
89
90
91

// Note: the Debugger process itself is referred to as 'Debugger',
// whereas the debugged process is referred to as 'Inferior' or 'Debuggee'.

//     DebuggerProcessNotReady
//          |
//     DebuggerProcessStartingUp
//          | <-------------------------------------.
//     DebuggerInferiorRunningRequested             |
92
93
94
//          |                                       |
//     DebuggerInferiorRunning                      |
//          |                                       |
con's avatar
con committed
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
//     DebuggerInferiorStopRequested                |
//          |                                       |
//     DebuggerInferiorStopped                      |
//          |                                       |
//          `---------------------------------------'
//
// Allowed actions:
//    [R] :  Run
//    [C] :  Continue
//    [N] :  Step, Next



enum DebuggerStatus
{
    DebuggerProcessNotReady,          // Debugger not started
    DebuggerProcessStartingUp,        // Debugger starting up

    DebuggerInferiorRunningRequested, // Debuggee requested to run
    DebuggerInferiorRunning,          // Debuggee running
    DebuggerInferiorStopRequested,    // Debuggee running, stop requested
    DebuggerInferiorStopped,          // Debuggee stopped
};

119
120
enum DebuggerStartMode
{
121
    NoStartMode,
122
123
124
125
126
127
128
    StartInternal,         // Start current start project's binary
    StartExternal,         // Start binary found in file system
    AttachExternal,        // Attach to running process by process id
    AttachCrashedExternal, // Attach to crashed process by process id
    AttachTcf,             // Attach to a running Target Communication Framework agent
    AttachCore,            // Attach to a core file
    StartRemote            // Start and attach to a remote process
129
130
};

131
132
133
134
enum LogChannel
{
    LogInput,   // Used for user input
    LogOutput,
135
    LogWarning,
136
137
138
139
140
141
    LogError,
    LogStatus,  // Used for status changed messages
    LogDebug,
    LogMisc    
};

142
143
struct DebuggerStartParameters
{
144
145
146
147
148
149
150
151
152
153
154
    DebuggerStartParameters();
    void clear();

    QString executable;
    QString coreFile;
    QStringList processArgs;
    QStringList environment;
    QString workingDir;
    QString buildDir;
    qint64 attachPID;
    bool useTerminal;
155
    QString crashParameter; // for AttachCrashedExternal
156
157
158
159
    // for remote debugging
    QString remoteChannel;
    QString remoteArchitecture;
    QString serverStartScript;
160
    int toolChainType;
161
162
163
164
};

QDebug operator<<(QDebug str, const DebuggerStartParameters &);

con's avatar
con committed
165
166
167
class IDebuggerEngine;
class GdbEngine;
class ScriptEngine;
168
class CdbDebugEngine;
169
struct CdbDebugEnginePrivate;
con's avatar
con committed
170

171
172
173
174
175
176
177
178
179
// Flags for initialization
enum DebuggerEngineTypeFlags {
    GdbEngineType = 0x1,
    ScriptEngineType = 0x2,
    CdbEngineType = 0x4,
    TcfEngineType = 0x8,
    AllEngineTypes = (GdbEngineType|ScriptEngineType|CdbEngineType|TcfEngineType)
};

con's avatar
con committed
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
// The construct below is not nice but enforces a bit of order. The
// DebuggerManager interfaces a lots of thing: The DebuggerPlugin,
// the DebuggerEngines, the RunMode, the handlers and views.
// Instead of making the whole interface public, we split in into
// smaller parts and grant friend access only to the classes that
// need it.


//
// IDebuggerManagerAccessForEngines
//

class IDebuggerManagerAccessForEngines
{
public:
    virtual ~IDebuggerManagerAccessForEngines() {}

private:
    // This is the part of the interface that's exclusively seen by the
199
    // debugger engines
200

201
202
    friend class CdbDebugEngine;
    friend class CdbDebugEventCallback;
203
    friend class CdbDumperHelper;
204
    friend class CdbExceptionLoggerEventCallback;
205
206
207
208
    friend class GdbEngine;
    friend class ScriptEngine;
    friend class TcfEngine;
    friend struct CdbDebugEnginePrivate;
con's avatar
con committed
209
210

    // called from the engines after successful startup
211
    virtual void notifyInferiorStopRequested() = 0;
212
    virtual void notifyInferiorStopped() = 0;
con's avatar
con committed
213
214
215
    virtual void notifyInferiorRunningRequested() = 0;
    virtual void notifyInferiorRunning() = 0;
    virtual void notifyInferiorExited() = 0;
216
    virtual void notifyInferiorPidChanged(qint64) = 0;
con's avatar
con committed
217
218
219
220
221
222
223
224

    virtual DisassemblerHandler *disassemblerHandler() = 0;
    virtual ModulesHandler *modulesHandler() = 0;
    virtual BreakHandler *breakHandler() = 0;
    virtual RegisterHandler *registerHandler() = 0;
    virtual StackHandler *stackHandler() = 0;
    virtual ThreadsHandler *threadsHandler() = 0;
    virtual WatchHandler *watchHandler() = 0;
225
    virtual SourceFilesWindow *sourceFileWindow() = 0;
con's avatar
con committed
226

Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
227
    virtual void showApplicationOutput(const QString &data) = 0;
228
229
    virtual void showDebuggerOutput(int channel, const QString &msg) = 0;
    virtual void showDebuggerInput(int channel, const QString &msg) = 0;
230

con's avatar
con committed
231
232
    virtual void reloadDisassembler() = 0;
    virtual void reloadModules() = 0;
233
    virtual void reloadSourceFiles() = 0;
con's avatar
con committed
234
    virtual void reloadRegisters() = 0;
235
236
237
238

    virtual bool qtDumperLibraryEnabled() const = 0;
    virtual QString qtDumperLibraryName() const = 0;
    virtual void showQtDumperLibraryWarning(const QString &details = QString()) = 0;
239
    virtual bool isReverseDebugging() const = 0;
240

241
242
243
    virtual qint64 inferiorPid() const = 0;

    virtual QSharedPointer<DebuggerStartParameters> startParameters() const = 0;
con's avatar
con committed
244
245
246
247
248
249
250
251
};


//
// DebuggerManager
//

class DebuggerManager : public QObject,
hjk's avatar
hjk committed
252
    public IDebuggerManagerAccessForEngines
con's avatar
con committed
253
254
255
256
{
    Q_OBJECT

public:
257
    DebuggerManager();
258
    QList<Core::IOptionsPage*> initializeEngines(unsigned enabledTypeFlags);
259

con's avatar
con committed
260
261
262
263
    ~DebuggerManager();

    IDebuggerManagerAccessForEngines *engineInterface();
    QMainWindow *mainWindow() const { return m_mainWindow; }
264
    QLabel *statusLabel() const { return m_statusLabel; }
con's avatar
con committed
265
266

public slots:
267
268
269
270
271
272
273
    void startNewDebugger(DebuggerRunControl *runControl, const QSharedPointer<DebuggerStartParameters> &startParameters);
    void exitDebugger();

    virtual QSharedPointer<DebuggerStartParameters> startParameters() const;
    virtual qint64 inferiorPid() const;

    void setQtDumperLibraryName(const QString &dl); // Run Control
con's avatar
con committed
274
275
276

    void setSimpleDockWidgetArrangement();
    void setLocked(bool locked);
277
    void dockActionTriggered();
278
    void modeVisibilityChanged(bool visible);
con's avatar
con committed
279
280
281
282
283
284

    void setBusyCursor(bool on);
    void queryCurrentTextEditor(QString *fileName, int *lineNumber, QObject **ed);
    QVariant sessionValue(const QString &name);

    void gotoLocation(const QString &file, int line, bool setLocationMarker);
285
    void fileOpen(const QString &file);
con's avatar
con committed
286
287
288
289
290
291
292
293
294
    void resetLocation();

    void interruptDebuggingRequest();

    void jumpToLineExec();
    void runToLineExec();
    void runToFunctionExec();
    void toggleBreakpoint();
    void breakByFunction(const QString &functionName);
295
    void breakByFunctionMain();
con's avatar
con committed
296
297
298
299
300
301
302
303
304
305
    void setBreakpoint(const QString &fileName, int lineNumber);
    void activateFrame(int index);
    void selectThread(int index);

    void stepExec();
    void stepOutExec();
    void nextExec();
    void stepIExec();
    void nextIExec();
    void continueExec();
306
    void detachDebugger();
con's avatar
con committed
307
308

    void addToWatchWindow();
hjk's avatar
hjk committed
309
    void updateWatchData(const WatchData &data);
310

con's avatar
con committed
311
    void sessionLoaded();
312
    void sessionUnloaded();
con's avatar
con committed
313
314
    void aboutToSaveSession();

315
    void assignValueInDebugger();
con's avatar
con committed
316
    void assignValueInDebugger(const QString &expr, const QString &value);
317
318

    void executeDebuggerCommand();
con's avatar
con committed
319
320
    void executeDebuggerCommand(const QString &command);

321
    void showStatusMessage(const QString &msg, int timeout = -1); // -1 forever
con's avatar
con committed
322
323

private slots:
324
325
    void showDebuggerOutput(int channel, const QString &msg);
    void showDebuggerInput(int channel, const QString &msg);
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
326
    void showApplicationOutput(const QString &data);
con's avatar
con committed
327
328
329
330

    void reloadDisassembler();
    void disassemblerDockToggled(bool on);

331
332
333
    void reloadSourceFiles();
    void sourceFilesDockToggled(bool on);

con's avatar
con committed
334
335
336
337
338
339
340
341
    void reloadModules();
    void modulesDockToggled(bool on);
    void loadSymbols(const QString &moduleName);
    void loadAllSymbols();

    void reloadRegisters();
    void registerDockToggled(bool on);
    void setStatus(int status);
342
    void clearStatusMessage();
343
    void attemptBreakpointSynchronization();
344
    void reloadFullStack();
con's avatar
con committed
345
346
347
348

private:
    //
    // Implementation of IDebuggerManagerAccessForEngines
349
    //
con's avatar
con committed
350
351
352
353
354
355
356
    DisassemblerHandler *disassemblerHandler() { return m_disassemblerHandler; }
    ModulesHandler *modulesHandler() { return m_modulesHandler; }
    BreakHandler *breakHandler() { return m_breakHandler; }
    RegisterHandler *registerHandler() { return m_registerHandler; }
    StackHandler *stackHandler() { return m_stackHandler; }
    ThreadsHandler *threadsHandler() { return m_threadsHandler; }
    WatchHandler *watchHandler() { return m_watchHandler; }
357
    SourceFilesWindow *sourceFileWindow() { return m_sourceFilesWindow; }
358

con's avatar
con committed
359
360
    void notifyInferiorStopped();
    void notifyInferiorRunningRequested();
361
    void notifyInferiorStopRequested();
con's avatar
con committed
362
363
    void notifyInferiorRunning();
    void notifyInferiorExited();
364
    void notifyInferiorPidChanged(qint64);
con's avatar
con committed
365

366
    void cleanupViews();
con's avatar
con committed
367
368
369
370

    //
    // Implementation of IDebuggerManagerAccessForDebugMode
    //
371
    QWidget *threadsWindow() const { return m_threadsWindow; }
con's avatar
con committed
372
373
    QList<QDockWidget*> dockWidgets() const { return m_dockWidgets; }

374
375
376
    virtual bool qtDumperLibraryEnabled() const;
    virtual QString qtDumperLibraryName() const;
    virtual void showQtDumperLibraryWarning(const QString &details = QString());
377
    virtual bool isReverseDebugging() const;
378

379
    //
con's avatar
con committed
380
    // internal implementation
381
    //
con's avatar
con committed
382
383
384
385
386
    Q_SLOT void loadSessionData();
    Q_SLOT void saveSessionData();
    Q_SLOT void dumpLog();

public:
387
    // stuff in this block should be made private by moving it to
con's avatar
con committed
388
389
390
    // one of the interfaces
    QAbstractItemModel *threadsModel();
    int status() const { return m_status; }
391
392
    DebuggerStartMode startMode() const;
    DebuggerRunControl *runControl() const { return m_runControl; }
con's avatar
con committed
393

394
395
    QList<Symbol> moduleSymbols(const QString &moduleName);

con's avatar
con committed
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
signals:
    void debuggingFinished();
    void inferiorPidChanged(qint64 pid);
    void statusChanged(int newstatus);
    void debugModeRequested();
    void previousModeRequested();
    void statusMessageRequested(const QString &msg, int timeout); // -1 for 'forever'
    void gotoLocationRequested(const QString &file, int line, bool setLocationMarker);
    void resetLocationRequested();
    void currentTextEditorRequested(QString *fileName, int *lineNumber, QObject **ob);
    void currentMainWindowRequested(QWidget **);
    void sessionValueRequested(const QString &name, QVariant *value);
    void setSessionValueRequested(const QString &name, const QVariant &value);
    void configValueRequested(const QString &name, QVariant *value);
    void setConfigValueRequested(const QString &name, const QVariant &value);
Oswald Buddenhagen's avatar
Oswald Buddenhagen committed
411
    void applicationOutputAvailable(const QString &output);
con's avatar
con committed
412
413
414
415

public:

private:
416
    void init();
hjk's avatar
hjk committed
417
    void runTest(const QString &fileName);
con's avatar
con committed
418
    QDockWidget *createDockForWidget(QWidget *widget);
hjk's avatar
hjk committed
419
    Q_SLOT void createNewDock(QWidget *widget);
420
421
422
    void updateDockWidget(QDockWidget *dockWidget);
    Q_SLOT void onDockVisibilityChange(bool visible);
    Q_SLOT void onTopLevelChanged();
con's avatar
con committed
423
424
425
426

    void shutdown();

    void toggleBreakpoint(const QString &fileName, int lineNumber);
427
428
    void toggleBreakpointEnabled(const QString &fileName, int lineNumber);
    BreakpointData *findBreakpoint(const QString &fileName, int lineNumber);
429
    void setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos);
con's avatar
con committed
430

431
    QSharedPointer<DebuggerStartParameters> m_startParameters;
432
    DebuggerRunControl *m_runControl;
433
434
435
    QString m_dumperLib;
    qint64 m_inferiorPid;

con's avatar
con committed
436
437
438

    /// Views
    QMainWindow *m_mainWindow;
439
    QLabel *m_statusLabel;
con's avatar
con committed
440
441
442
443
444
445
    QDockWidget *m_breakDock;
    QDockWidget *m_disassemblerDock;
    QDockWidget *m_modulesDock;
    QDockWidget *m_outputDock;
    QDockWidget *m_registerDock;
    QDockWidget *m_stackDock;
446
    QDockWidget *m_sourceFilesDock;
con's avatar
con committed
447
448
449
    QDockWidget *m_threadsDock;
    QDockWidget *m_watchDock;
    QList<QDockWidget*> m_dockWidgets;
450
    QList<bool> m_dockWidgetActiveState;
451
452
    bool m_locked;
    bool m_handleDockVisibilityChanges;
con's avatar
con committed
453
454
455
456
457
458
459
460

    BreakHandler *m_breakHandler;
    DisassemblerHandler *m_disassemblerHandler;
    ModulesHandler *m_modulesHandler;
    RegisterHandler *m_registerHandler;
    StackHandler *m_stackHandler;
    ThreadsHandler *m_threadsHandler;
    WatchHandler *m_watchHandler;
461
    SourceFilesWindow *m_sourceFilesWindow;
con's avatar
con committed
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478

    /// Actions
    friend class DebuggerPlugin;
    QAction *m_continueAction;
    QAction *m_stopAction;
    QAction *m_resetAction; // FIXME: Should not be needed in a stable release
    QAction *m_stepAction;
    QAction *m_stepOutAction;
    QAction *m_runToLineAction;
    QAction *m_runToFunctionAction;
    QAction *m_jumpToLineAction;
    QAction *m_nextAction;
    QAction *m_watchAction;
    QAction *m_breakAction;
    QAction *m_sepAction;
    QAction *m_stepIAction;
    QAction *m_nextIAction;
479
    QAction *m_reverseDirectionAction;
con's avatar
con committed
480
481
482
483
484
485
486
487
488
489
490
491
492
493

    QWidget *m_breakWindow;
    QWidget *m_disassemblerWindow;
    QWidget *m_localsWindow;
    QWidget *m_registerWindow;
    QWidget *m_modulesWindow;
    QWidget *m_tooltipWindow;
    QWidget *m_stackWindow;
    QWidget *m_threadsWindow;
    QWidget *m_watchersWindow;
    DebuggerOutputWindow *m_outputWindow;

    int m_status;
    bool m_busy;
494
495
    QTimer *m_statusTimer;
    QString m_lastPermanentStatusMessage;
con's avatar
con committed
496
497
498
499
500
501
502
503
504

    IDebuggerEngine *engine();
    IDebuggerEngine *m_engine;
};

} // namespace Internal
} // namespace Debugger

#endif // DEBUGGER_DEBUGGERMANAGER_H