Updated documentation.
[kdbg.git] / kdbg / dbgdriver.h
blob813b64661585178a31cf83ebe5a167a26d1a8b90
1 // $Id$
3 // Copyright by Johannes Sixt
4 // This file is under GPL, the GNU General Public Licence
6 #ifndef DBGDRIVER_H
7 #define DBGDRIVER_H
9 #include <qqueue.h>
10 #include <qlist.h>
11 #include <qfile.h>
12 #include <kprocess.h>
15 class VarTree;
16 class ExprWnd;
17 class KDebugger;
20 enum DbgCommand {
21 DCinitialize,
22 DCtty,
23 DCexecutable,
24 DCtargetremote,
25 DCcorefile,
26 DCattach,
27 DCinfolinemain,
28 DCinfolocals,
29 DCinforegisters,
30 DCsetargs,
31 DCsetenv,
32 DCunsetenv,
33 DCcd,
34 DCbt,
35 DCrun,
36 DCcont,
37 DCstep,
38 DCnext,
39 DCfinish,
40 DCuntil, /* line number is zero-based! */
41 DCkill,
42 DCbreaktext,
43 DCbreakline, /* line number is zero-based! */
44 DCtbreakline, /* line number is zero-based! */
45 DCdelete,
46 DCenable,
47 DCdisable,
48 DCprint,
49 DCprintStruct,
50 DCprintQStringStruct,
51 DCframe,
52 DCfindType,
53 DCinfosharedlib,
54 DCinfobreak,
55 DCcondition,
56 DCignore
59 enum RunDevNull {
60 RDNstdin = 0x1, /* redirect stdin to /dev/null */
61 RDNstdout = 0x2, /* redirect stdout to /dev/null */
62 RDNstderr = 0x4 /* redirect stderr to /dev/null */
65 /**
66 * Debugger commands are placed in a queue. Only one command at a time is
67 * sent down to the debugger. All other commands in the queue are retained
68 * until the sent command has been processed by gdb. The debugger tells us
69 * that it's done with the command by sending the prompt. The output of the
70 * debugger is parsed at that time. Then, if more commands are in the
71 * queue, the next one is sent to the debugger.
73 struct CmdQueueItem
75 DbgCommand m_cmd;
76 QString m_cmdString;
77 bool m_committed; /* just a debugging aid */
78 // remember which expression when printing an expression
79 VarTree* m_expr;
80 ExprWnd* m_exprWnd;
81 // whether command was emitted due to direct user request (only set when relevant)
82 bool m_byUser;
84 CmdQueueItem(DbgCommand cmd, const QString& str) :
85 m_cmd(cmd),
86 m_cmdString(str),
87 m_committed(false),
88 m_expr(0),
89 m_exprWnd(0),
90 m_byUser(false)
91 { }
94 /**
95 * The information about a breakpoint that is parsed from the list of
96 * breakpoints.
98 struct Breakpoint
100 int id; /* gdb's number */
101 bool temporary;
102 bool enabled;
103 QString location;
104 QString condition; /* condition as printed by gdb */
105 int ignoreCount; /* ignore next that may hits */
106 int hitCount; /* as reported by gdb */
107 // the following items repeat the location, but in a better usable way
108 QString fileName;
109 int lineNo; /* zero-based line number */
113 * The information about a stack frame.
115 struct StackFrame
117 int frameNo;
118 QString fileName;
119 int lineNo; /* zero-based line number */
120 VarTree* var; /* more information if non-zero */
121 StackFrame() : var(0) { }
122 ~StackFrame();
126 * Register information
128 struct RegisterInfo
130 QString regName;
131 QString rawValue;
132 QString cookedValue; /* may be empty */
136 * This is an abstract base class for debugger process.
138 * This class represents the debugger program. It provides the low-level
139 * interface to the commandline debugger. As such it implements the
140 * commands and parses the output.
142 class DebuggerDriver : public KProcess
144 Q_OBJECT
145 public:
146 DebuggerDriver();
147 virtual ~DebuggerDriver() = 0;
149 virtual QString driverName() const = 0;
151 * Returns the default command string to invoke the debugger driver.
153 virtual QString defaultInvocation() const = 0;
155 virtual bool startup(QString cmdStr);
156 void dequeueCmdByVar(VarTree* var);
157 void setLogFileName(const QString& fname) { m_logFileName = fname; }
159 protected:
160 QString m_runCmd;
162 enum DebuggerState {
163 DSidle, /* gdb waits for input */
164 DSinterrupted, /* a command was interrupted */
165 DSrunningLow, /* gdb is running a low-priority command */
166 DSrunning, /* gdb waits for program */
167 DScommandSent, /* command has been sent, we wait for wroteStdin signal */
168 DScommandSentLow /* low-prioritycommand has been sent */
170 DebuggerState m_state;
172 public:
173 bool isIdle() const { return m_state == DSidle; }
175 * Tells whether a high prority command would be executed immediately.
177 bool canExecuteImmediately() const { return m_hipriCmdQueue.isEmpty(); }
179 protected:
180 char* m_output; /* normal gdb output */
181 int m_outputLen; /* current accumulated output */
182 int m_outputAlloc; /* space available in m_gdbOutput */
183 #if QT_VERSION < 200
184 typedef QString DelayedStr;
185 #else
186 typedef QCString DelayedStr;
187 #endif
188 QQueue<DelayedStr> m_delayedOutput; /* output colleced while we have receivedOutput */
189 /* but before signal wroteStdin arrived */
191 public:
193 * Enqueues a high-priority command. High-priority commands are
194 * executed before any low-priority commands. No user interaction is
195 * possible as long as there is a high-priority command in the queue.
197 virtual CmdQueueItem* executeCmd(DbgCommand,
198 bool clearLow = false) = 0;
199 virtual CmdQueueItem* executeCmd(DbgCommand, QString strArg,
200 bool clearLow = false) = 0;
201 virtual CmdQueueItem* executeCmd(DbgCommand, int intArg,
202 bool clearLow = false) = 0;
203 virtual CmdQueueItem* executeCmd(DbgCommand, QString strArg, int intArg,
204 bool clearLow = false) = 0;
205 virtual CmdQueueItem* executeCmd(DbgCommand, QString strArg1, QString strArg2,
206 bool clearLow = false) = 0;
207 virtual CmdQueueItem* executeCmd(DbgCommand, int intArg1, int intArg2,
208 bool clearLow = false) = 0;
210 enum QueueMode {
211 QMnormal, /* queues the command last */
212 QMoverride, /* removes an already queued command */
213 QMoverrideMoreEqual /* ditto, also puts the command first in the queue */
217 * Enqueues a low-priority command. Low-priority commands are executed
218 * after any high-priority commands.
220 virtual CmdQueueItem* queueCmd(DbgCommand,
221 QueueMode mode) = 0;
222 virtual CmdQueueItem* queueCmd(DbgCommand, QString strArg,
223 QueueMode mode) = 0;
224 virtual CmdQueueItem* queueCmd(DbgCommand, int intArg,
225 QueueMode mode) = 0;
226 virtual CmdQueueItem* queueCmd(DbgCommand, QString strArg, int intArg,
227 QueueMode mode) = 0;
230 * Flushes the command queues.
231 * @param hipriOnly if true, only the high priority queue is flushed.
233 virtual void flushCommands(bool hipriOnly = false);
236 * Terminates the debugger process.
238 virtual void terminate() = 0;
241 * Interrupts the debuggee.
243 virtual void interruptInferior() = 0;
246 * Parses the output as an array of QChars.
248 virtual VarTree* parseQCharArray(const char* output, bool wantErrorValue) = 0;
251 * Parses a back-trace (the output of the DCbt command).
253 virtual void parseBackTrace(const char* output, QList<StackFrame>& stack) = 0;
256 * Parses the output of the DCframe command;
257 * @param frameNo Returns the frame number.
258 * @param file Returns the source file name.
259 * @param lineNo The zero-based line number.
260 * @return false if the frame could not be parsed successfully. The
261 * output values are undefined in this case.
263 virtual bool parseFrameChange(const char* output,
264 int& frameNo, QString& file, int& lineNo) = 0;
267 * Parses a list of breakpoints.
268 * @param output The output of the debugger.
269 * @param brks The list of new #Breakpoint objects. The list
270 * must initially be empty.
271 * @return False if there was an error before the first breakpoint
272 * was found. Even if true is returned, #brks may be empty.
274 virtual bool parseBreakList(const char* output, QList<Breakpoint>& brks) = 0;
277 * Parses the output when the program stops to see whether this it
278 * stopped due to a breakpoint.
279 * @param output The output of the debugger.
280 * @param id Returns the breakpoint id.
281 * @param file Returns the file name in which the breakpoint is.
282 * @param lineNo Returns he zero-based line number of the breakpoint.
283 * @return False if there was no breakpoint.
285 virtual bool parseBreakpoint(const char* output, int& id,
286 QString& file, int& lineNo) = 0;
289 * Parses the output of the DCinfolocals command.
290 * @param output The output of the debugger.
291 * @param newVars Receives the parsed variable values. The values are
292 * simply append()ed to the supplied list.
294 virtual void parseLocals(const char* output, QList<VarTree>& newVars) = 0;
297 * Parses the output of a DCprint or DCprintStruct command.
298 * @param output The output of the debugger.
299 * @param wantErrorValue Specifies whether the error message should be
300 * provided as the value of a NKplain variable. If this is false,
301 * #var will be 0 if the printed value is an error message.
302 * @param var Returns the variable value. It is set to 0 if there was
303 * a parse error or if the output is an error message and wantErrorValue
304 * is false. If it is not 0, #var->text() will return junk and must be
305 * set using #var->setText().
306 * @return false if the output is an error message. Even if true is
307 * returned, #var might still be 0 (due to a parse error).
309 virtual bool parsePrintExpr(const char* output, bool wantErrorValue,
310 VarTree*& var) = 0;
313 * Parses the output of the DCcd command.
314 * @return false if the message is an error message.
316 virtual bool parseChangeWD(const char* output, QString& message) = 0;
319 * Parses the output of the DCexecutable command.
320 * @return false if an error occured.
322 virtual bool parseChangeExecutable(const char* output, QString& message) = 0;
325 * Parses the output of the DCcorefile command.
326 * @return false if the core file was not loaded successfully.
328 virtual bool parseCoreFile(const char* output) = 0;
330 enum StopFlags {
331 SFrefreshSource = 1, /* refresh of source code is needed */
332 SFrefreshBreak = 2, /* refresh breakpoints */
333 SFprogramActive = 4 /* program remains active */
336 * Parses the output of commands that execute (a piece of) the program.
337 * @return The inclusive OR of zero or more of the StopFlags.
339 virtual uint parseProgramStopped(const char* output, QString& message) = 0;
342 * Parses the output of the DCsharedlibs command.
344 virtual void parseSharedLibs(const char* output, QStrList& shlibs) = 0;
347 * Parses the output of the DCfindType command.
348 * @return true if a type was found.
350 virtual bool parseFindType(const char* output, QString& type) = 0;
353 * Parses the output of the DCinforegisters command.
355 virtual void parseRegisters(const char* output, QList<RegisterInfo>& regs) = 0;
357 protected:
358 /** Removes all commands from the low-priority queue. */
359 void flushLoPriQueue();
360 /** Removes all commands from the high-priority queue. */
361 void flushHiPriQueue();
363 QQueue<CmdQueueItem> m_hipriCmdQueue;
364 QList<CmdQueueItem> m_lopriCmdQueue;
366 * The active command is kept separately from other pending commands.
368 CmdQueueItem* m_activeCmd;
370 * Helper function that queues the given command string in the
371 * low-priority queue.
373 CmdQueueItem* queueCmdString(DbgCommand cmd, QString cmdString,
374 QueueMode mode);
376 * Helper function that queues the given command string in the
377 * high-priority queue.
379 CmdQueueItem* executeCmdString(DbgCommand cmd, QString cmdString,
380 bool clearLow);
381 void writeCommand();
382 virtual void commandFinished(CmdQueueItem* cmd) = 0;
384 protected:
385 /** @internal */
386 virtual int commSetupDoneC();
388 char m_prompt[10];
389 int m_promptLen;
390 char m_promptLastChar;
392 // log file
393 QString m_logFileName;
394 QFile m_logFile;
396 protected slots:
397 void slotReceiveOutput(KProcess*, char* buffer, int buflen);
398 void slotCommandRead(KProcess*);
399 void slotExited(KProcess*);
401 signals:
403 * This signal is emitted when the output of a command has been fully
404 * collected and is ready to be interpreted.
406 void commandReceived(CmdQueueItem* cmd, const char* output);
409 * This signal is emitted when the debugger recognizes that a specific
410 * location in a file ought to be displayed.
412 * Gdb's --fullname option supports this for the step, next, frame, and
413 * run commands (and possibly others).
415 * @param file specifies the file; this is not necessarily a full path
416 * name, and if it is relative, you won't know relative to what, you
417 * can only guess.
418 * @param lineNo specifies the line number (0-based!) (this may be
419 * negative, in which case the file should be activated, but the line
420 * should NOT be changed).
422 void activateFileLine(const QString& file, int lineNo);
425 * This signal is emitted when a command that starts the inferior has
426 * been submitted to the debugger.
428 void inferiorRunning();
431 * This signal is emitted when all output from the debugger has been
432 * consumed and no more commands are in the queues.
434 void enterIdleState();
437 #endif // DBGDRIVER_H