Added Spanish translations.
[kdbg.git] / kdbg / debugger.h
blobc40927d8c1869a0a83362f5ef0eb8b6d2c3f9d4f
1 // $Id$
3 // Copyright by Johannes Sixt
4 // This file is under GPL, the GNU General Public Licence
6 #ifndef DEBUGGER_H
7 #define DEBUGGER_H
9 #include <qqueue.h>
10 #include <qtimer.h>
11 #include <qfile.h>
12 #include <kprocess.h>
13 #include "brkpt.h"
14 #include "envvar.h"
15 #include "exprwnd.h" /* some compilers require this */
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
21 class ExprWnd;
22 class VarTree;
23 class ProgramTypeTable;
24 class KTreeViewItem;
25 class KConfig;
26 class QListBox;
29 class GdbProcess : public KProcess
31 public:
32 GdbProcess();
33 protected:
34 virtual int commSetupDoneC();
37 class KDebugger : public QObject
39 Q_OBJECT
40 public:
41 KDebugger(QWidget* parent, /* will be used as the parent for dialogs */
42 ExprWnd* localVars,
43 ExprWnd* watchVars,
44 QListBox* backtrace
46 ~KDebugger();
48 /**
49 * This function starts to debug the specified executable.
50 * @return false if an error occurs, in particular if a program is
51 * currently being debugged
53 bool debugProgram(const QString& executable);
55 /**
56 * Queries the user for an executable file and debugs it. If a program
57 * is currently being debugged, it is terminated first.
59 void fileExecutable();
61 /**
62 * Queries the user for a core file and uses it to debug the active
63 * program
65 void fileCoreFile();
67 /**
68 * Runs the program or continues it if it is stopped at a breakpoint.
70 void programRun();
72 /**
73 * Attaches to a process and debugs it.
75 void programAttach();
77 /**
78 * Restarts the debuggee.
80 void programRunAgain();
82 /**
83 * Performs a single-step, possibly stepping into a function call.
85 void programStep();
87 /**
88 * Performs a single-step, stepping over a function call.
90 void programNext();
92 /**
93 * Runs the program until it returns from the current function.
95 void programFinish();
97 /**
98 * Interrupts the program if it is currently running.
100 void programBreak();
103 * Queries the user for program arguments.
105 void programArgs();
108 * Shows the breakpoint list if it isn't currently visible or hides it
109 * if it is.
111 void breakListToggleVisible();
114 * Run the debuggee until the specified line in the specified file is
115 * reached.
117 * @return false if the command was not executed, e.g. because the
118 * debuggee is running at the moment.
120 bool runUntil(const QString& fileName, int lineNo);
123 * Set a breakpoint.
125 * @return false if the command was not executed, e.g. because the
126 * debuggee is running at the moment.
128 bool setBreakpoint(const QString& fileName, int lineNo, bool temporary);
131 * Enable or disable a breakpoint at the specified location.
133 * @return false if the command was not executed, e.g. because the
134 * debuggee is running at the moment.
136 bool enableDisableBreakpoint(const QString& fileName, int lineNo);
139 * Tells whether one of the single stepping commands can be invoked
140 * (step, next, finish, until, also run).
142 bool canSingleStep();
145 * Tells whether a breakpoints can be set, deleted, enabled, or disabled.
147 bool canChangeBreakpoints();
150 * Tells whether the debuggee can be changed.
152 bool canChangeExecutable() { return isReady() && !m_programActive; }
155 * Add a watch expression.
157 void addWatch(const QString& expr);
160 * Retrieves the current status message.
162 const QString& statusMessage() const { return m_statusMessage; }
164 * Is the debugger ready to receive another high-priority command?
166 bool isReady() const { return m_haveExecutable &&
167 /*(m_state == DSidle || m_state == DSrunningLow)*/
168 m_hipriCmdQueue.isEmpty(); }
170 * Is the debuggee running (not just active)?
172 bool isProgramRunning() { return m_haveExecutable && m_programRunning; }
175 * Do we have an executable set?
177 bool haveExecutable() { return m_haveExecutable; }
180 * Is the debuggee active, i.e. was it started by the debugger?
182 bool isProgramActive() { return m_programActive; }
184 /** Is the breakpoint table visible? */
185 bool isBreakListVisible() { return m_bpTable.isVisible(); }
187 /** The table of breakpoints. */
188 BreakpointTable& breakList() { return m_bpTable; }
190 const QString& executable() const { return m_executable; }
192 void setCoreFile(const QString& corefile) { m_corefile = corefile; }
195 * Sets the command to invoke gdb. If cmd is the empty string, the
196 * default is substituted.
198 void setDebuggerCmd(const QString& cmd);
200 /** Retrieves the command to invoke gdb. */
201 QString debuggerCmd() const { return m_debuggerCmdStr; }
204 * Sets the command to invoke the terminal that displays the program
205 * output. If cmd is the empty string, the default is substituted.
207 void setTerminalCmd(const QString& cmd);
210 * Retrieves the command to invoke ther terminal that displays the
211 * program output.
213 QString terminalCmd() const { return m_outputTermCmdStr; }
215 // settings
216 void saveSettings(KConfig*);
217 void restoreSettings(KConfig*);
219 public:
220 // debugger driver
221 enum DbgCommand {
222 DCinitialize,
223 DCinitialSet,
224 DCexecutable,
225 DCcorefile,
226 DCattach,
227 DCinfolinemain,
228 DCinfolocals,
229 DCsetargs,
230 DCsetenv,
231 DCcd,
232 DCbt,
233 DCrun,
234 DCcont,
235 DCstep,
236 DCnext,
237 DCfinish,
238 DCuntil,
239 DCbreak,
240 DCdelete,
241 DCenable,
242 DCdisable,
243 DCprint,
244 DCprintStruct,
245 DCprintQStringStruct,
246 DCframe,
247 DCfindType,
248 DCinfosharedlib,
249 DCinfobreak,
250 DCcondition,
251 DCignore
253 protected:
254 QString m_outputTermCmdStr;
255 pid_t m_outputTermPID;
256 QString m_outputTermName;
257 QString m_outputTermKeepScript;
258 bool createOutputWindow();
259 QString m_debuggerCmdStr;
260 bool startGdb();
261 void stopGdb();
262 void writeCommand();
264 enum DebuggerState {
265 DSidle, /* gdb waits for input */
266 DSinterrupted, /* a command was interrupted */
267 DSrunningLow, /* gdb is running a low-priority command */
268 DSrunning, /* gdb waits for program */
269 DScommandSent, /* command has been sent, we wait for wroteStdin signal */
270 DScommandSentLow, /* low-prioritycommand has been sent */
272 DebuggerState m_state;
273 char* m_gdbOutput; /* normal gdb output */
274 int m_gdbOutputLen; /* current accumulated output */
275 int m_gdbOutputAlloc; /* space available in m_gdbOutput */
276 QQueue<QString> m_delayedOutput; /* output colleced while we have receivedOutput */
277 /* but before signal wroteStdin arrived */
278 QList<VarTree> m_watchEvalExpr; /* exprs to evaluate for watch windows */
280 public:
282 * Gdb commands are placed in a queue. Only one command at a time is
283 * sent down to gdb. All other commands in the queue are retained until
284 * the sent command has been processed by gdb. Gdb tells us that it's
285 * done with the command by sending the prompt. The output of gdb is
286 * parsed at that time. Then, if more commands are in the queue, the
287 * next one is sent to gdb.
289 * The active command is kept separately from other pending commands.
291 struct CmdQueueItem
293 DbgCommand m_cmd;
294 QString m_cmdString;
295 bool m_committed; /* just a debugging aid */
296 // remember which expression when printing an expression
297 VarTree* m_expr;
298 ExprWnd* m_exprWnd;
299 // whether command was emitted due to direct user request (only set when relevant)
300 bool m_byUser;
302 CmdQueueItem(DbgCommand cmd, const QString& str) :
303 m_cmd(cmd),
304 m_cmdString(str),
305 m_committed(false),
306 m_expr(0),
307 m_exprWnd(0),
308 m_byUser(false)
312 * Enqueues a high-priority command. High-priority commands are
313 * executed before any low-priority commands. No user interaction is
314 * possible as long as there is a high-priority command in the queue.
316 CmdQueueItem* executeCmd(DbgCommand cmd, QString cmdString, bool clearLow = false);
317 enum QueueMode {
318 QMnormal, /* queues the command last */
319 QMoverride, /* removes an already queued command */
320 QMoverrideMoreEqual /* ditto, also puts the command first in the queue */
323 * Enqueues a low-priority command. Low-priority commands are executed
324 * after any high-priority commands.
326 CmdQueueItem* queueCmd(DbgCommand cmd, QString cmdString, QueueMode mode);
327 /** Removes all commands from the low-priority queue. */
328 void flushLoPriQueue();
329 /** Removes all commands from the high-priority queue. */
330 void flushHiPriQueue();
332 protected:
333 QQueue<CmdQueueItem> m_hipriCmdQueue;
334 QList<CmdQueueItem> m_lopriCmdQueue;
335 CmdQueueItem* m_activeCmd; /* the cmd we are working on */
336 void parse(CmdQueueItem* cmd);
337 VarTree* parseExpr(const char* name, bool wantErrorValue = true);
338 VarTree* parseQCharArray(const char* name, bool wantErrorValue);
339 void handleRunCommands();
340 void updateAllExprs();
341 void updateBreakptTable();
342 void updateProgEnvironment(const QString& args, const QString& wd,
343 const QDict<EnvVar>& newVars);
344 void parseLocals(QList<VarTree>& newVars);
345 void handleLocals();
346 bool handlePrint(CmdQueueItem* cmd);
347 void handleBacktrace();
348 void handleFrameChange();
349 void handleFindType(CmdQueueItem* cmd);
350 void handlePrintStruct(CmdQueueItem* cmd);
351 void handleSharedLibs();
352 void evalExpressions();
353 void evalInitialStructExpression(VarTree* var, ExprWnd* wnd, bool immediate);
354 void evalStructExpression(VarTree* var, ExprWnd* wnd, bool immediate);
355 void exprExpandingHelper(ExprWnd* wnd, KTreeViewItem* item, bool& allow);
356 void dereferencePointer(ExprWnd* wnd, VarTree* var, bool immediate);
357 void determineType(ExprWnd* wnd, VarTree* var);
358 void removeExpr(ExprWnd* wnd, VarTree* var);
359 CmdQueueItem* loadCoreFile();
361 QString m_lastDirectory; /* the dir of the most recently opened file */
362 bool m_haveExecutable; /* has an executable been specified */
363 bool m_programActive; /* is the program active (possibly halting in a brkpt)? */
364 bool m_programRunning; /* is the program executing (not stopped)? */
365 bool m_sharedLibsListed; /* do we know the shared libraries loaded by the prog? */
366 QString m_executable;
367 QString m_corefile;
368 QString m_attachedPid; /* user input of attaching to pid */
369 QString m_programArgs;
370 QString m_programWD; /* working directory of gdb */
371 QDict<EnvVar> m_envVars; /* environment variables set by user */
372 QStrList m_sharedLibs; /* shared libraries used by program */
373 ProgramTypeTable* m_typeTable; /* known types used by the program */
374 bool m_qstring2nullOk; /* whether gdb knows about QString::null */
375 KSimpleConfig* m_programConfig; /* program-specific settings (brkpts etc) */
376 void saveProgramSettings();
377 void restoreProgramSettings();
379 // debugger process
380 GdbProcess m_gdb;
381 int m_gdbMajor, m_gdbMinor;
382 bool m_explicitKill; /* whether we are killing gdb ourselves */
384 #ifdef GDB_TRANSCRIPT
385 // log file
386 QFile m_logFile;
387 #endif
389 QString m_statusMessage;
391 protected slots:
392 void receiveOutput(KProcess*, char* buffer, int buflen);
393 void commandRead(KProcess*);
394 void gdbExited(KProcess*);
395 void gotoFrame(int);
396 void slotLocalsExpanding(KTreeViewItem*, bool&);
397 void slotWatchExpanding(KTreeViewItem*, bool&);
398 void slotToggleBreak(const QString&, int);
399 void slotEnaDisBreak(const QString&, int);
400 void slotUpdateAnimation();
401 void slotDeleteWatch();
403 signals:
405 * This signal is emitted whenever a part of the debugger needs to
406 * highlight the specfied source code line (e.g. when the program
407 * stops).
409 * @param file specifies the file; this is not necessarily a full path
410 * name, and if it is relative, you won't know relative to what, you
411 * can only guess.
412 * @param lineNo specifies the line number (0-based!) (this may be
413 * negative, in which case the file should be activated, but the line
414 * should NOT be changed).
416 void activateFileLine(const QString& file, int lineNo);
419 * This signal is emitted when a line decoration item (those thingies
420 * that indicate breakpoints) must be changed.
422 void lineItemsChanged();
425 * This signal is a special case of @ref #lineItemsChanged because it
426 * indicates that only the program counter has changed.
428 * @param filename specifies the filename where the program stopped
429 * @param lineNo specifies the line number (zero-based); it can be -1
430 * if it is unknown
431 * @param frameNo specifies the frame number: 0 is the innermost frame,
432 * positive numbers are frames somewhere up the stack (indicates points
433 * where a function was called); the latter cases should be indicated
434 * differently in the source window.
436 void updatePC(const QString& filename, int lineNo, int frameNo);
439 * This signal is emitted when gdb detects that the executable has been
440 * updated, e.g. recompiled. (You usually need not handle this signal
441 * if you are the editor which changed the executable.)
443 void executableUpdated();
446 * This signal is emitted when the animated icon should advance to the
447 * next picture.
449 void animationTimeout();
452 * Indicates that a new status message is available.
454 void updateStatusMessage();
457 * Indicates that the internal state of the debugger has changed, and
458 * that this will very likely have an impact on the UI.
460 void updateUI();
462 protected:
463 BreakpointTable m_bpTable;
464 ExprWnd& m_localVariables;
465 ExprWnd& m_watchVariables;
466 QListBox& m_btWindow;
468 // animation
469 QTimer m_animationTimer;
470 int m_animationInterval;
472 // implementation helpers
473 protected:
474 void initMenu();
475 void initToolbar();
476 void initAnimation();
477 void startAnimation(bool fast);
478 void stopAnimation();
480 QWidget* parentWidget() { return static_cast<QWidget*>(parent()); }
482 friend class BreakpointTable;
485 #endif // DEBUGGER_H