3 // Copyright by Johannes Sixt
4 // This file is under GPL, the GNU General Public Licence
11 #include <qstringlist.h>
13 #include "exprwnd.h" /* some compilers require this */
21 class ProgramTypeTable
;
31 struct DisassembledCode
;
37 class KDebugger
: public QObject
41 KDebugger(QWidget
* parent
, /* will be used as the parent for dialogs */
48 * This function starts to debug the specified executable using the
49 * specified driver. If a program is currently being debugged, it is
50 * terminated first. Ownership of driver is taken if and only if
53 * @return false if an error occurs.
55 bool debugProgram(const QString
& executable
,
56 DebuggerDriver
* driver
);
59 * Uses the specified core to debug the active program.
60 * @param batch tells whether the core file was given on the
63 void useCoreFile(QString corefile
, bool batch
);
66 * Attaches to the specified process and debugs it.
68 void attachProgram(const QString
& pid
);
71 * Returns the file name of the per-program config file for the
74 static QString
getConfigForExe(const QString
& exe
);
77 * The driver name entry in the per-program config file.
79 static const char DriverNameEntry
[];
83 * Runs the program or continues it if it is stopped at a breakpoint.
88 * Restarts the debuggee.
90 void programRunAgain();
93 * Performs a single-step, possibly stepping into a function call.
94 * If byInsn is true, a step by instruction is performed.
99 * Performs a single-step, stepping over a function call.
100 * If byInsn is true, a step by instruction is performed.
105 * Performs a single-step by instruction, possibly stepping into a
111 * Performs a single-step by instruction, stepping over a function
117 * Runs the program until it returns from the current function.
119 void programFinish();
122 * Kills the program (removes it from memory).
127 * Interrupts the program if it is currently running.
133 * Queries the user for program arguments.
135 void programArgs(QWidget
* parent
);
138 * Queries the user for program settings: Debugger command, terminal
141 void programSettings(QWidget
* parent
);
144 * Setup remote debugging device
146 void setRemoteDevice(const QString
& remoteDevice
) { m_remoteDevice
= remoteDevice
; }
149 * Run the debuggee until the specified line in the specified file is
152 * @return false if the command was not executed, e.g. because the
153 * debuggee is running at the moment.
155 bool runUntil(const QString
& fileName
, int lineNo
);
160 * @param fileName The source file in which to set the breakpoint.
161 * @param lineNo The zero-based line number.
162 * @param address The exact address of the breakpoint.
163 * @param temporary Specifies whether this is a temporary breakpoint
164 * @return false if the command was not executed, e.g. because the
165 * debuggee is running at the moment.
167 bool setBreakpoint(QString fileName
, int lineNo
,
168 const DbgAddr
& address
, bool temporary
);
171 * Enable or disable a breakpoint at the specified location.
173 * @param fileName The source file in which the breakpoint is.
174 * @param lineNo The zero-based line number.
175 * @param address The exact address of the breakpoint.
176 * @return false if the command was not executed, e.g. because the
177 * debuggee is running at the moment.
179 bool enableDisableBreakpoint(QString fileName
, int lineNo
,
180 const DbgAddr
& address
);
183 * Tells whether one of the single stepping commands can be invoked
184 * (step, next, finish, until, also run).
186 bool canSingleStep();
189 * Tells whether a breakpoints can be set, deleted, enabled, or disabled.
191 bool canChangeBreakpoints();
194 * Tells whether the debuggee can be changed.
196 bool canUseCoreFile() { return isReady() && !m_programActive
; }
199 * Add a watch expression.
201 void addWatch(const QString
& expr
);
204 * Retrieves the current status message.
206 const QString
& statusMessage() const { return m_statusMessage
; }
209 * Is the debugger ready to receive another high-priority command?
211 bool isReady() const;
214 * Is the debuggee running (not just active)?
216 bool isProgramRunning() { return m_haveExecutable
&& m_programRunning
; }
219 * Do we have an executable set?
221 bool haveExecutable() { return m_haveExecutable
; }
224 * Is the debuggee active, i.e. was it started by the debugger?
226 bool isProgramActive() { return m_programActive
; }
229 * Is the debugger driver idle?
233 /** The list of breakpoints. */
234 int numBreakpoints() const { return m_brkpts
.size(); }
235 const Breakpoint
* breakpoint(int i
) const { return m_brkpts
[i
]; }
237 const QString
& executable() const { return m_executable
; }
240 * Terminal emulation level.
243 ttyNone
= 0, /* ignore output, input triggers EOF */
244 ttySimpleOutputOnly
= 1, /* minmal output emulation, input triggers EOF */
245 ttyFull
= 7 /* program needs full emulation */
249 * Returns the level of terminal emulation requested by the inferior.
251 TTYLevel
ttyLevel() const { return m_ttyLevel
; }
253 /** Sets the terminal that is to be used by the debugger. */
254 void setTerminal(const QString
& term
) { m_inferiorTerminal
= term
; }
256 /** Returns the debugger driver. */
257 DebuggerDriver
* driver() { return m_d
; }
259 /** Returns the pid that the debugger is currently attached to. */
260 const QString
& attachedPid() const { return m_attachedPid
; }
263 * The memory at that the expression evaluates to is watched. Can be
264 * empty. Triggers a redisplay even if the expression did not change.
266 void setMemoryExpression(const QString
& memexpr
);
269 * Sets how the watched memory location is displayed.
270 * Call setMemoryExpression() to force a redisplay.
272 void setMemoryFormat(unsigned format
) { m_memoryFormat
= format
; }
275 void saveSettings(KConfig
*);
276 void restoreSettings(KConfig
*);
279 QString m_inferiorTerminal
;
280 QString m_debuggerCmd
; /* per-program setting */
281 TTYLevel m_ttyLevel
; /* level of terminal emulation */
286 QList
<VarTree
> m_watchEvalExpr
; /* exprs to evaluate for watch windows */
287 QArray
<Breakpoint
*> m_brkpts
;
288 QString m_memoryExpression
; /* memory location to watch */
289 unsigned m_memoryFormat
; /* how that output should look */
292 void parse(CmdQueueItem
* cmd
, const char* output
);
294 VarTree
* parseExpr(const char* output
, bool wantErrorValue
);
295 void handleRunCommands(const char* output
);
296 void updateAllExprs();
297 void updateProgEnvironment(const QString
& args
, const QString
& wd
,
298 const QDict
<EnvVar
>& newVars
,
299 const QStringList
& newOptions
);
300 void parseLocals(const char* output
, QList
<VarTree
>& newVars
);
301 void handleLocals(const char* output
);
302 bool handlePrint(CmdQueueItem
* cmd
, const char* output
);
303 void handleBacktrace(const char* output
);
304 void handleFrameChange(const char* output
);
305 void handleFindType(CmdQueueItem
* cmd
, const char* output
);
306 void handlePrintStruct(CmdQueueItem
* cmd
, const char* output
);
307 void handleSharedLibs(const char* output
);
308 void handleRegisters(const char* output
);
309 void handleMemoryDump(const char* output
);
310 void handleInfoLine(CmdQueueItem
* cmd
, const char* output
);
311 void handleDisassemble(CmdQueueItem
* cmd
, const char* output
);
312 void handleThreadList(const char* output
);
313 void evalExpressions();
314 void evalInitialStructExpression(VarTree
* var
, ExprWnd
* wnd
, bool immediate
);
315 void evalStructExpression(VarTree
* var
, ExprWnd
* wnd
, bool immediate
);
316 void exprExpandingHelper(ExprWnd
* wnd
, KTreeViewItem
* item
, bool& allow
);
317 void dereferencePointer(ExprWnd
* wnd
, VarTree
* var
, bool immediate
);
318 void determineType(ExprWnd
* wnd
, VarTree
* var
);
319 void removeExpr(ExprWnd
* wnd
, VarTree
* var
);
320 void queueMemoryDump(bool immediate
);
321 CmdQueueItem
* loadCoreFile();
322 void openProgramConfig(const QString
& name
);
324 Breakpoint
* breakpointByFilePos(QString file
, int lineNo
,
325 const DbgAddr
& address
);
326 void newBreakpoint(const char* output
);
327 void updateBreakList(const char* output
);
328 bool stopMayChangeBreakList() const;
329 void saveBreakpoints(KSimpleConfig
* config
);
330 void restoreBreakpoints(KSimpleConfig
* config
);
332 bool m_haveExecutable
; /* has an executable been specified */
333 bool m_programActive
; /* is the program active (possibly halting in a brkpt)? */
334 bool m_programRunning
; /* is the program executing (not stopped)? */
335 bool m_sharedLibsListed
; /* do we know the shared libraries loaded by the prog? */
336 QString m_executable
;
338 QString m_attachedPid
; /* user input of attaching to pid */
339 QString m_programArgs
;
340 QString m_remoteDevice
;
341 QString m_programWD
; /* working directory of gdb */
342 QDict
<EnvVar
> m_envVars
; /* environment variables set by user */
343 QStringList m_boolOptions
; /* boolean options */
344 QStrList m_sharedLibs
; /* shared libraries used by program */
345 ProgramTypeTable
* m_typeTable
; /* known types used by the program */
346 KSimpleConfig
* m_programConfig
; /* program-specific settings (brkpts etc) */
347 void saveProgramSettings();
348 void restoreProgramSettings();
352 bool m_explicitKill
; /* whether we are killing gdb ourselves */
354 QString m_statusMessage
;
357 void gdbExited(KProcess
*);
358 void slotInferiorRunning();
359 void backgroundUpdate();
361 void slotLocalsExpanding(KTreeViewItem
*, bool&);
362 void slotWatchExpanding(KTreeViewItem
*, bool&);
363 void slotUpdateAnimation();
364 void slotDeleteWatch();
365 void slotValuePopup(const QString
&);
366 void slotDisassemble(const QString
&, int);
373 * This signal is emitted before the debugger is started. The slot is
374 * supposed to set up m_inferiorTerminal.
376 void debuggerStarting();
379 * This signal is emitted whenever a part of the debugger needs to
380 * highlight the specfied source code line (e.g. when the program
383 * @param file specifies the file; this is not necessarily a full path
384 * name, and if it is relative, you won't know relative to what, you
386 * @param lineNo specifies the line number (0-based!) (this may be
387 * negative, in which case the file should be activated, but the line
388 * should NOT be changed).
389 * @param address specifies the exact address of the PC or is empty.
391 void activateFileLine(const QString
& file
, int lineNo
, const DbgAddr
& address
);
394 * This signal is emitted when a line decoration item (those thingies
395 * that indicate breakpoints) must be changed.
397 void lineItemsChanged();
400 * This signal is a special case of @ref #lineItemsChanged because it
401 * indicates that only the program counter has changed.
403 * @param filename specifies the filename where the program stopped
404 * @param lineNo specifies the line number (zero-based); it can be -1
406 * @param address specifies the address that the instruction pointer
408 * @param frameNo specifies the frame number: 0 is the innermost frame,
409 * positive numbers are frames somewhere up the stack (indicates points
410 * where a function was called); the latter cases should be indicated
411 * differently in the source window.
413 void updatePC(const QString
& filename
, int lineNo
,
414 const DbgAddr
& address
, int frameNo
);
417 * This signal is emitted when gdb detects that the executable has been
418 * updated, e.g. recompiled. (You usually need not handle this signal
419 * if you are the editor which changed the executable.)
421 void executableUpdated();
424 * This signal is emitted when the animated icon should advance to the
427 void animationTimeout();
430 * Indicates that a new status message is available.
432 void updateStatusMessage();
435 * Indicates that the internal state of the debugger has changed, and
436 * that this will very likely have an impact on the UI.
441 * Indicates that the list of breakpoints has possibly changed.
443 void breakpointsChanged();
446 * Indicates that the register values have possibly changed.
448 void registersChanged(QList
<RegisterInfo
>&);
451 * Indicates that the list of threads has possibly changed.
453 void threadsChanged(QList
<ThreadInfo
>&);
456 * Indicates that the value for a value popup is ready.
458 void valuePopup(const QString
&);
461 * Provides the disassembled code of the location given by file and
462 * line number (zero-based).
464 void disassembled(const QString
& file
, int line
, const QList
<DisassembledCode
>& code
);
467 * Indicates that the program has stopped for any reason: by a
468 * breakpoint, by a signal that the debugger driver caught, by a single
471 void programStopped();
474 * Indicates that a new memory dump output is ready.
475 * @param msg is an error message or empty
476 * @param memdump is the memory dump
478 void memoryDumpChanged(const QString
&, QList
<MemoryDump
>&);
481 * Gives other objects a chance to save program specific settings.
483 void saveProgramSpecific(KSimpleConfig
* config
);
486 * Gives other objects a chance to restore program specific settings.
488 void restoreProgramSpecific(KSimpleConfig
* config
);
491 ExprWnd
& m_localVariables
;
492 ExprWnd
& m_watchVariables
;
493 QListBox
& m_btWindow
;
496 QTimer m_animationTimer
;
497 int m_animationInterval
;
499 // implementation helpers
501 void startAnimation(bool fast
);
502 void stopAnimation();
504 QWidget
* parentWidget() { return static_cast<QWidget
*>(parent()); }
506 friend class BreakpointTable
;