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