OSDN Git Service

43b87b873c8f51b28accef6d05716de1bcf8667f
[qt-creator-jp/qt-creator-jp.git] / src / plugins / debugger / gdbengine.h
1 /***************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact:  Qt Software Information (qt-info@nokia.com)
8 **
9 **
10 ** Non-Open Source Usage
11 **
12 ** Licensees may use this file in accordance with the Qt Beta Version
13 ** License Agreement, Agreement version 2.2 provided with the Software or,
14 ** alternatively, in accordance with the terms contained in a written
15 ** agreement between you and Nokia.
16 **
17 ** GNU General Public License Usage
18 **
19 ** Alternatively, this file may be used under the terms of the GNU General
20 ** Public License versions 2.0 or 3.0 as published by the Free Software
21 ** Foundation and appearing in the file LICENSE.GPL included in the packaging
22 ** of this file.  Please review the following information to ensure GNU
23 ** General Public Licensing requirements will be met:
24 **
25 ** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
26 ** http://www.gnu.org/copyleft/gpl.html.
27 **
28 ** In addition, as a special exception, Nokia gives you certain additional
29 ** rights. These rights are described in the Nokia Qt GPL Exception
30 ** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
31 **
32 ***************************************************************************/
33
34 #ifndef DEBUGGER_GDBENGINE_H
35 #define DEBUGGER_GDBENGINE_H
36
37 #include "idebuggerengine.h"
38 #include "gdbmi.h"
39 #include "outputcollector.h"
40
41 #include <QtCore/QByteArray>
42 #include <QtCore/QHash>
43 #include <QtCore/QMap>
44 #include <QtCore/QObject>
45 #include <QtCore/QProcess>
46 #include <QtCore/QPoint>
47 #include <QtCore/QTextCodec>
48 #include <QtCore/QVariant>
49
50 QT_BEGIN_NAMESPACE
51 class QAction;
52 class QAbstractItemModel;
53 class QWidget;
54 QT_END_NAMESPACE
55
56 namespace Debugger {
57 namespace Internal {
58
59 class DebuggerManager;
60 class IDebuggerManagerAccessForEngines;
61 class GdbResultRecord;
62 class GdbMi;
63
64 class WatchData;
65 class BreakpointData;
66
67 struct GdbCookie
68 {
69     GdbCookie() : type(0), synchronized(false) {}
70
71     QString command;
72     int type;
73     bool synchronized;
74     QVariant cookie;
75 };
76
77 enum DataDumperState
78 {
79     DataDumperUninitialized,
80     DataDumperLoadTried,
81     DataDumperAvailable,
82     DataDumperUnavailable,
83 };
84
85
86 class GdbEngine : public IDebuggerEngine
87 {
88     Q_OBJECT
89
90 public:
91     GdbEngine(DebuggerManager *parent);
92     ~GdbEngine();
93
94 signals:
95     void gdbResponseAvailable();
96     void gdbInputAvailable(const QString &prefix, const QString &msg);
97     void gdbOutputAvailable(const QString &prefix, const QString &msg);
98     void applicationOutputAvailable(const QString &output);
99
100 private:
101     //
102     // IDebuggerEngine implementation
103     //
104     void stepExec();
105     void stepOutExec();
106     void nextExec();
107     void stepIExec();
108     void nextIExec();
109
110     void shutdown();
111     void setToolTipExpression(const QPoint &pos, const QString &exp);
112     bool startDebugger();
113     void exitDebugger();
114
115     void continueInferior();
116     void interruptInferior();
117
118     void runToLineExec(const QString &fileName, int lineNumber);
119     void runToFunctionExec(const QString &functionName);
120     void jumpToLineExec(const QString &fileName, int lineNumber);
121
122     void activateFrame(int index);
123     void selectThread(int index);
124
125     Q_SLOT void attemptBreakpointSynchronization();
126
127     void loadSessionData() {}
128     void saveSessionData() {}
129
130     void assignValueInDebugger(const QString &expr, const QString &value);
131     void executeDebuggerCommand(const QString & command);
132
133     void loadSymbols(const QString &moduleName);
134     void loadAllSymbols();
135
136     void setDebugDumpers(bool on);
137     void setUseCustomDumpers(bool on);
138
139     //
140     // Own stuff
141     //
142     int currentFrame() const;
143     QString currentWorkingDirectory() const { return m_pwd; }
144
145     bool supportsThreads() const;
146
147     void initializeConnections();
148     void initializeVariables();
149     void queryFullName(const QString &fileName, QString *fullName);
150     QString fullName(const QString &fileName);
151     QString shortName(const QString &fullName);
152     // get one usable name out of these, try full names first
153     QString fullName(const QStringList &candidates);
154
155     void handleResult(const GdbResultRecord &, int type, const QVariant &);
156
157     // type and cookie are sender-internal data, opaque for the "event
158     // queue". resultNeeded == true increments m_pendingResults on
159     // send and decrements on receipt, effectively preventing 
160     // watch model updates before everything is finished.
161     enum StopNeeded { DoesNotNeedStop, NeedsStop };
162     enum Synchronization { NotSynchronized, Synchronized };
163     void sendCommand(const QString &command,
164         int type = 0, const QVariant &cookie = QVariant(),
165         StopNeeded needStop = DoesNotNeedStop,
166         Synchronization synchronized = NotSynchronized);
167     void sendSynchronizedCommand(const QString & command,
168         int type = 0, const QVariant &cookie = QVariant(),
169         StopNeeded needStop = DoesNotNeedStop);
170
171     void setTokenBarrier();
172
173     void updateLocals();
174
175 private slots:
176     void handleResponse();
177
178     void gdbProcError(QProcess::ProcessError error);
179     void readGdbStandardOutput();
180     void readGdbStandardError();
181     void readDebugeeOutput(const QByteArray &data);
182
183 private:
184     int terminationIndex(const QByteArray &buffer, int &length);
185     void handleStart(const GdbResultRecord &response);
186     void handleAsyncOutput2(const GdbMi &data);
187     void handleAsyncOutput(const GdbMi &data);
188     void handleResultRecord(const GdbResultRecord &response);
189     void handleFileExecAndSymbols(const GdbResultRecord &response);
190     void handleExecRun(const GdbResultRecord &response);
191     void handleExecJumpToLine(const GdbResultRecord &response);
192     void handleExecRunToFunction(const GdbResultRecord &response);
193     void handleInfoShared(const GdbResultRecord &response);
194     void handleInfoProc(const GdbResultRecord &response);
195     void handleInfoThreads(const GdbResultRecord &response);
196     void handleShowVersion(const GdbResultRecord &response);
197     void handleQueryPwd(const GdbResultRecord &response);
198     void handleQuerySources(const GdbResultRecord &response);
199     void debugMessage(const QString &msg);
200
201     OutputCollector m_outputCollector;
202     QTextCodec *m_outputCodec;
203     QTextCodec::ConverterState m_outputCodecState;
204
205     QByteArray m_inbuffer;
206
207     QProcess m_gdbProc;
208
209     QHash<int, GdbCookie> m_cookieForToken;
210     QHash<int, QByteArray> m_customOutputForToken;
211
212     QByteArray m_pendingConsoleStreamOutput;
213     QByteArray m_pendingTargetStreamOutput;
214     QByteArray m_pendingLogStreamOutput;
215     QString m_pwd;
216
217     // contains the first token number for the current round
218     // of evaluation. Responses with older tokens are considers
219     // out of date and discarded.
220     int m_oldestAcceptableToken;
221
222     int m_gdbVersion; // 6.8.0 is 680
223
224     // awful hack to keep track of used files
225     QMap<QString, QString> m_shortToFullName;
226     QMap<QString, QString> m_fullToShortName;
227
228     //
229     // Breakpoint specific stuff
230     //
231     void handleBreakList(const GdbResultRecord &record);
232     void handleBreakList(const GdbMi &table);
233     void handleBreakIgnore(const GdbResultRecord &record, int index);
234     void handleBreakInsert(const GdbResultRecord &record, int index);
235     void handleBreakInsert1(const GdbResultRecord &record, int index);
236     void handleBreakCondition(const GdbResultRecord &record, int index);
237     void handleBreakInfo(const GdbResultRecord &record, int index);
238     void extractDataFromInfoBreak(const QString &output, BreakpointData *data);
239     void breakpointDataFromOutput(BreakpointData *data, const GdbMi &bkpt);
240     void sendInsertBreakpoint(int index);
241
242
243     //
244     // Disassembler specific stuff
245     //
246     void handleDisassemblerList(const GdbResultRecord &record,
247         const QString &cookie);
248     void reloadDisassembler();
249     QString m_address;
250
251
252     //
253     // Modules specific stuff
254     //
255     void reloadModules();
256     void handleModulesList(const GdbResultRecord &record);
257
258
259     //
260     // Register specific stuff
261     // 
262     void reloadRegisters();
263     void handleRegisterListNames(const GdbResultRecord &record);
264     void handleRegisterListValues(const GdbResultRecord &record);
265
266     //
267     // Source file specific stuff
268     // 
269     void reloadSourceFiles();
270
271     //
272     // Stack specific stuff
273     // 
274     void handleStackListFrames(const GdbResultRecord &record);
275     void handleStackSelectThread(const GdbResultRecord &record, int cookie);
276     void handleStackListThreads(const GdbResultRecord &record, int cookie);
277
278
279     //
280     // Tooltip specific stuff
281     // 
282     void sendToolTipCommand(const QString &command, const QString &cookie);
283
284
285     //
286     // Watch specific stuff
287     //
288     // FIXME: BaseClass. called to improve situation for a watch item
289     void updateSubItem(const WatchData &data);
290
291     void updateWatchModel();
292     Q_SLOT void updateWatchModel2();
293
294     void insertData(const WatchData &data);
295     void sendWatchParameters(const QByteArray &params0);
296     void createGdbVariable(const WatchData &data);
297
298     void handleTypeContents(const QString &output);
299     void maybeHandleInferiorPidChanged(const QString &pid);
300
301     void tryLoadCustomDumpers();
302     void runCustomDumper(const WatchData &data, bool dumpChildren);
303     bool isCustomValueDumperAvailable(const QString &type) const;
304
305     void handleVarListChildren(const GdbResultRecord &record,
306         const WatchData &cookie);
307     void handleVarCreate(const GdbResultRecord &record,
308         const WatchData &cookie);
309     void handleVarAssign();
310     void handleEvaluateExpression(const GdbResultRecord &record,
311         const WatchData &cookie);
312     void handleToolTip(const GdbResultRecord &record,
313         const QString &cookie);
314     void handleDumpCustomValue1(const GdbResultRecord &record,
315         const WatchData &cookie);
316     void handleQueryDataDumper1(const GdbResultRecord &record);
317     void handleQueryDataDumper2(const GdbResultRecord &record);
318     void handleDumpCustomValue2(const GdbResultRecord &record,
319         const WatchData &cookie);
320     void handleDumpCustomEditValue(const GdbResultRecord &record);
321     void handleDumpCustomSetup(const GdbResultRecord &record);
322     void handleStackListLocals(const GdbResultRecord &record);
323     void handleStackListArguments(const GdbResultRecord &record);
324     void handleVarListChildrenHelper(const GdbMi &child,
325         const WatchData &parent);
326     void setWatchDataType(WatchData &data, const GdbMi &mi);
327     void setLocals(const QList<GdbMi> &locals);
328
329     QString m_editedData;
330     int m_pendingRequests;
331
332     QStringList m_availableSimpleDumpers;
333     QString m_namespace; // namespace used in "namespaced Qt";
334     int m_qtVersion; // Qt version used in the debugged program
335     
336     DataDumperState m_dataDumperState; // state of qt creator dumpers
337     QList<GdbMi> m_currentFunctionArgs;
338     QString m_currentFrame;
339     QMap<QString, QString> m_varToType;
340
341     bool m_waitingForBreakpointSynchronizationToContinue;
342     bool m_waitingForFirstBreakpointToBeHit;
343     bool m_modulesListOutdated;
344
345     QList<GdbCookie> m_commandsToRunOnTemporaryBreak;
346
347     DebuggerManager *q;
348     IDebuggerManagerAccessForEngines *qq;
349 };
350
351 } // namespace Internal
352 } // namespace Debugger
353
354 #endif // DEBUGGER_GDBENGINE_H