3 // Copyright by Johannes Sixt
4 // This file is under GPL, the GNU General Public Licence
40 DCuntil
, /* line number is zero-based! */
43 DCbreakline
, /* line number is zero-based! */
44 DCtbreakline
, /* line number is zero-based! */
60 RDNstdin
= 0x1, /* redirect stdin to /dev/null */
61 RDNstdout
= 0x2, /* redirect stdout to /dev/null */
62 RDNstderr
= 0x4 /* redirect stderr to /dev/null */
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.
77 bool m_committed
; /* just a debugging aid */
78 // remember which expression when printing an expression
81 // whether command was emitted due to direct user request (only set when relevant)
84 CmdQueueItem(DbgCommand cmd
, const QString
& str
) :
95 * The information about a breakpoint that is parsed from the list of
100 int id
; /* gdb's number */
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
109 int lineNo
; /* zero-based line number */
113 * The information about a stack frame.
119 int lineNo
; /* zero-based line number */
120 VarTree
* var
; /* more information if non-zero */
121 StackFrame() : var(0) { }
126 * Register information
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
147 virtual ~DebuggerDriver() = 0;
149 virtual QString
driverName() const = 0;
150 virtual bool startup();
151 void dequeueCmdByVar(VarTree
* var
);
152 void setLogFileName(const QString
& fname
) { m_logFileName
= fname
; }
158 DSidle
, /* gdb waits for input */
159 DSinterrupted
, /* a command was interrupted */
160 DSrunningLow
, /* gdb is running a low-priority command */
161 DSrunning
, /* gdb waits for program */
162 DScommandSent
, /* command has been sent, we wait for wroteStdin signal */
163 DScommandSentLow
/* low-prioritycommand has been sent */
165 DebuggerState m_state
;
168 bool isIdle() const { return m_state
== DSidle
; }
171 char* m_output
; /* normal gdb output */
172 int m_outputLen
; /* current accumulated output */
173 int m_outputAlloc
; /* space available in m_gdbOutput */
175 typedef QString DelayedStr
;
177 typedef QCString DelayedStr
;
179 QQueue
<DelayedStr
> m_delayedOutput
; /* output colleced while we have receivedOutput */
180 /* but before signal wroteStdin arrived */
184 * Enqueues a high-priority command. High-priority commands are
185 * executed before any low-priority commands. No user interaction is
186 * possible as long as there is a high-priority command in the queue.
188 virtual CmdQueueItem
* executeCmd(DbgCommand
,
189 bool clearLow
= false) = 0;
190 virtual CmdQueueItem
* executeCmd(DbgCommand
, QString strArg
,
191 bool clearLow
= false) = 0;
192 virtual CmdQueueItem
* executeCmd(DbgCommand
, int intArg
,
193 bool clearLow
= false) = 0;
194 virtual CmdQueueItem
* executeCmd(DbgCommand
, QString strArg
, int intArg
,
195 bool clearLow
= false) = 0;
196 virtual CmdQueueItem
* executeCmd(DbgCommand
, QString strArg1
, QString strArg2
,
197 bool clearLow
= false) = 0;
198 virtual CmdQueueItem
* executeCmd(DbgCommand
, int intArg1
, int intArg2
,
199 bool clearLow
= false) = 0;
202 QMnormal
, /* queues the command last */
203 QMoverride
, /* removes an already queued command */
204 QMoverrideMoreEqual
/* ditto, also puts the command first in the queue */
208 * Enqueues a low-priority command. Low-priority commands are executed
209 * after any high-priority commands.
211 virtual CmdQueueItem
* queueCmd(DbgCommand
,
213 virtual CmdQueueItem
* queueCmd(DbgCommand
, QString strArg
,
215 virtual CmdQueueItem
* queueCmd(DbgCommand
, int intArg
,
217 virtual CmdQueueItem
* queueCmd(DbgCommand
, QString strArg
, int intArg
,
221 * Parses the output as an array of QChars.
223 virtual VarTree
* parseQCharArray(const char* output
, bool wantErrorValue
) = 0;
226 * Parses a back-trace (the output of the DCbt command).
228 virtual void parseBackTrace(const char* output
, QList
<StackFrame
>& stack
) = 0;
231 * Parses the output of the DCframe command;
232 * @param frameNo Returns the frame number.
233 * @param file Returns the source file name.
234 * @param lineNo The zero-based line number.
235 * @return false if the frame could not be parsed successfully. The
236 * output values are undefined in this case.
238 virtual bool parseFrameChange(const char* output
,
239 int& frameNo
, QString
& file
, int& lineNo
) = 0;
242 * Parses a list of breakpoints.
243 * @param output The output of the debugger.
244 * @param brks The list of new #Breakpoint objects. The list
245 * must initially be empty.
246 * @return False if there was an error before the first breakpoint
247 * was found. Even if true is returned, #brks may be empty.
249 virtual bool parseBreakList(const char* output
, QList
<Breakpoint
>& brks
) = 0;
252 * Parses the output when the program stops to see whether this it
253 * stopped due to a breakpoint.
254 * @param output The output of the debugger.
255 * @param id Returns the breakpoint id.
256 * @param file Returns the file name in which the breakpoint is.
257 * @param lineNo Returns he zero-based line number of the breakpoint.
258 * @return False if there was no breakpoint.
260 virtual bool parseBreakpoint(const char* output
, int& id
,
261 QString
& file
, int& lineNo
) = 0;
264 * Parses the output of the DCinfolocals command.
265 * @param output The output of the debugger.
266 * @param newVars Receives the parsed variable values. The values are
267 * simply append()ed to the supplied list.
269 virtual void parseLocals(const char* output
, QList
<VarTree
>& newVars
) = 0;
272 * Parses the output of a DCprint or DCprintStruct command.
273 * @param output The output of the debugger.
274 * @param wantErrorValue Specifies whether the error message should be
275 * provided as the value of a NKplain variable. If this is false,
276 * #var will be 0 if the printed value is an error message.
277 * @param var Returns the variable value. It is set to 0 if there was
278 * a parse error or if the output is an error message and wantErrorValue
279 * is false. If it is not 0, #var->text() will return junk and must be
280 * set using #var->setText().
281 * @return false if the output is an error message. Even if true is
282 * returned, #var might still be 0 (due to a parse error).
284 virtual bool parsePrintExpr(const char* output
, bool wantErrorValue
,
288 * Parses the output of the DCcd command.
289 * @return false if the message is an error message.
291 virtual bool parseChangeWD(const char* output
, QString
& message
) = 0;
294 * Parses the output of the DCexecutable command.
295 * @return false if an error occured.
297 virtual bool parseChangeExecutable(const char* output
, QString
& message
) = 0;
300 * Parses the output of the DCcorefile command.
301 * @return false if the core file was not loaded successfully.
303 virtual bool parseCoreFile(const char* output
) = 0;
306 SFrefreshSource
= 1, /* refresh of source code is needed */
307 SFrefreshBreak
= 2, /* refresh breakpoints */
308 SFprogramActive
= 4 /* program remains active */
311 * Parses the output of commands that execute (a piece of) the program.
312 * @return The inclusive OR of zero or more of the StopFlags.
314 virtual uint
parseProgramStopped(const char* output
, QString
& message
) = 0;
317 * Parses the output of the DCsharedlibs command.
319 virtual void parseSharedLibs(const char* output
, QStrList
& shlibs
) = 0;
322 * Parses the output of the DCfindType command.
323 * @return true if a type was found.
325 virtual bool parseFindType(const char* output
, QString
& type
) = 0;
328 * Parses the output of the DCinforegisters command.
330 virtual void parseRegisters(const char* output
, QList
<RegisterInfo
>& regs
) = 0;
333 /** Removes all commands from the low-priority queue. */
334 void flushLoPriQueue();
335 /** Removes all commands from the high-priority queue. */
336 void flushHiPriQueue();
339 QQueue
<CmdQueueItem
> m_hipriCmdQueue
;
340 QList
<CmdQueueItem
> m_lopriCmdQueue
;
342 * The active command is kept separately from other pending commands.
344 CmdQueueItem
* m_activeCmd
;
346 * Helper function that queues the given command string in the
347 * low-priority queue.
349 CmdQueueItem
* queueCmdString(DbgCommand cmd
, QString cmdString
,
352 * Helper function that queues the given command string in the
353 * high-priority queue.
355 CmdQueueItem
* executeCmdString(DbgCommand cmd
, QString cmdString
,
358 virtual void commandFinished(CmdQueueItem
* cmd
) = 0;
362 virtual int commSetupDoneC();
366 char m_promptLastChar
;
369 QString m_logFileName
;
373 void slotReceiveOutput(KProcess
*, char* buffer
, int buflen
);
374 void slotCommandRead(KProcess
*);
375 void slotExited(KProcess
*);
379 * This signal is emitted when the output of a command has been fully
380 * collected and is ready to be interpreted.
382 void commandReceived(CmdQueueItem
* cmd
, const char* output
);
385 * This signal is emitted when the debugger recognizes that a specific
386 * location in a file ought to be displayed.
388 * Gdb's --fullname option supports this for the step, next, frame, and
389 * run commands (and possibly others).
391 * @param file specifies the file; this is not necessarily a full path
392 * name, and if it is relative, you won't know relative to what, you
394 * @param lineNo specifies the line number (0-based!) (this may be
395 * negative, in which case the file should be activated, but the line
396 * should NOT be changed).
398 void activateFileLine(const QString
& file
, int lineNo
);
401 * This signal is emitted when a command that starts the inferior has
402 * been submitted to the debugger.
404 void inferiorRunning();
407 * This signal is emitted when all output from the debugger has been
408 * consumed and no more commands are in the queues.
410 void enterIdleState();
412 // implementation helpers
414 friend class KDebugger
;
417 #endif // DBGDRIVER_H