1 /*
2  * Copyright Johannes Sixt
3  * This file is licensed under the GNU General Public License Version 2.
4  * See the file COPYING in the toplevel directory of the source directory.
5  */
6 
7 #ifndef DEBUGGER_H
8 #define DEBUGGER_H
9 
10 #include <QSet>
11 #include <QStringList>
12 #include <list>
13 #include <map>
14 #include "envvar.h"
15 #include "exprwnd.h"			/* some compilers require this */
16 
17 class ExprWnd;
18 class VarTree;
19 struct ExprValue;
20 class ProgramTypeTable;
21 class KTreeViewItem;
22 class KConfig;
23 class KConfigBase;
24 class KConfigGroup;
25 class QListWidget;
26 class RegisterInfo;
27 class ThreadInfo;
28 class DebuggerDriver;
29 class CmdQueueItem;
30 class Breakpoint;
31 struct DisassembledCode;
32 struct MemoryDump;
33 struct DbgAddr;
34 
35 
36 class KDebugger : public QObject
37 {
38     Q_OBJECT
39 public:
40     KDebugger(QWidget* parent,		/* will be used as the parent for dialogs */
41 	      ExprWnd* localVars,
42 	      ExprWnd* watchVars,
43 	      QListWidget* backtrace);
44     ~KDebugger();
45 
46     /**
47      * This function starts to debug the specified executable using the
48      * specified driver. If a program is currently being debugged, it is
49      * terminated first. Ownership of driver is taken if and only if
50      * true is returned.
51      *
52      * @return false if an error occurs.
53      */
54     bool debugProgram(const QString& executable,
55 		      DebuggerDriver* driver);
56 
57     /**
58      * Uses the specified core to debug the active program.
59      * @param batch tells whether the core file was given on the
60      * command line.
61      */
62     void useCoreFile(QString corefile, bool batch);
63 
64     /**
65      * Overrides the program argument in the per-program config
66      * with a new value.
67      */
68     void overrideProgramArguments(const QString& args);
69 
70 
71     /**
72      * Uses the specified pid to attach to the active program.
73      */
74     void setAttachPid(const QString& pid);
75 
76     /**
77      * Attaches to the specified process and debugs it.
78      */
79     void attachProgram(const QString& pid);
80 
81     /**
82      * Returns the file name of the per-program config file for the
83      * specified program.
84      */
85     static QString getConfigForExe(const QString& exe);
86 
87     /**
88      * The driver name entry in the per-program config file.
89      */
90     static const char DriverNameEntry[];
91 
92 public slots:
93     /**
94      * Runs the program or continues it if it is stopped at a breakpoint.
95      */
96     void programRun();
97 
98     /**
99      * Restarts the debuggee.
100      */
101     void programRunAgain();
102 
103     /**
104      * Performs a single-step, possibly stepping into a function call.
105      * If byInsn is true, a step by instruction is performed.
106      */
107     void programStep();
108 
109     /**
110      * Performs a single-step, stepping over a function call.
111      * If byInsn is true, a step by instruction is performed.
112      */
113     void programNext();
114 
115     /**
116      * Performs a single-step by instruction, possibly stepping into a
117      * function call.
118      */
119     void programStepi();
120 
121     /**
122      * Performs a single-step by instruction, stepping over a function
123      * call.
124      */
125     void programNexti();
126 
127     /**
128      * Runs the program until it returns from the current function.
129      */
130     void programFinish();
131 
132     /**
133      * Kills the program (removes it from memory).
134      */
135     void programKill();
136 
137     /**
138      * Detach the program (continues exection outside debugger).
139      */
140     void programDetach();
141 
142     /**
143      * Interrupts the program if it is currently running.
144      */
145     void programBreak();
146 
147     /**
148      * Moves the program counter to the specified line.
149      * If an address is given, it is moved to the address.
150      */
151     void setProgramCounter(const QString&, int, const DbgAddr&);
152 
153 public:
154     /**
155      * Queries the user for program arguments.
156      */
157     void programArgs(QWidget* parent);
158 
159     /**
160      * Queries the user for program settings: Debugger command, terminal
161      * emulator.
162      */
163     void programSettings(QWidget* parent);
164 
165     /**
166      * Setup remote debugging device
167      */
setRemoteDevice(const QString & remoteDevice)168     void setRemoteDevice(const QString& remoteDevice) { m_remoteDevice = remoteDevice; }
169 
170     /**
171      * Run the debuggee until the specified line in the specified file is
172      * reached.
173      *
174      * @return false if the command was not executed, e.g. because the
175      * debuggee is running at the moment.
176      */
177     bool runUntil(const QString& fileName, int lineNo);
178 
179     /**
180      * Ask debugger for information about the specified line in the specified file.
181      *
182      * If \a addr is given, then it is used as a hint to position
183      * to position the cursor in the source window at that address
184      * if it belongs to the specified line.
185      * @param fileName The source file in which to set the breakpoint.
186      * @param lineNo The zero-based line number.
187      * @param addr An address that belongs to the name; can be empty.
188      * @return false if the command was not executed, e.g. because the
189      * debuggee is running at the moment.
190      */
191     bool infoLine(QString fileName, int lineNo, const DbgAddr& addr);
192     /**
193      * Set a breakpoint.
194      *
195      * @param fileName The source file in which to set the breakpoint.
196      * @param lineNo The zero-based line number.
197      * @param address The exact address of the breakpoint.
198      * @param temporary Specifies whether this is a temporary breakpoint
199      * @return false if the command was not executed, e.g. because the
200      * debuggee is running at the moment.
201      */
202     bool setBreakpoint(QString fileName, int lineNo,
203 		       const DbgAddr& address, bool temporary);
204 
205     /**
206      * Set a breakpoint.
207      *
208      * @param bp Describes the breakpoint.
209      * @param queueOnly If false, the breakpoint is set using a high-priority command.
210      */
211     void setBreakpoint(Breakpoint* bp, bool queueOnly);
212 
213     /**
214      * Enable or disable a breakpoint at the specified location.
215      *
216      * @param fileName The source file in which the breakpoint is.
217      * @param lineNo The zero-based line number.
218      * @param address The exact address of the breakpoint.
219      * @return false if the command was not executed, e.g. because the
220      * debuggee is running at the moment.
221      */
222     bool enableDisableBreakpoint(QString fileName, int lineNo,
223 				 const DbgAddr& address);
224 
225     /**
226      * Enables or disables the specified breakpoint.
227      *
228      * @return false if the command was not executed, e.g. because the
229      * debuggee is running at the moment.
230      */
enableDisableBreakpoint(int id)231     bool enableDisableBreakpoint(int id)
232     { return enableDisableBreakpoint(breakpointById(id)); }
233 
234     /**
235      * Removes the specified breakpoint. Note that if bp is an orphaned
236      * breakpoint, then bp is an invalid pointer if (and only if) this
237      * function returns true.
238      *
239      * @return false if the command was not executed, e.g. because the
240      * debuggee is running at the moment.
241      */
deleteBreakpoint(int id)242     bool deleteBreakpoint(int id)
243     { return deleteBreakpoint(breakpointById(id)); }
244 
245     /**
246      * Changes the specified breakpoint's condition and ignore count.
247      *
248      * @return false if the command was not executed, e.g. because the
249      * debuggee is running at the moment.
250      */
conditionalBreakpoint(int id,const QString & condition,int ignoreCount)251     bool conditionalBreakpoint(int id,
252 			       const QString& condition,
253 			       int ignoreCount)
254     { return conditionalBreakpoint(breakpointById(id), condition, ignoreCount); }
255 
256     /**
257      * Tells whether one of the single stepping commands can be invoked
258      * (step, next, finish, until, also run).
259      */
260     bool canSingleStep();
261 
262     /**
263      * Tells whether a breakpoints can be set, deleted, enabled, or disabled.
264      */
265     bool canChangeBreakpoints();
266 
267     /**
268      * Tells whether a the program is loaded, but not active.
269      */
270     bool canStart();
271 
272     /**
273      * Add a watch expression.
274      */
275     void addWatch(const QString& expr);
276 
277     /**
278      * Retrieves the current status message.
279      */
statusMessage()280     const QString& statusMessage() const { return m_statusMessage; }
281 
282     /**
283      * Is the debugger ready to receive another high-priority command?
284      */
285     bool isReady() const;
286 
287     /**
288      * Is the debuggee running (not just active)?
289      */
isProgramRunning()290     bool isProgramRunning() { return m_haveExecutable && m_programRunning; }
291 
292     /**
293      * Do we have an executable set?
294      */
haveExecutable()295     bool haveExecutable() { return m_haveExecutable; }
296 
297     /**
298      * Is the debuggee active, i.e. was it started by the debugger?
299      */
isProgramActive()300     bool isProgramActive() { return m_programActive; }
301 
302     /**
303      * Is the debugger driver idle?
304      */
305     bool isIdle() const;
306 
307     /* The list of breakpoints. */
308     typedef std::list<Breakpoint>::const_iterator BrkptROIterator;
breakpointsBegin()309     BrkptROIterator breakpointsBegin() const { return m_brkpts.begin(); }
breakpointsEnd()310     BrkptROIterator breakpointsEnd() const { return m_brkpts.end(); }
311 
executable()312     const QString& executable() const { return m_executable; }
313 
314     /**
315      * Terminal emulation level.
316      */
317     enum TTYLevel {
318 	ttyNone = 0,			/* ignore output, input triggers EOF */
319 	ttySimpleOutputOnly = 1,	/* minmal output emulation, input triggers EOF */
320 	ttyFull = 7			/* program needs full emulation */
321     };
322 
323     /**
324      * Returns the level of terminal emulation requested by the inferior.
325      */
ttyLevel()326     TTYLevel ttyLevel() const { return m_ttyLevel; }
327 
328     /** Sets the terminal that is to be used by the debugger. */
setTerminal(const QString & term)329     void setTerminal(const QString& term) { m_inferiorTerminal = term; }
330 
331     /** Returns the debugger driver. */
driver()332     DebuggerDriver* driver() { return m_d; }
333 
334     /** Returns the pid that the debugger is currently attached to. */
attachedPid()335     const QString& attachedPid() const { return m_attachedPid; }
336 
337     /**
338      * The memory at that the expression evaluates to is watched. Can be
339      * empty. Triggers a redisplay even if the expression did not change.
340      * Memory expression start and total length is used to update all bytes of memory when
341      * is necessary, to request new parts of memory is used current_memexpr and current_length
342      */
343     void setMemoryExpression(const QString& start_memexpr, unsigned total_length,
344             const QString& current_memexpr, unsigned current_length);
345 
346     /**
347      * Sets how the watched memory location is displayed.
348      * Call setMemoryExpression() to force a redisplay.
349      */
setMemoryFormat(unsigned format)350     void setMemoryFormat(unsigned format) { m_memoryFormat = format; }
351 
352     // settings
353     void saveSettings(KConfig*);
354     void restoreSettings(KConfig*);
355 
356 protected:
357     QString m_inferiorTerminal;
358     QString m_debuggerCmd;		/* per-program setting */
359     TTYLevel m_ttyLevel;		/* level of terminal emulation */
360     bool startDriver();
361     void stopDriver();
362     void writeCommand();
363 
364     std::list<QString> m_watchEvalExpr;	/* exprs to evaluate for watch window */
365     std::list<Breakpoint> m_brkpts;
366     QString m_memoryExpression;		/* memory location to watch */
367     unsigned m_memoryFormat;		/* how that output should look */
368     unsigned m_memoryLength;         /* memory length to watch */
369     QString m_memoryStartExpression; /* start memory location to watch */
370     unsigned m_memoryTotalLength;    /* memory total length to watch */
371 
372 protected slots:
373     void parse(CmdQueueItem* cmd, const char* output);
374 protected:
375     void handleRunCommands(const char* output);
376     void updateAllExprs();
377     void updateProgEnvironment(const QString& args, const QString& wd,
378 			       const std::map<QString,EnvVar>& newVars,
379 			       const QSet<QString>& newOptions);
380     void parseLocals(const char* output, std::list<ExprValue*>& newVars);
381     void handleLocals(const char* output);
382     bool handlePrint(CmdQueueItem* cmd, const char* output);
383     bool handlePrintPopup(CmdQueueItem* cmd, const char* output);
384     bool handlePrintDeref(CmdQueueItem* cmd, const char* output);
385     void handleBacktrace(const char* output);
386     void handleFrameChange(const char* output);
387     void handleFindType(CmdQueueItem* cmd, const char* output);
388     void handlePrintStruct(CmdQueueItem* cmd, const char* output);
389     void handleSharedLibs(const char* output);
390     void handleRegisters(const char* output);
391     void handleMemoryDump(const char* output);
392     void handleInfoLine(CmdQueueItem* cmd, const char* output);
393     void handleDisassemble(CmdQueueItem* cmd, const char* output);
394     void handleThreadList(const char* output);
395     void handleSetPC(const char* output);
396     void handleSetVariable(CmdQueueItem* cmd, const char* output);
397     void evalExpressions();
398     void evalInitialStructExpression(VarTree* var, ExprWnd* wnd, bool immediate);
399     void evalStructExpression(VarTree* var, ExprWnd* wnd, bool immediate);
400     void dereferencePointer(ExprWnd* wnd, VarTree* var, bool immediate);
401     void determineType(ExprWnd* wnd, VarTree* var);
402     void queueMemoryDump(bool immediate, bool update);
403     CmdQueueItem* loadCoreFile();
404     void openProgramConfig(const QString& name);
405 
406     typedef std::list<Breakpoint>::iterator BrkptIterator;
407     BrkptIterator breakpointByFilePos(QString file, int lineNo,
408 				    const DbgAddr& address);
409     BrkptIterator breakpointById(int id);
410     CmdQueueItem* executeBreakpoint(const Breakpoint* bp, bool queueOnly);
411     void newBreakpoint(CmdQueueItem* cmd, const char* output);
412     void updateBreakList(const char* output);
413     bool stopMayChangeBreakList() const;
414     void saveBreakpoints(KConfig* config);
415     void restoreBreakpoints(KConfig* config);
416     bool enableDisableBreakpoint(BrkptIterator bp);
417     bool deleteBreakpoint(BrkptIterator bp);
418     bool conditionalBreakpoint(BrkptIterator bp,
419 			       const QString& condition,
420 			       int ignoreCount);
421 
422     bool m_haveExecutable;		/* has an executable been specified */
423     bool m_programActive;		/* is the program active (possibly halting in a brkpt)? */
424     bool m_programRunning;		/* is the program executing (not stopped)? */
425     bool m_sharedLibsListed;		/* do we know the shared libraries loaded by the prog? */
426     QString m_executable;
427     QString m_corefile;
428     QString m_attachedPid;		/* user input of attaching to pid */
429     QString m_programArgs;
430     QString m_remoteDevice;
431     QString m_programWD;		/* working directory of gdb */
432     std::map<QString,QString> m_envVars;	/* environment variables set by user */
433     QSet<QString> m_boolOptions;	/* boolean options */
434     QStringList m_sharedLibs;		/* shared libraries used by program */
435     ProgramTypeTable* m_typeTable;	/* known types used by the program */
436     KConfig* m_programConfig;		/* program-specific settings (brkpts etc) */
437     void saveProgramSettings();
438     void restoreProgramSettings();
439     QString readDebuggerCmd(const KConfigGroup& g);
440 
441     // debugger process
442     DebuggerDriver* m_d;
443     bool m_explicitKill;		/* whether we are killing gdb ourselves */
444 
445     QString m_statusMessage;
446 
447 protected slots:
448     void gdbExited();
449     void slotInferiorRunning();
450     void backgroundUpdate();
451     void gotoFrame(int);
452     void slotExpanding(QTreeWidgetItem*);
453     void slotDeleteWatch();
454     void slotValuePopup(const QString&);
455     void slotDisassemble(const QString&, int);
456     void slotValueEdited(VarTree*, const QString&);
457 public slots:
458     void setThread(int);
459     void shutdown();
460 
461 signals:
462     /**
463      * This signal is emitted before the debugger is started. The slot is
464      * supposed to set up m_inferiorTerminal.
465      */
466     void debuggerStarting();
467 
468     /**
469      * This signal is emitted whenever a part of the debugger needs to
470      * highlight the specfied source code line (e.g. when the program
471      * stops).
472      *
473      * @param file specifies the file; this is not necessarily a full path
474      * name, and if it is relative, you won't know relative to what, you
475      * can only guess.
476      * @param lineNo specifies the line number (0-based!) (this may be
477      * negative, in which case the file should be activated, but the line
478      * should NOT be changed).
479      * @param address specifies the exact address of the PC or is empty.
480      */
481     void activateFileLine(const QString& file, int lineNo, const DbgAddr& address);
482 
483     /**
484      * This signal indicates that the program counter has changed.
485      *
486      * @param filename specifies the filename where the program stopped
487      * @param lineNo specifies the line number (zero-based); it can be -1
488      * if it is unknown
489      * @param address specifies the address that the instruction pointer
490      * points to.
491      * @param frameNo specifies the frame number: 0 is the innermost frame,
492      * positive numbers are frames somewhere up the stack (indicates points
493      * where a function was called); the latter cases should be indicated
494      * differently in the source window.
495      */
496     void updatePC(const QString& filename, int lineNo,
497 		  const DbgAddr& address, int frameNo);
498 
499     /**
500      * This signal is emitted when gdb detects that the executable has been
501      * updated, e.g. recompiled. (You usually need not handle this signal
502      * if you are the editor which changed the executable.)
503      */
504     void executableUpdated();
505 
506     /**
507      * Indicates that a new status message is available.
508      */
509     void updateStatusMessage();
510 
511     /**
512      * Indicates that the internal state of the debugger has changed, and
513      * that this will very likely have an impact on the UI.
514      */
515     void updateUI();
516 
517     /**
518      * Indicates that the list of breakpoints has possibly changed.
519      */
520     void breakpointsChanged();
521 
522     /**
523      * Indicates that the register values have possibly changed.
524      */
525     void registersChanged(const std::list<RegisterInfo>&);
526 
527     /**
528      * Indicates that the list of threads has possibly changed.
529      */
530     void threadsChanged(const std::list<ThreadInfo>&);
531 
532     /**
533      * Indicates that the value for a value popup is ready.
534      */
535     void valuePopup(const QString&);
536 
537     /**
538      * Provides the disassembled code of the location given by file and
539      * line number (zero-based).
540      */
541     void disassembled(const QString& file, int line, const std::list<DisassembledCode>& code);
542 
543     /**
544      * Indicates that the program has stopped for any reason: by a
545      * breakpoint, by a signal that the debugger driver caught, by a single
546      * step instruction.
547      */
548     void programStopped();
549 
550     /**
551      * Indicates that a new memory dump output is ready.
552      * @param msg is an error message or empty
553      * @param memdump is the memory dump
554      */
555     void memoryDumpChanged(const QString&, const std::list<MemoryDump>&);
556 
557     /**
558      * Gives other objects a chance to save program specific settings.
559      */
560     void saveProgramSpecific(KConfigBase* config);
561 
562     /**
563      * Gives other objects a chance to restore program specific settings.
564      */
565     void restoreProgramSpecific(KConfigBase* config);
566 
567 protected:
568     ExprWnd& m_localVariables;
569     ExprWnd& m_watchVariables;
570     QListWidget& m_btWindow;
571 
572     // implementation helpers
573 protected:
parentWidget()574     QWidget* parentWidget() { return static_cast<QWidget*>(parent()); }
575 };
576 
577 #endif // DEBUGGER_H
578