1 /***************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Qt Software Information (qt-info@nokia.com)
10 ** Non-Open Source Usage
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.
17 ** GNU General Public License Usage
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:
25 ** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
26 ** http://www.gnu.org/copyleft/gpl.html.
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.
32 ***************************************************************************/
34 #ifndef DEBUGGER_GDBENGINE_H
35 #define DEBUGGER_GDBENGINE_H
37 #include "idebuggerengine.h"
39 #include "outputcollector.h"
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>
52 class QAbstractItemModel;
59 class DebuggerManager;
60 class IDebuggerManagerAccessForEngines;
61 class GdbResultRecord;
69 GdbCookie() : type(0), synchronized(false) {}
79 DataDumperUninitialized,
82 DataDumperUnavailable,
86 class GdbEngine : public IDebuggerEngine
91 GdbEngine(DebuggerManager *parent);
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);
102 // IDebuggerEngine implementation
111 void setToolTipExpression(const QPoint &pos, const QString &exp);
112 bool startDebugger();
115 void continueInferior();
116 void interruptInferior();
118 void runToLineExec(const QString &fileName, int lineNumber);
119 void runToFunctionExec(const QString &functionName);
120 void jumpToLineExec(const QString &fileName, int lineNumber);
122 void activateFrame(int index);
123 void selectThread(int index);
125 Q_SLOT void attemptBreakpointSynchronization();
127 void loadSessionData() {}
128 void saveSessionData() {}
130 void assignValueInDebugger(const QString &expr, const QString &value);
131 void executeDebuggerCommand(const QString & command);
133 void loadSymbols(const QString &moduleName);
134 void loadAllSymbols();
136 void setDebugDumpers(bool on);
137 void setUseCustomDumpers(bool on);
142 int currentFrame() const;
143 QString currentWorkingDirectory() const { return m_pwd; }
145 bool supportsThreads() const;
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);
155 void handleResult(const GdbResultRecord &, int type, const QVariant &);
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);
171 void setTokenBarrier();
176 void handleResponse();
178 void gdbProcError(QProcess::ProcessError error);
179 void readGdbStandardOutput();
180 void readGdbStandardError();
181 void readDebugeeOutput(const QByteArray &data);
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);
201 OutputCollector m_outputCollector;
202 QTextCodec *m_outputCodec;
203 QTextCodec::ConverterState m_outputCodecState;
205 QByteArray m_inbuffer;
209 QHash<int, GdbCookie> m_cookieForToken;
210 QHash<int, QByteArray> m_customOutputForToken;
212 QByteArray m_pendingConsoleStreamOutput;
213 QByteArray m_pendingTargetStreamOutput;
214 QByteArray m_pendingLogStreamOutput;
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;
222 int m_gdbVersion; // 6.8.0 is 680
224 // awful hack to keep track of used files
225 QMap<QString, QString> m_shortToFullName;
226 QMap<QString, QString> m_fullToShortName;
229 // Breakpoint specific stuff
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);
244 // Disassembler specific stuff
246 void handleDisassemblerList(const GdbResultRecord &record,
247 const QString &cookie);
248 void reloadDisassembler();
253 // Modules specific stuff
255 void reloadModules();
256 void handleModulesList(const GdbResultRecord &record);
260 // Register specific stuff
262 void reloadRegisters();
263 void handleRegisterListNames(const GdbResultRecord &record);
264 void handleRegisterListValues(const GdbResultRecord &record);
267 // Source file specific stuff
269 void reloadSourceFiles();
272 // Stack specific stuff
274 void handleStackListFrames(const GdbResultRecord &record);
275 void handleStackSelectThread(const GdbResultRecord &record, int cookie);
276 void handleStackListThreads(const GdbResultRecord &record, int cookie);
280 // Tooltip specific stuff
282 void sendToolTipCommand(const QString &command, const QString &cookie);
286 // Watch specific stuff
288 // FIXME: BaseClass. called to improve situation for a watch item
289 void updateSubItem(const WatchData &data);
291 void updateWatchModel();
292 Q_SLOT void updateWatchModel2();
294 void insertData(const WatchData &data);
295 void sendWatchParameters(const QByteArray ¶ms0);
296 void createGdbVariable(const WatchData &data);
298 void handleTypeContents(const QString &output);
299 void maybeHandleInferiorPidChanged(const QString &pid);
301 void tryLoadCustomDumpers();
302 void runCustomDumper(const WatchData &data, bool dumpChildren);
303 bool isCustomValueDumperAvailable(const QString &type) const;
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);
329 QString m_editedData;
330 int m_pendingRequests;
332 QStringList m_availableSimpleDumpers;
333 QString m_namespace; // namespace used in "namespaced Qt";
334 int m_qtVersion; // Qt version used in the debugged program
336 DataDumperState m_dataDumperState; // state of qt creator dumpers
337 QList<GdbMi> m_currentFunctionArgs;
338 QString m_currentFrame;
339 QMap<QString, QString> m_varToType;
341 bool m_waitingForBreakpointSynchronizationToContinue;
342 bool m_waitingForFirstBreakpointToBeHit;
343 bool m_modulesListOutdated;
345 QList<GdbCookie> m_commandsToRunOnTemporaryBreak;
348 IDebuggerManagerAccessForEngines *qq;
351 } // namespace Internal
352 } // namespace Debugger
354 #endif // DEBUGGER_GDBENGINE_H