Have "View Code" take compilation directory into account.
[kdbg.git] / kdbg / debugger.cpp
blob8095486ac87b51c7a911229a375a38ef9ccf0b95
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 */
7 #include "debugger.h"
8 #include "dbgdriver.h"
9 #include "pgmargs.h"
10 #include "typetable.h"
11 #include "exprwnd.h"
12 #include "pgmsettings.h"
13 #include "programconfig.h"
14 #include <qregexp.h>
15 #include <qfileinfo.h>
16 #include <qlistbox.h>
17 #include <qstringlist.h>
18 #include <kapplication.h>
19 #include <kconfig.h>
20 #include <klocale.h> /* i18n */
21 #include <kmessagebox.h>
22 #include <ctype.h>
23 #include <stdlib.h> /* strtol, atoi */
24 #ifdef HAVE_UNISTD_H
25 #include <unistd.h> /* sleep(3) */
26 #endif
27 #include "mydebug.h"
30 KDebugger::KDebugger(QWidget* parent,
31 ExprWnd* localVars,
32 ExprWnd* watchVars,
33 QListBox* backtrace) :
34 QObject(parent, "debugger"),
35 m_ttyLevel(ttyFull),
36 m_memoryFormat(MDTword | MDThex),
37 m_haveExecutable(false),
38 m_programActive(false),
39 m_programRunning(false),
40 m_sharedLibsListed(false),
41 m_typeTable(0),
42 m_programConfig(0),
43 m_d(0),
44 m_localVariables(*localVars),
45 m_watchVariables(*watchVars),
46 m_btWindow(*backtrace)
48 m_envVars.setAutoDelete(true);
50 connect(&m_localVariables, SIGNAL(expanded(QListViewItem*)),
51 SLOT(slotExpanding(QListViewItem*)));
52 connect(&m_watchVariables, SIGNAL(expanded(QListViewItem*)),
53 SLOT(slotExpanding(QListViewItem*)));
54 connect(&m_localVariables, SIGNAL(editValueCommitted(VarTree*, const QString&)),
55 SLOT(slotValueEdited(VarTree*, const QString&)));
56 connect(&m_watchVariables, SIGNAL(editValueCommitted(VarTree*, const QString&)),
57 SLOT(slotValueEdited(VarTree*, const QString&)));
59 connect(&m_btWindow, SIGNAL(highlighted(int)), SLOT(gotoFrame(int)));
61 emit updateUI();
64 KDebugger::~KDebugger()
66 if (m_programConfig != 0) {
67 saveProgramSettings();
68 m_programConfig->sync();
69 delete m_programConfig;
72 delete m_typeTable;
76 void KDebugger::saveSettings(KConfig* /*config*/)
80 void KDebugger::restoreSettings(KConfig* /*config*/)
85 //////////////////////////////////////////////////////////////////////
86 // external interface
88 const char GeneralGroup[] = "General";
89 const char DebuggerCmdStr[] = "DebuggerCmdStr";
90 const char TTYLevelEntry[] = "TTYLevel";
91 const char KDebugger::DriverNameEntry[] = "DriverName";
93 bool KDebugger::debugProgram(const QString& name,
94 DebuggerDriver* driver)
96 if (m_d != 0 && m_d->isRunning())
98 QApplication::setOverrideCursor(waitCursor);
100 stopDriver();
102 QApplication::restoreOverrideCursor();
104 if (m_d->isRunning() || m_haveExecutable) {
105 /* timed out! We can't really do anything useful now */
106 TRACE("timed out while waiting for gdb to die!");
107 return false;
109 delete m_d;
110 m_d = 0;
113 // wire up the driver
114 connect(driver, SIGNAL(activateFileLine(const QString&,int,const DbgAddr&)),
115 this, SIGNAL(activateFileLine(const QString&,int,const DbgAddr&)));
116 connect(driver, SIGNAL(processExited(KProcess*)), SLOT(gdbExited(KProcess*)));
117 connect(driver, SIGNAL(commandReceived(CmdQueueItem*,const char*)),
118 SLOT(parse(CmdQueueItem*,const char*)));
119 connect(driver, SIGNAL(wroteStdin(KProcess*)), SIGNAL(updateUI()));
120 connect(driver, SIGNAL(inferiorRunning()), SLOT(slotInferiorRunning()));
121 connect(driver, SIGNAL(enterIdleState()), SLOT(backgroundUpdate()));
122 connect(driver, SIGNAL(enterIdleState()), SIGNAL(updateUI()));
123 connect(&m_localVariables, SIGNAL(removingItem(VarTree*)),
124 driver, SLOT(dequeueCmdByVar(VarTree*)));
125 connect(&m_watchVariables, SIGNAL(removingItem(VarTree*)),
126 driver, SLOT(dequeueCmdByVar(VarTree*)));
128 // create the program settings object
129 openProgramConfig(name);
131 // get debugger command from per-program settings
132 if (m_programConfig != 0) {
133 m_programConfig->setGroup(GeneralGroup);
134 m_debuggerCmd = readDebuggerCmd();
135 // get terminal emulation level
136 m_ttyLevel = TTYLevel(m_programConfig->readNumEntry(TTYLevelEntry, ttyFull));
138 // the rest is read in later in the handler of DCexecutable
140 m_d = driver;
142 if (!startDriver()) {
143 TRACE("startDriver failed");
144 m_d = 0;
145 return false;
148 TRACE("before file cmd");
149 m_d->executeCmd(DCexecutable, name);
150 m_executable = name;
152 // set remote target
153 if (!m_remoteDevice.isEmpty()) {
154 m_d->executeCmd(DCtargetremote, m_remoteDevice);
155 m_d->queueCmd(DCbt, DebuggerDriver::QMoverride);
156 m_d->queueCmd(DCframe, 0, DebuggerDriver::QMnormal);
157 m_programActive = true;
158 m_haveExecutable = true;
161 // create a type table
162 m_typeTable = new ProgramTypeTable;
163 m_sharedLibsListed = false;
165 emit updateUI();
167 return true;
170 void KDebugger::shutdown()
172 // shut down debugger driver
173 if (m_d != 0 && m_d->isRunning())
175 stopDriver();
179 void KDebugger::useCoreFile(QString corefile, bool batch)
181 m_corefile = corefile;
182 if (!batch) {
183 CmdQueueItem* cmd = loadCoreFile();
184 cmd->m_byUser = true;
188 void KDebugger::setAttachPid(const QString& pid)
190 m_attachedPid = pid;
193 void KDebugger::programRun()
195 if (!isReady())
196 return;
198 // when program is active, but not a core file, continue
199 // otherwise run the program
200 if (m_programActive && m_corefile.isEmpty()) {
201 // gdb command: continue
202 m_d->executeCmd(DCcont, true);
203 } else {
204 // gdb command: run
205 m_d->executeCmd(DCrun, true);
206 m_corefile = QString();
207 m_programActive = true;
209 m_programRunning = true;
212 void KDebugger::attachProgram(const QString& pid)
214 if (!isReady())
215 return;
217 m_attachedPid = pid;
218 TRACE("Attaching to " + m_attachedPid);
219 m_d->executeCmd(DCattach, m_attachedPid);
220 m_programActive = true;
221 m_programRunning = true;
224 void KDebugger::programRunAgain()
226 if (canSingleStep()) {
227 m_d->executeCmd(DCrun, true);
228 m_corefile = QString();
229 m_programRunning = true;
233 void KDebugger::programStep()
235 if (canSingleStep()) {
236 m_d->executeCmd(DCstep, true);
237 m_programRunning = true;
241 void KDebugger::programNext()
243 if (canSingleStep()) {
244 m_d->executeCmd(DCnext, true);
245 m_programRunning = true;
249 void KDebugger::programStepi()
251 if (canSingleStep()) {
252 m_d->executeCmd(DCstepi, true);
253 m_programRunning = true;
257 void KDebugger::programNexti()
259 if (canSingleStep()) {
260 m_d->executeCmd(DCnexti, true);
261 m_programRunning = true;
265 void KDebugger::programFinish()
267 if (canSingleStep()) {
268 m_d->executeCmd(DCfinish, true);
269 m_programRunning = true;
273 void KDebugger::programKill()
275 if (haveExecutable() && isProgramActive()) {
276 if (m_programRunning) {
277 m_d->interruptInferior();
279 // this is an emergency command; flush queues
280 m_d->flushCommands(true);
281 m_d->executeCmd(DCkill, true);
285 bool KDebugger::runUntil(const QString& fileName, int lineNo)
287 if (isReady() && m_programActive && !m_programRunning) {
288 // strip off directory part of file name
289 QString file = fileName;
290 int offset = file.findRev("/");
291 if (offset >= 0) {
292 file.remove(0, offset+1);
294 m_d->executeCmd(DCuntil, file, lineNo, true);
295 m_programRunning = true;
296 return true;
297 } else {
298 return false;
302 void KDebugger::programBreak()
304 if (m_haveExecutable && m_programRunning) {
305 m_d->interruptInferior();
309 void KDebugger::programArgs(QWidget* parent)
311 if (m_haveExecutable) {
312 QStringList allOptions = m_d->boolOptionList();
313 PgmArgs dlg(parent, m_executable, m_envVars, allOptions);
314 dlg.setArgs(m_programArgs);
315 dlg.setWd(m_programWD);
316 dlg.setOptions(m_boolOptions);
317 if (dlg.exec()) {
318 updateProgEnvironment(dlg.args(), dlg.wd(),
319 dlg.envVars(), dlg.options());
324 void KDebugger::programSettings(QWidget* parent)
326 if (!m_haveExecutable)
327 return;
329 ProgramSettings dlg(parent, m_executable);
331 dlg.m_chooseDriver.setDebuggerCmd(m_debuggerCmd);
332 dlg.m_output.setTTYLevel(m_ttyLevel);
334 if (dlg.exec() == QDialog::Accepted)
336 m_debuggerCmd = dlg.m_chooseDriver.debuggerCmd();
337 m_ttyLevel = TTYLevel(dlg.m_output.ttyLevel());
341 bool KDebugger::setBreakpoint(QString file, int lineNo,
342 const DbgAddr& address, bool temporary)
344 if (!isReady()) {
345 return false;
348 BrkptIterator bp = breakpointByFilePos(file, lineNo, address);
349 if (bp == m_brkpts.end())
352 * No such breakpoint, so set a new one. If we have an address, we
353 * set the breakpoint exactly there. Otherwise we use the file name
354 * plus line no.
356 Breakpoint* bp = new Breakpoint;
357 bp->temporary = temporary;
359 if (address.isEmpty())
361 bp->fileName = file;
362 bp->lineNo = lineNo;
364 else
366 bp->address = address;
368 setBreakpoint(bp, false);
370 else
373 * If the breakpoint is disabled, enable it; if it's enabled,
374 * delete that breakpoint.
376 if (bp->enabled) {
377 deleteBreakpoint(bp);
378 } else {
379 enableDisableBreakpoint(bp);
382 return true;
385 void KDebugger::setBreakpoint(Breakpoint* bp, bool queueOnly)
387 CmdQueueItem* cmd = executeBreakpoint(bp, queueOnly);
388 cmd->m_brkpt = bp; // used in newBreakpoint()
391 CmdQueueItem* KDebugger::executeBreakpoint(const Breakpoint* bp, bool queueOnly)
393 CmdQueueItem* cmd;
394 if (!bp->text.isEmpty())
397 * The breakpoint was set using the text box in the breakpoint
398 * list. This is the only way in which watchpoints are set.
400 if (bp->type == Breakpoint::watchpoint) {
401 cmd = m_d->executeCmd(DCwatchpoint, bp->text);
402 } else {
403 cmd = m_d->executeCmd(DCbreaktext, bp->text);
406 else if (bp->address.isEmpty())
408 // strip off directory part of file name
409 QString file = bp->fileName;
410 int offset = file.findRev("/");
411 if (offset >= 0) {
412 file.remove(0, offset+1);
414 if (queueOnly) {
415 cmd = m_d->queueCmd(bp->temporary ? DCtbreakline : DCbreakline,
416 file, bp->lineNo, DebuggerDriver::QMoverride);
417 } else {
418 cmd = m_d->executeCmd(bp->temporary ? DCtbreakline : DCbreakline,
419 file, bp->lineNo);
422 else
424 if (queueOnly) {
425 cmd = m_d->queueCmd(bp->temporary ? DCtbreakaddr : DCbreakaddr,
426 bp->address.asString(), DebuggerDriver::QMoverride);
427 } else {
428 cmd = m_d->executeCmd(bp->temporary ? DCtbreakaddr : DCbreakaddr,
429 bp->address.asString());
432 return cmd;
435 bool KDebugger::infoLine(QString file, int lineNo)
437 m_d->executeCmd(DCinfoline, file, lineNo);
438 return true;
441 bool KDebugger::enableDisableBreakpoint(QString file, int lineNo,
442 const DbgAddr& address)
444 BrkptIterator bp = breakpointByFilePos(file, lineNo, address);
445 return enableDisableBreakpoint(bp);
448 bool KDebugger::enableDisableBreakpoint(BrkptIterator bp)
450 if (bp == m_brkpts.end())
451 return false;
454 * Toggle enabled/disabled state.
456 * The driver is not bothered if we are modifying an orphaned
457 * breakpoint.
459 if (!bp->isOrphaned()) {
460 if (!canChangeBreakpoints()) {
461 return false;
463 m_d->executeCmd(bp->enabled ? DCdisable : DCenable, bp->id);
464 } else {
465 bp->enabled = !bp->enabled;
466 emit breakpointsChanged();
468 return true;
471 bool KDebugger::conditionalBreakpoint(BrkptIterator bp,
472 const QString& condition,
473 int ignoreCount)
475 if (bp == m_brkpts.end())
476 return false;
479 * Change the condition and ignore count.
481 * The driver is not bothered if we are removing an orphaned
482 * breakpoint.
485 if (!bp->isOrphaned()) {
486 if (!canChangeBreakpoints()) {
487 return false;
490 bool changed = false;
492 if (bp->condition != condition) {
493 // change condition
494 m_d->executeCmd(DCcondition, condition, bp->id);
495 changed = true;
497 if (bp->ignoreCount != ignoreCount) {
498 // change ignore count
499 m_d->executeCmd(DCignore, bp->id, ignoreCount);
500 changed = true;
502 if (changed) {
503 // get the changes
504 m_d->queueCmd(DCinfobreak, DebuggerDriver::QMoverride);
506 } else {
507 bp->condition = condition;
508 bp->ignoreCount = ignoreCount;
509 emit breakpointsChanged();
511 return true;
514 bool KDebugger::deleteBreakpoint(BrkptIterator bp)
516 if (bp == m_brkpts.end())
517 return false;
520 * Remove the breakpoint.
522 * The driver is not bothered if we are removing an orphaned
523 * breakpoint.
525 if (!bp->isOrphaned()) {
526 if (!canChangeBreakpoints()) {
527 return false;
529 m_d->executeCmd(DCdelete, bp->id);
530 } else {
531 m_brkpts.erase(bp);
532 emit breakpointsChanged();
534 return false;
537 bool KDebugger::canSingleStep()
539 return isReady() && m_programActive && !m_programRunning;
542 bool KDebugger::canChangeBreakpoints()
544 return isReady() && !m_programRunning;
547 bool KDebugger::canStart()
549 return isReady() && !m_programActive;
552 bool KDebugger::isReady() const
554 return m_haveExecutable &&
555 m_d != 0 && m_d->canExecuteImmediately();
558 bool KDebugger::isIdle() const
560 return m_d == 0 || m_d->isIdle();
564 //////////////////////////////////////////////////////////
565 // debugger driver
567 bool KDebugger::startDriver()
569 emit debuggerStarting(); /* must set m_inferiorTerminal */
572 * If the per-program command string is empty, use the global setting
573 * (which might also be empty, in which case the driver uses its
574 * default).
576 m_explicitKill = false;
577 if (!m_d->startup(m_debuggerCmd)) {
578 return false;
582 * If we have an output terminal, we use it. Otherwise we will run the
583 * program with input and output redirected to /dev/null. Other
584 * redirections are also necessary depending on the tty emulation
585 * level.
587 int redirect = RDNstdin|RDNstdout|RDNstderr; /* redirect everything */
588 if (!m_inferiorTerminal.isEmpty()) {
589 switch (m_ttyLevel) {
590 default:
591 case ttyNone:
592 // redirect everything
593 break;
594 case ttySimpleOutputOnly:
595 redirect = RDNstdin;
596 break;
597 case ttyFull:
598 redirect = 0;
599 break;
602 m_d->executeCmd(DCtty, m_inferiorTerminal, redirect);
604 return true;
607 void KDebugger::stopDriver()
609 m_explicitKill = true;
611 if (m_attachedPid.isEmpty()) {
612 m_d->terminate();
613 } else {
614 m_d->detachAndTerminate();
618 * We MUST wait until the slot gdbExited() has been called. But to
619 * avoid a deadlock, we wait only for some certain maximum time. Should
620 * this timeout be reached, the only reasonable thing one could do then
621 * is exiting kdbg.
623 kapp->processEvents(1000); /* ideally, this will already shut it down */
624 int maxTime = 20; /* about 20 seconds */
625 while (m_haveExecutable && maxTime > 0) {
626 // give gdb time to die (and send a SIGCLD)
627 ::sleep(1);
628 --maxTime;
629 kapp->processEvents(1000);
633 void KDebugger::gdbExited(KProcess*)
636 * Save settings, but only if gdb has already processed "info line
637 * main", otherwise we would save an empty config file, because it
638 * isn't read in until then!
640 if (m_programConfig != 0) {
641 if (m_haveExecutable) {
642 saveProgramSettings();
643 m_programConfig->sync();
645 delete m_programConfig;
646 m_programConfig = 0;
649 // erase types
650 delete m_typeTable;
651 m_typeTable = 0;
653 if (m_explicitKill) {
654 TRACE(m_d->driverName() + " exited normally");
655 } else {
656 QString msg = i18n("%1 exited unexpectedly.\n"
657 "Restart the session (e.g. with File|Executable).");
658 KMessageBox::error(parentWidget(), msg.arg(m_d->driverName()));
661 // reset state
662 m_haveExecutable = false;
663 m_executable = "";
664 m_programActive = false;
665 m_programRunning = false;
666 m_explicitKill = false;
667 m_debuggerCmd = QString(); /* use global setting at next start! */
668 m_attachedPid = QString(); /* we are no longer attached to a process */
669 m_ttyLevel = ttyFull;
670 m_brkpts.clear();
672 // erase PC
673 emit updatePC(QString(), -1, DbgAddr(), 0);
676 QString KDebugger::getConfigForExe(const QString& name)
678 QFileInfo fi(name);
679 QString pgmConfigFile = fi.dirPath(true);
680 if (!pgmConfigFile.isEmpty()) {
681 pgmConfigFile += '/';
683 pgmConfigFile += ".kdbgrc." + fi.fileName();
684 TRACE("program config file = " + pgmConfigFile);
685 return pgmConfigFile;
688 void KDebugger::openProgramConfig(const QString& name)
690 ASSERT(m_programConfig == 0);
692 QString pgmConfigFile = getConfigForExe(name);
694 m_programConfig = new ProgramConfig(pgmConfigFile);
697 const char EnvironmentGroup[] = "Environment";
698 const char WatchGroup[] = "Watches";
699 const char FileVersion[] = "FileVersion";
700 const char ProgramArgs[] = "ProgramArgs";
701 const char WorkingDirectory[] = "WorkingDirectory";
702 const char OptionsSelected[] = "OptionsSelected";
703 const char Variable[] = "Var%d";
704 const char Value[] = "Value%d";
705 const char ExprFmt[] = "Expr%d";
707 void KDebugger::saveProgramSettings()
709 ASSERT(m_programConfig != 0);
710 m_programConfig->setGroup(GeneralGroup);
711 m_programConfig->writeEntry(FileVersion, 1);
712 m_programConfig->writeEntry(ProgramArgs, m_programArgs);
713 m_programConfig->writeEntry(WorkingDirectory, m_programWD);
714 m_programConfig->writeEntry(OptionsSelected, m_boolOptions);
715 m_programConfig->writeEntry(DebuggerCmdStr, m_debuggerCmd);
716 m_programConfig->writeEntry(TTYLevelEntry, int(m_ttyLevel));
717 QString driverName;
718 if (m_d != 0)
719 driverName = m_d->driverName();
720 m_programConfig->writeEntry(DriverNameEntry, driverName);
722 // write environment variables
723 m_programConfig->deleteGroup(EnvironmentGroup);
724 m_programConfig->setGroup(EnvironmentGroup);
725 QDictIterator<EnvVar> it = m_envVars;
726 EnvVar* var;
727 QString varName;
728 QString varValue;
729 for (int i = 0; (var = it) != 0; ++it, ++i) {
730 varName.sprintf(Variable, i);
731 varValue.sprintf(Value, i);
732 m_programConfig->writeEntry(varName, it.currentKey());
733 m_programConfig->writeEntry(varValue, var->value);
736 saveBreakpoints(m_programConfig);
738 // watch expressions
739 // first get rid of whatever was in this group
740 m_programConfig->deleteGroup(WatchGroup);
741 // then start a new group
742 m_programConfig->setGroup(WatchGroup);
743 VarTree* item = m_watchVariables.firstChild();
744 int watchNum = 0;
745 for (; item != 0; item = item->nextSibling(), ++watchNum) {
746 varName.sprintf(ExprFmt, watchNum);
747 m_programConfig->writeEntry(varName, item->getText());
750 // give others a chance
751 emit saveProgramSpecific(m_programConfig);
754 void KDebugger::overrideProgramArguments(const QString& args)
756 ASSERT(m_programConfig != 0);
757 m_programConfig->setGroup(GeneralGroup);
758 m_programConfig->writeEntry(ProgramArgs, args);
761 void KDebugger::restoreProgramSettings()
763 ASSERT(m_programConfig != 0);
764 m_programConfig->setGroup(GeneralGroup);
766 * We ignore file version for now we will use it in the future to
767 * distinguish different versions of this configuration file.
769 // m_debuggerCmd has been read in already
770 // m_ttyLevel has been read in already
771 QString pgmArgs = m_programConfig->readEntry(ProgramArgs);
772 QString pgmWd = m_programConfig->readEntry(WorkingDirectory);
773 QStringList boolOptions = m_programConfig->readListEntry(OptionsSelected);
774 m_boolOptions = QStringList();
776 // read environment variables
777 m_programConfig->setGroup(EnvironmentGroup);
778 m_envVars.clear();
779 QDict<EnvVar> pgmVars;
780 EnvVar* var;
781 QString varName;
782 QString varValue;
783 for (int i = 0;; ++i) {
784 varName.sprintf(Variable, i);
785 varValue.sprintf(Value, i);
786 if (!m_programConfig->hasKey(varName)) {
787 /* entry not present, assume that we've hit them all */
788 break;
790 QString name = m_programConfig->readEntry(varName);
791 if (name.isEmpty()) {
792 // skip empty names
793 continue;
795 var = new EnvVar;
796 var->value = m_programConfig->readEntry(varValue);
797 var->status = EnvVar::EVnew;
798 pgmVars.insert(name, var);
801 updateProgEnvironment(pgmArgs, pgmWd, pgmVars, boolOptions);
803 restoreBreakpoints(m_programConfig);
805 // watch expressions
806 m_programConfig->setGroup(WatchGroup);
807 m_watchVariables.clear();
808 for (int i = 0;; ++i) {
809 varName.sprintf(ExprFmt, i);
810 if (!m_programConfig->hasKey(varName)) {
811 /* entry not present, assume that we've hit them all */
812 break;
814 QString expr = m_programConfig->readEntry(varName);
815 if (expr.isEmpty()) {
816 // skip empty expressions
817 continue;
819 addWatch(expr);
822 // give others a chance
823 emit restoreProgramSpecific(m_programConfig);
827 * Reads the debugger command line from the program settings. The config
828 * group must have been set by the caller.
830 QString KDebugger::readDebuggerCmd()
832 QString debuggerCmd = m_programConfig->readEntry(DebuggerCmdStr);
834 // always let the user confirm the debugger cmd if we are root
835 if (::geteuid() == 0)
837 if (!debuggerCmd.isEmpty()) {
838 QString msg = i18n(
839 "The settings for this program specify "
840 "the following debugger command:\n%1\n"
841 "Shall this command be used?");
842 if (KMessageBox::warningYesNo(parentWidget(), msg.arg(debuggerCmd))
843 != KMessageBox::Yes)
845 // don't use it
846 debuggerCmd = QString();
850 return debuggerCmd;
854 * Breakpoints are saved one per group.
856 const char BPGroup[] = "Breakpoint %d";
857 const char File[] = "File";
858 const char Line[] = "Line";
859 const char Text[] = "Text";
860 const char Address[] = "Address";
861 const char Temporary[] = "Temporary";
862 const char Enabled[] = "Enabled";
863 const char Condition[] = "Condition";
865 void KDebugger::saveBreakpoints(ProgramConfig* config)
867 QString groupName;
868 int i = 0;
869 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
871 if (bp->type == Breakpoint::watchpoint)
872 continue; /* don't save watchpoints */
873 groupName.sprintf(BPGroup, i++);
875 /* remove remmants */
876 config->deleteGroup(groupName);
878 config->setGroup(groupName);
879 if (!bp->text.isEmpty()) {
881 * The breakpoint was set using the text box in the breakpoint
882 * list. We do not save the location by filename+line number,
883 * but instead honor what the user typed (a function name, for
884 * example, which could move between sessions).
886 config->writeEntry(Text, bp->text);
887 } else if (!bp->fileName.isEmpty()) {
888 config->writeEntry(File, bp->fileName);
889 config->writeEntry(Line, bp->lineNo);
891 * Addresses are hardly correct across sessions, so we don't
892 * save it.
894 } else {
895 config->writeEntry(Address, bp->address.asString());
897 config->writeEntry(Temporary, bp->temporary);
898 config->writeEntry(Enabled, bp->enabled);
899 if (!bp->condition.isEmpty())
900 config->writeEntry(Condition, bp->condition);
901 // we do not save the ignore count
903 // delete remaining groups
904 // we recognize that a group is present if there is an Enabled entry
905 for (;; i++) {
906 groupName.sprintf(BPGroup, i);
907 config->setGroup(groupName);
908 if (!config->hasKey(Enabled)) {
909 /* group not present, assume that we've hit them all */
910 break;
912 config->deleteGroup(groupName);
916 void KDebugger::restoreBreakpoints(ProgramConfig* config)
918 QString groupName;
920 * We recognize the end of the list if there is no Enabled entry
921 * present.
923 for (int i = 0;; i++) {
924 groupName.sprintf(BPGroup, i);
925 config->setGroup(groupName);
926 if (!config->hasKey(Enabled)) {
927 /* group not present, assume that we've hit them all */
928 break;
930 Breakpoint* bp = new Breakpoint;
931 bp->fileName = config->readEntry(File);
932 bp->lineNo = config->readNumEntry(Line, -1);
933 bp->text = config->readEntry(Text);
934 bp->address = config->readEntry(Address);
935 // check consistency
936 if ((bp->fileName.isEmpty() || bp->lineNo < 0) &&
937 bp->text.isEmpty() &&
938 bp->address.isEmpty())
940 delete bp;
941 continue;
943 bp->enabled = config->readBoolEntry(Enabled, true);
944 bp->temporary = config->readBoolEntry(Temporary, false);
945 bp->condition = config->readEntry(Condition);
948 * Add the breakpoint.
950 setBreakpoint(bp, false);
951 // the new breakpoint is disabled or conditionalized later
952 // in newBreakpoint()
954 m_d->queueCmd(DCinfobreak, DebuggerDriver::QMoverride);
958 // parse output of command cmd
959 void KDebugger::parse(CmdQueueItem* cmd, const char* output)
961 ASSERT(cmd != 0); /* queue mustn't be empty */
963 TRACE(QString(__PRETTY_FUNCTION__) + " parsing " + output);
965 switch (cmd->m_cmd) {
966 case DCtargetremote:
967 // the output (if any) is uninteresting
968 case DCsetargs:
969 case DCtty:
970 // there is no output
971 case DCsetenv:
972 case DCunsetenv:
973 case DCsetoption:
974 /* if value is empty, we see output, but we don't care */
975 break;
976 case DCcd:
977 /* display gdb's message in the status bar */
978 m_d->parseChangeWD(output, m_statusMessage);
979 emit updateStatusMessage();
980 break;
981 case DCinitialize:
982 break;
983 case DCexecutable:
984 if (m_d->parseChangeExecutable(output, m_statusMessage))
986 // success; restore breakpoints etc.
987 if (m_programConfig != 0) {
988 restoreProgramSettings();
990 // load file containing main() or core file
991 if (!m_corefile.isEmpty())
993 // load core file
994 loadCoreFile();
996 else if (!m_attachedPid.isEmpty())
998 m_d->queueCmd(DCattach, m_attachedPid, DebuggerDriver::QMoverride);
999 m_programActive = true;
1000 m_programRunning = true;
1002 else if (!m_remoteDevice.isEmpty())
1004 // handled elsewhere
1006 else
1008 m_d->queueCmd(DCinfolinemain, DebuggerDriver::QMnormal);
1010 if (!m_statusMessage.isEmpty())
1011 emit updateStatusMessage();
1012 } else {
1013 QString msg = m_d->driverName() + ": " + m_statusMessage;
1014 KMessageBox::sorry(parentWidget(), msg);
1015 m_executable = "";
1016 m_corefile = ""; /* don't process core file */
1017 m_haveExecutable = false;
1019 break;
1020 case DCcorefile:
1021 // in any event we have an executable at this point
1022 m_haveExecutable = true;
1023 if (m_d->parseCoreFile(output)) {
1024 // loading a core is like stopping at a breakpoint
1025 m_programActive = true;
1026 handleRunCommands(output);
1027 // do not reset m_corefile
1028 } else {
1029 // report error
1030 QString msg = m_d->driverName() + ": " + QString(output);
1031 KMessageBox::sorry(parentWidget(), msg);
1033 // if core file was loaded from command line, revert to info line main
1034 if (!cmd->m_byUser) {
1035 m_d->queueCmd(DCinfolinemain, DebuggerDriver::QMnormal);
1037 m_corefile = QString(); /* core file not available any more */
1039 break;
1040 case DCinfolinemain:
1041 // ignore the output, marked file info follows
1042 m_haveExecutable = true;
1043 break;
1044 case DCinfolocals:
1045 // parse local variables
1046 if (output[0] != '\0') {
1047 handleLocals(output);
1049 break;
1050 case DCinforegisters:
1051 handleRegisters(output);
1052 break;
1053 case DCexamine:
1054 handleMemoryDump(output);
1055 break;
1056 case DCinfoline:
1057 handleInfoLine(cmd, output);
1058 break;
1059 case DCdisassemble:
1060 handleDisassemble(cmd, output);
1061 break;
1062 case DCframe:
1063 handleFrameChange(output);
1064 updateAllExprs();
1065 break;
1066 case DCbt:
1067 handleBacktrace(output);
1068 updateAllExprs();
1069 break;
1070 case DCprint:
1071 handlePrint(cmd, output);
1072 break;
1073 case DCprintDeref:
1074 handlePrintDeref(cmd, output);
1075 break;
1076 case DCattach:
1077 m_haveExecutable = true;
1078 // fall through
1079 case DCrun:
1080 case DCcont:
1081 case DCstep:
1082 case DCstepi:
1083 case DCnext:
1084 case DCnexti:
1085 case DCfinish:
1086 case DCuntil:
1087 case DCthread:
1088 handleRunCommands(output);
1089 break;
1090 case DCkill:
1091 m_programRunning = m_programActive = false;
1092 // erase PC
1093 emit updatePC(QString(), -1, DbgAddr(), 0);
1094 break;
1095 case DCbreaktext:
1096 case DCbreakline:
1097 case DCtbreakline:
1098 case DCbreakaddr:
1099 case DCtbreakaddr:
1100 case DCwatchpoint:
1101 newBreakpoint(cmd, output);
1102 // fall through
1103 case DCdelete:
1104 case DCenable:
1105 case DCdisable:
1106 // these commands need immediate response
1107 m_d->queueCmd(DCinfobreak, DebuggerDriver::QMoverrideMoreEqual);
1108 break;
1109 case DCinfobreak:
1110 // note: this handler must not enqueue a command, since
1111 // DCinfobreak is used at various different places.
1112 updateBreakList(output);
1113 break;
1114 case DCfindType:
1115 handleFindType(cmd, output);
1116 break;
1117 case DCprintStruct:
1118 case DCprintQStringStruct:
1119 case DCprintWChar:
1120 handlePrintStruct(cmd, output);
1121 break;
1122 case DCinfosharedlib:
1123 handleSharedLibs(output);
1124 break;
1125 case DCcondition:
1126 case DCignore:
1127 // we are not interested in the output
1128 break;
1129 case DCinfothreads:
1130 handleThreadList(output);
1131 break;
1132 case DCsetpc:
1133 handleSetPC(output);
1134 break;
1135 case DCsetvariable:
1136 handleSetVariable(cmd, output);
1137 break;
1141 void KDebugger::backgroundUpdate()
1144 * If there are still expressions that need to be updated, then do so.
1146 if (m_programActive)
1147 evalExpressions();
1150 void KDebugger::handleRunCommands(const char* output)
1152 uint flags = m_d->parseProgramStopped(output, m_statusMessage);
1153 emit updateStatusMessage();
1155 m_programActive = flags & DebuggerDriver::SFprogramActive;
1157 // refresh files if necessary
1158 if (flags & DebuggerDriver::SFrefreshSource) {
1159 TRACE("re-reading files");
1160 emit executableUpdated();
1164 * Try to set any orphaned breakpoints now.
1166 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
1168 if (bp->isOrphaned()) {
1169 TRACE(QString("re-trying brkpt loc: %2 file: %3 line: %1")
1170 .arg(bp->lineNo).arg(bp->location, bp->fileName));
1171 CmdQueueItem* cmd = executeBreakpoint(&*bp, true);
1172 cmd->m_existingBrkpt = bp->id; // used in newBreakpoint()
1173 flags |= DebuggerDriver::SFrefreshBreak;
1178 * If we stopped at a breakpoint, we must update the breakpoint list
1179 * because the hit count changes. Also, if the breakpoint was temporary
1180 * it would go away now.
1182 if ((flags & (DebuggerDriver::SFrefreshBreak|DebuggerDriver::SFrefreshSource)) ||
1183 stopMayChangeBreakList())
1185 m_d->queueCmd(DCinfobreak, DebuggerDriver::QMoverride);
1189 * If we haven't listed the shared libraries yet, do so. We must do
1190 * this before we emit any commands that list variables, since the type
1191 * libraries depend on the shared libraries.
1193 if (!m_sharedLibsListed) {
1194 // must be a high-priority command!
1195 m_d->executeCmd(DCinfosharedlib);
1198 // get the backtrace if the program is running
1199 if (m_programActive) {
1200 m_d->queueCmd(DCbt, DebuggerDriver::QMoverride);
1201 } else {
1202 // program finished: erase PC
1203 emit updatePC(QString(), -1, DbgAddr(), 0);
1204 // dequeue any commands in the queues
1205 m_d->flushCommands();
1208 /* Update threads list */
1209 if (m_programActive && (flags & DebuggerDriver::SFrefreshThreads)) {
1210 m_d->queueCmd(DCinfothreads, DebuggerDriver::QMoverride);
1213 m_programRunning = false;
1214 emit programStopped();
1217 void KDebugger::slotInferiorRunning()
1219 m_programRunning = true;
1222 void KDebugger::updateAllExprs()
1224 if (!m_programActive)
1225 return;
1227 // retrieve local variables
1228 m_d->queueCmd(DCinfolocals, DebuggerDriver::QMoverride);
1230 // retrieve registers
1231 m_d->queueCmd(DCinforegisters, DebuggerDriver::QMoverride);
1233 // get new memory dump
1234 if (!m_memoryExpression.isEmpty()) {
1235 queueMemoryDump(false);
1238 // update watch expressions
1239 VarTree* item = m_watchVariables.firstChild();
1240 for (; item != 0; item = item->nextSibling()) {
1241 m_watchEvalExpr.push_back(item->getText());
1245 void KDebugger::updateProgEnvironment(const QString& args, const QString& wd,
1246 const QDict<EnvVar>& newVars,
1247 const QStringList& newOptions)
1249 m_programArgs = args;
1250 m_d->executeCmd(DCsetargs, m_programArgs);
1251 TRACE("new pgm args: " + m_programArgs + "\n");
1253 m_programWD = wd.stripWhiteSpace();
1254 if (!m_programWD.isEmpty()) {
1255 m_d->executeCmd(DCcd, m_programWD);
1256 TRACE("new wd: " + m_programWD + "\n");
1259 // update environment variables
1260 QDictIterator<EnvVar> it = newVars;
1261 EnvVar* val;
1262 for (; (val = it) != 0; ++it) {
1263 QString var = it.currentKey();
1264 switch (val->status) {
1265 case EnvVar::EVnew:
1266 m_envVars.insert(var, val);
1267 // fall thru
1268 case EnvVar::EVdirty:
1269 // the value must be in our list
1270 ASSERT(m_envVars[var] == val);
1271 // update value
1272 m_d->executeCmd(DCsetenv, var, val->value);
1273 break;
1274 case EnvVar::EVdeleted:
1275 // must be in our list
1276 ASSERT(m_envVars[var] == val);
1277 // delete value
1278 m_d->executeCmd(DCunsetenv, var);
1279 m_envVars.remove(var);
1280 break;
1281 default:
1282 ASSERT(false);
1283 case EnvVar::EVclean:
1284 // variable not changed
1285 break;
1289 // update options
1290 QStringList::ConstIterator oi;
1291 for (oi = newOptions.begin(); oi != newOptions.end(); ++oi)
1293 if (m_boolOptions.findIndex(*oi) < 0) {
1294 // the options is currently not set, so set it
1295 m_d->executeCmd(DCsetoption, *oi, 1);
1296 } else {
1297 // option is set, no action required, but move it to the end
1298 m_boolOptions.remove(*oi);
1300 m_boolOptions.append(*oi);
1303 * Now all options that should be set are at the end of m_boolOptions.
1304 * If some options need to be unset, they are at the front of the list.
1305 * Here we unset and remove them.
1307 while (m_boolOptions.count() > newOptions.count()) {
1308 m_d->executeCmd(DCsetoption, m_boolOptions.first(), 0);
1309 m_boolOptions.remove(m_boolOptions.begin());
1313 void KDebugger::handleLocals(const char* output)
1315 // retrieve old list of local variables
1316 QStringList oldVars = m_localVariables.exprList();
1319 * Get local variables.
1321 std::list<ExprValue*> newVars;
1322 parseLocals(output, newVars);
1325 * Clear any old VarTree item pointers, so that later we don't access
1326 * dangling pointers.
1328 m_localVariables.clearPendingUpdates();
1331 * Match old variables against new ones.
1333 for (QStringList::ConstIterator n = oldVars.begin(); n != oldVars.end(); ++n) {
1334 // lookup this variable in the list of new variables
1335 std::list<ExprValue*>::iterator v = newVars.begin();
1336 while (v != newVars.end() && (*v)->m_name != *n)
1337 ++v;
1338 if (v == newVars.end()) {
1339 // old variable not in the new variables
1340 TRACE("old var deleted: " + *n);
1341 VarTree* v = m_localVariables.topLevelExprByName(*n);
1342 if (v != 0) {
1343 m_localVariables.removeExpr(v);
1345 } else {
1346 // variable in both old and new lists: update
1347 TRACE("update var: " + *n);
1348 m_localVariables.updateExpr(*v, *m_typeTable);
1349 // remove the new variable from the list
1350 delete *v;
1351 newVars.erase(v);
1354 // insert all remaining new variables
1355 while (!newVars.empty())
1357 ExprValue* v = newVars.front();
1358 TRACE("new var: " + v->m_name);
1359 m_localVariables.insertExpr(v, *m_typeTable);
1360 delete v;
1361 newVars.pop_front();
1365 void KDebugger::parseLocals(const char* output, std::list<ExprValue*>& newVars)
1367 std::list<ExprValue*> vars;
1368 m_d->parseLocals(output, vars);
1370 QString origName; /* used in renaming variables */
1371 while (!vars.empty())
1373 ExprValue* variable = vars.front();
1374 vars.pop_front();
1376 * When gdb prints local variables, those from the innermost block
1377 * come first. We run through the list of already parsed variables
1378 * to find duplicates (ie. variables that hide local variables from
1379 * a surrounding block). We keep the name of the inner variable, but
1380 * rename those from the outer block so that, when the value is
1381 * updated in the window, the value of the variable that is
1382 * _visible_ changes the color!
1384 int block = 0;
1385 origName = variable->m_name;
1386 for (std::list<ExprValue*>::iterator v = newVars.begin(); v != newVars.end(); ++v) {
1387 if (variable->m_name == (*v)->m_name) {
1388 // we found a duplicate, change name
1389 block++;
1390 QString newName = origName + " (" + QString().setNum(block) + ")";
1391 variable->m_name = newName;
1394 newVars.push_back(variable);
1398 bool KDebugger::handlePrint(CmdQueueItem* cmd, const char* output)
1400 ASSERT(cmd->m_expr != 0);
1402 ExprValue* variable = m_d->parsePrintExpr(output, true);
1403 if (variable == 0)
1404 return false;
1406 // set expression "name"
1407 variable->m_name = cmd->m_expr->getText();
1410 TRACE("update expr: " + cmd->m_expr->getText());
1411 cmd->m_exprWnd->updateExpr(cmd->m_expr, variable, *m_typeTable);
1412 delete variable;
1415 evalExpressions(); /* enqueue dereferenced pointers */
1417 return true;
1420 bool KDebugger::handlePrintDeref(CmdQueueItem* cmd, const char* output)
1422 ASSERT(cmd->m_expr != 0);
1424 ExprValue* variable = m_d->parsePrintExpr(output, true);
1425 if (variable == 0)
1426 return false;
1428 // set expression "name"
1429 variable->m_name = cmd->m_expr->getText();
1433 * We must insert a dummy parent, because otherwise variable's value
1434 * would overwrite cmd->m_expr's value.
1436 ExprValue* dummyParent = new ExprValue(variable->m_name, VarTree::NKplain);
1437 dummyParent->m_varKind = VarTree::VKdummy;
1438 // the name of the parsed variable is the address of the pointer
1439 QString addr = "*" + cmd->m_expr->value();
1440 variable->m_name = addr;
1441 variable->m_nameKind = VarTree::NKaddress;
1443 dummyParent->m_child = variable;
1444 // expand the first level for convenience
1445 variable->m_initiallyExpanded = true;
1446 TRACE("update ptr: " + cmd->m_expr->getText());
1447 cmd->m_exprWnd->updateExpr(cmd->m_expr, dummyParent, *m_typeTable);
1448 delete dummyParent;
1451 evalExpressions(); /* enqueue dereferenced pointers */
1453 return true;
1456 // parse the output of bt
1457 void KDebugger::handleBacktrace(const char* output)
1459 // reduce flicker
1460 m_btWindow.setAutoUpdate(false);
1462 m_btWindow.clear();
1464 std::list<StackFrame> stack;
1465 m_d->parseBackTrace(output, stack);
1467 if (!stack.empty()) {
1468 std::list<StackFrame>::iterator frm = stack.begin();
1469 // first frame must set PC
1470 // note: frm->lineNo is zero-based
1471 emit updatePC(frm->fileName, frm->lineNo, frm->address, frm->frameNo);
1473 for (; frm != stack.end(); ++frm) {
1474 QString func;
1475 if (frm->var != 0)
1476 func = frm->var->m_name;
1477 else
1478 func = frm->fileName + ":" + QString().setNum(frm->lineNo+1);
1479 m_btWindow.insertItem(func);
1480 TRACE("frame " + func + " (" + frm->fileName + ":" +
1481 QString().setNum(frm->lineNo+1) + ")");
1485 m_btWindow.setAutoUpdate(true);
1486 m_btWindow.repaint();
1489 void KDebugger::gotoFrame(int frame)
1491 m_d->executeCmd(DCframe, frame);
1494 void KDebugger::handleFrameChange(const char* output)
1496 QString fileName;
1497 int frameNo;
1498 int lineNo;
1499 DbgAddr address;
1500 if (m_d->parseFrameChange(output, frameNo, fileName, lineNo, address)) {
1501 /* lineNo can be negative here if we can't find a file name */
1502 emit updatePC(fileName, lineNo, address, frameNo);
1503 } else {
1504 emit updatePC(fileName, -1, address, frameNo);
1508 void KDebugger::evalExpressions()
1510 // evaluate expressions in the following order:
1511 // watch expressions
1512 // pointers in local variables
1513 // pointers in watch expressions
1514 // types in local variables
1515 // types in watch expressions
1516 // struct members in local variables
1517 // struct members in watch expressions
1518 VarTree* exprItem = 0;
1519 if (!m_watchEvalExpr.empty())
1521 QString expr = m_watchEvalExpr.front();
1522 m_watchEvalExpr.pop_front();
1523 exprItem = m_watchVariables.topLevelExprByName(expr);
1525 if (exprItem != 0) {
1526 CmdQueueItem* cmd = m_d->queueCmd(DCprint, exprItem->getText(), DebuggerDriver::QMoverride);
1527 // remember which expr this was
1528 cmd->m_expr = exprItem;
1529 cmd->m_exprWnd = &m_watchVariables;
1530 } else {
1531 ExprWnd* wnd;
1532 #define POINTER(widget) \
1533 wnd = &widget; \
1534 exprItem = widget.nextUpdatePtr(); \
1535 if (exprItem != 0) goto pointer
1536 #define STRUCT(widget) \
1537 wnd = &widget; \
1538 exprItem = widget.nextUpdateStruct(); \
1539 if (exprItem != 0) goto ustruct
1540 #define TYPE(widget) \
1541 wnd = &widget; \
1542 exprItem = widget.nextUpdateType(); \
1543 if (exprItem != 0) goto type
1544 repeat:
1545 POINTER(m_localVariables);
1546 POINTER(m_watchVariables);
1547 STRUCT(m_localVariables);
1548 STRUCT(m_watchVariables);
1549 TYPE(m_localVariables);
1550 TYPE(m_watchVariables);
1551 #undef POINTER
1552 #undef STRUCT
1553 #undef TYPE
1554 return;
1556 pointer:
1557 // we have an expression to send
1558 dereferencePointer(wnd, exprItem, false);
1559 return;
1561 ustruct:
1562 // paranoia
1563 if (exprItem->m_type == 0 || exprItem->m_type == TypeInfo::unknownType())
1564 goto repeat;
1565 evalInitialStructExpression(exprItem, wnd, false);
1566 return;
1568 type:
1570 * Sometimes a VarTree gets registered twice for a type update. So
1571 * it may happen that it has already been updated. Hence, we ignore
1572 * it here and go on to the next task.
1574 if (exprItem->m_type != 0)
1575 goto repeat;
1576 determineType(wnd, exprItem);
1580 void KDebugger::dereferencePointer(ExprWnd* wnd, VarTree* exprItem,
1581 bool immediate)
1583 ASSERT(exprItem->m_varKind == VarTree::VKpointer);
1585 QString expr = exprItem->computeExpr();
1586 TRACE("dereferencing pointer: " + expr);
1587 CmdQueueItem* cmd;
1588 if (immediate) {
1589 cmd = m_d->queueCmd(DCprintDeref, expr, DebuggerDriver::QMoverrideMoreEqual);
1590 } else {
1591 cmd = m_d->queueCmd(DCprintDeref, expr, DebuggerDriver::QMoverride);
1593 // remember which expr this was
1594 cmd->m_expr = exprItem;
1595 cmd->m_exprWnd = wnd;
1598 void KDebugger::determineType(ExprWnd* wnd, VarTree* exprItem)
1600 ASSERT(exprItem->m_varKind == VarTree::VKstruct);
1602 QString expr = exprItem->computeExpr();
1603 TRACE("get type of: " + expr);
1604 CmdQueueItem* cmd;
1605 cmd = m_d->queueCmd(DCfindType, expr, DebuggerDriver::QMoverride);
1607 // remember which expr this was
1608 cmd->m_expr = exprItem;
1609 cmd->m_exprWnd = wnd;
1612 void KDebugger::handleFindType(CmdQueueItem* cmd, const char* output)
1614 QString type;
1615 if (m_d->parseFindType(output, type))
1617 ASSERT(cmd != 0 && cmd->m_expr != 0);
1619 TypeInfo* info = m_typeTable->lookup(type);
1621 if (info == 0) {
1623 * We've asked gdb for the type of the expression in
1624 * cmd->m_expr, but it returned a name we don't know. The base
1625 * class (and member) types have been checked already (at the
1626 * time when we parsed that particular expression). Now it's
1627 * time to derive the type from the base classes as a last
1628 * resort.
1630 info = cmd->m_expr->inferTypeFromBaseClass();
1631 // if we found a type through this method, register an alias
1632 if (info != 0) {
1633 TRACE("infered alias: " + type);
1634 m_typeTable->registerAlias(type, info);
1637 if (info == 0) {
1638 TRACE("unknown type "+type);
1639 cmd->m_expr->m_type = TypeInfo::unknownType();
1640 } else {
1641 cmd->m_expr->m_type = info;
1642 /* since this node has a new type, we get its value immediately */
1643 evalInitialStructExpression(cmd->m_expr, cmd->m_exprWnd, false);
1644 return;
1648 evalExpressions(); /* queue more of them */
1651 void KDebugger::handlePrintStruct(CmdQueueItem* cmd, const char* output)
1653 VarTree* var = cmd->m_expr;
1654 ASSERT(var != 0);
1655 ASSERT(var->m_varKind == VarTree::VKstruct);
1657 ExprValue* partExpr;
1658 if (cmd->m_cmd == DCprintQStringStruct) {
1659 partExpr = m_d->parseQCharArray(output, false, m_typeTable->qCharIsShort());
1660 } else if (cmd->m_cmd == DCprintWChar) {
1661 partExpr = m_d->parseQCharArray(output, false, true);
1662 } else {
1663 partExpr = m_d->parsePrintExpr(output, false);
1665 bool errorValue =
1666 partExpr == 0 ||
1667 /* we only allow simple values at the moment */
1668 partExpr->m_child != 0;
1670 QString partValue;
1671 if (errorValue)
1673 partValue = "?""?""?"; // 2 question marks in a row would be a trigraph
1674 } else {
1675 partValue = partExpr->m_value;
1677 delete partExpr;
1678 partExpr = 0;
1681 * Updating a struct value works like this: var->m_partialValue holds
1682 * the value that we have gathered so far (it's been initialized with
1683 * var->m_type->m_displayString[0] earlier). Each time we arrive here,
1684 * we append the printed result followed by the next
1685 * var->m_type->m_displayString to var->m_partialValue.
1687 * If the expression we just evaluated was a guard expression, and it
1688 * resulted in an error, we must not evaluate the real expression, but
1689 * go on to the next index. (We must still add the question marks to
1690 * the value).
1692 * Next, if this was the length expression, we still have not seen the
1693 * real expression, but the length of a QString.
1695 ASSERT(var->m_exprIndex >= 0 && var->m_exprIndex <= typeInfoMaxExpr);
1697 if (errorValue || !var->m_exprIndexUseGuard)
1699 // add current partValue (which might be the question marks)
1700 var->m_partialValue += partValue;
1701 var->m_exprIndex++; /* next part */
1702 var->m_exprIndexUseGuard = true;
1703 var->m_partialValue += var->m_type->m_displayString[var->m_exprIndex];
1705 else
1707 // this was a guard expression that succeeded
1708 // go for the real expression
1709 var->m_exprIndexUseGuard = false;
1712 /* go for more sub-expressions if needed */
1713 if (var->m_exprIndex < var->m_type->m_numExprs) {
1714 /* queue a new print command with quite high priority */
1715 evalStructExpression(var, cmd->m_exprWnd, true);
1716 return;
1719 cmd->m_exprWnd->updateStructValue(var);
1721 evalExpressions(); /* enqueue dereferenced pointers */
1724 /* queues the first printStruct command for a struct */
1725 void KDebugger::evalInitialStructExpression(VarTree* var, ExprWnd* wnd, bool immediate)
1727 var->m_exprIndex = 0;
1728 if (var->m_type != TypeInfo::wchartType())
1730 var->m_exprIndexUseGuard = true;
1731 var->m_partialValue = var->m_type->m_displayString[0];
1732 evalStructExpression(var, wnd, immediate);
1734 else
1736 var->m_exprIndexUseGuard = false;
1737 QString expr = var->computeExpr();
1738 CmdQueueItem* cmd = m_d->queueCmd(DCprintWChar, expr,
1739 immediate ? DebuggerDriver::QMoverrideMoreEqual
1740 : DebuggerDriver::QMoverride);
1741 // remember which expression this was
1742 cmd->m_expr = var;
1743 cmd->m_exprWnd = wnd;
1747 /** queues a printStruct command; var must have been initialized correctly */
1748 void KDebugger::evalStructExpression(VarTree* var, ExprWnd* wnd, bool immediate)
1750 QString base = var->computeExpr();
1751 QString expr;
1752 if (var->m_exprIndexUseGuard) {
1753 expr = var->m_type->m_guardStrings[var->m_exprIndex];
1754 if (expr.isEmpty()) {
1755 // no guard, omit it and go to expression
1756 var->m_exprIndexUseGuard = false;
1759 if (!var->m_exprIndexUseGuard) {
1760 expr = var->m_type->m_exprStrings[var->m_exprIndex];
1763 expr.replace("%s", base);
1765 DbgCommand dbgCmd = DCprintStruct;
1766 // check if this is a QString::Data
1767 if (expr.left(15) == "/QString::Data ")
1769 if (m_typeTable->parseQt2QStrings())
1771 expr = expr.mid(15, expr.length()); /* strip off /QString::Data */
1772 dbgCmd = DCprintQStringStruct;
1773 } else {
1775 * This should not happen: the type libraries should be set up
1776 * in a way that this can't happen. If this happens
1777 * nevertheless it means that, eg., kdecore was loaded but qt2
1778 * was not (only qt2 enables the QString feature).
1780 // TODO: remove this "print"; queue the next printStruct instead
1781 expr = "*0";
1784 TRACE("evalStruct: " + expr + (var->m_exprIndexUseGuard ? " // guard" : " // real"));
1785 CmdQueueItem* cmd = m_d->queueCmd(dbgCmd, expr,
1786 immediate ? DebuggerDriver::QMoverrideMoreEqual
1787 : DebuggerDriver::QMnormal);
1789 // remember which expression this was
1790 cmd->m_expr = var;
1791 cmd->m_exprWnd = wnd;
1794 void KDebugger::handleSharedLibs(const char* output)
1796 // parse the table of shared libraries
1797 m_sharedLibs = m_d->parseSharedLibs(output);
1798 m_sharedLibsListed = true;
1800 // get type libraries
1801 m_typeTable->loadLibTypes(m_sharedLibs);
1803 // hand over the QString data cmd
1804 m_d->setPrintQStringDataCmd(m_typeTable->printQStringDataCmd());
1807 CmdQueueItem* KDebugger::loadCoreFile()
1809 return m_d->queueCmd(DCcorefile, m_corefile, DebuggerDriver::QMoverride);
1812 void KDebugger::slotExpanding(QListViewItem* item)
1814 VarTree* exprItem = static_cast<VarTree*>(item);
1815 if (exprItem->m_varKind != VarTree::VKpointer) {
1816 return;
1818 ExprWnd* wnd = static_cast<ExprWnd*>(item->listView());
1819 dereferencePointer(wnd, exprItem, true);
1822 // add the expression in the edit field to the watch expressions
1823 void KDebugger::addWatch(const QString& t)
1825 QString expr = t.stripWhiteSpace();
1826 // don't add a watched expression again
1827 if (expr.isEmpty() || m_watchVariables.topLevelExprByName(expr) != 0)
1828 return;
1829 ExprValue e(expr, VarTree::NKplain);
1830 m_watchVariables.insertExpr(&e, *m_typeTable);
1832 // if we are boring ourselves, send down the command
1833 if (m_programActive) {
1834 m_watchEvalExpr.push_back(expr);
1835 if (m_d->isIdle()) {
1836 evalExpressions();
1841 // delete a toplevel watch expression
1842 void KDebugger::slotDeleteWatch()
1844 // delete only allowed while debugger is idle; or else we might delete
1845 // the very expression the debugger is currently working on...
1846 if (m_d == 0 || !m_d->isIdle())
1847 return;
1849 VarTree* item = m_watchVariables.currentItem();
1850 if (item == 0 || !item->isToplevelExpr())
1851 return;
1853 // remove the variable from the list to evaluate
1854 QStringList::iterator i = m_watchEvalExpr.find(item->getText());
1855 if (i != m_watchEvalExpr.end()) {
1856 m_watchEvalExpr.erase(i);
1858 m_watchVariables.removeExpr(item);
1859 // item is invalid at this point!
1862 void KDebugger::handleRegisters(const char* output)
1864 emit registersChanged(m_d->parseRegisters(output));
1868 * The output of the DCbreak* commands has more accurate information about
1869 * the file and the line number.
1871 * All newly set breakpoints are inserted in the m_brkpts, even those that
1872 * were not set sucessfully. The unsuccessful breakpoints ("orphaned
1873 * breakpoints") are assigned negative ids, and they are tried to set later
1874 * when the program stops again at a breakpoint.
1876 void KDebugger::newBreakpoint(CmdQueueItem* cmd, const char* output)
1878 BrkptIterator bp;
1879 if (cmd->m_brkpt != 0) {
1880 // a new breakpoint, put it in the list
1881 assert(cmd->m_brkpt->id == 0);
1882 m_brkpts.push_back(*cmd->m_brkpt);
1883 delete cmd->m_brkpt;
1884 bp = m_brkpts.end();
1885 --bp;
1886 } else {
1887 // an existing breakpoint was retried
1888 assert(cmd->m_existingBrkpt != 0);
1889 bp = breakpointById(cmd->m_existingBrkpt);
1890 if (bp == m_brkpts.end())
1891 return;
1894 // parse the output to determine success or failure
1895 int id;
1896 QString file;
1897 int lineNo;
1898 QString address;
1899 if (!m_d->parseBreakpoint(output, id, file, lineNo, address))
1902 * Failure, the breakpoint could not be set. If this is a new
1903 * breakpoint, assign it a negative id. We look for the minimal id
1904 * of all breakpoints (that are already in the list) to get the new
1905 * id.
1907 if (bp->id == 0)
1909 int minId = 0;
1910 for (BrkptIterator i = m_brkpts.begin(); i != m_brkpts.end(); ++i) {
1911 if (i->id < minId)
1912 minId = i->id;
1914 bp->id = minId-1;
1916 return;
1919 // The breakpoint was successfully set.
1920 if (bp->id <= 0)
1922 // this is a new or orphaned breakpoint:
1923 // set the remaining properties
1924 if (!bp->enabled) {
1925 m_d->executeCmd(DCdisable, id);
1927 if (!bp->condition.isEmpty()) {
1928 m_d->executeCmd(DCcondition, bp->condition, id);
1932 bp->id = id;
1933 bp->fileName = file;
1934 bp->lineNo = lineNo;
1935 if (!address.isEmpty())
1936 bp->address = address;
1939 void KDebugger::updateBreakList(const char* output)
1941 // get the new list
1942 std::list<Breakpoint> brks;
1943 m_d->parseBreakList(output, brks);
1945 // merge existing information into the new list
1946 // then swap the old and new lists
1948 for (BrkptIterator bp = brks.begin(); bp != brks.end(); ++bp)
1950 BrkptIterator i = breakpointById(bp->id);
1951 if (i != m_brkpts.end())
1953 // preserve accurate location information
1954 // note that xsldbg doesn't have a location in
1955 // the listed breakpoint if it has just been set
1956 // therefore, we copy it as well if necessary
1957 bp->text = i->text;
1958 if (!i->fileName.isEmpty()) {
1959 bp->fileName = i->fileName;
1960 bp->lineNo = i->lineNo;
1965 // orphaned breakpoints must be copied
1966 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
1968 if (bp->isOrphaned())
1969 brks.push_back(*bp);
1972 m_brkpts.swap(brks);
1973 emit breakpointsChanged();
1976 // look if there is at least one temporary breakpoint
1977 // or a watchpoint
1978 bool KDebugger::stopMayChangeBreakList() const
1980 for (BrkptROIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
1982 if (bp->temporary || bp->type == Breakpoint::watchpoint)
1983 return true;
1985 return false;
1988 KDebugger::BrkptIterator KDebugger::breakpointByFilePos(QString file, int lineNo,
1989 const DbgAddr& address)
1991 // look for exact file name match
1992 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
1994 if (bp->lineNo == lineNo &&
1995 bp->fileName == file &&
1996 (address.isEmpty() || bp->address == address))
1998 return bp;
2001 // not found, so try basename
2002 // strip off directory part of file name
2003 int offset = file.findRev("/");
2004 file.remove(0, offset+1);
2006 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
2008 // get base name of breakpoint's file
2009 QString basename = bp->fileName;
2010 int offset = basename.findRev("/");
2011 if (offset >= 0) {
2012 basename.remove(0, offset+1);
2015 if (bp->lineNo == lineNo &&
2016 basename == file &&
2017 (address.isEmpty() || bp->address == address))
2019 return bp;
2023 // not found
2024 return m_brkpts.end();
2027 KDebugger::BrkptIterator KDebugger::breakpointById(int id)
2029 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
2031 if (bp->id == id) {
2032 return bp;
2035 // not found
2036 return m_brkpts.end();
2039 void KDebugger::slotValuePopup(const QString& expr)
2041 // search the local variables for a match
2042 VarTree* v = m_localVariables.topLevelExprByName(expr);
2043 if (v == 0) {
2044 // not found, check watch expressions
2045 v = m_watchVariables.topLevelExprByName(expr);
2046 if (v == 0) {
2047 // try a member of 'this'
2048 v = m_localVariables.topLevelExprByName("this");
2049 if (v != 0)
2050 v = ExprWnd::ptrMemberByName(v, expr);
2051 if (v == 0) {
2052 // nothing found; do nothing
2053 return;
2058 // construct the tip
2059 QString tip = v->getText() + " = ";
2060 if (!v->value().isEmpty())
2062 tip += v->value();
2064 else
2066 // no value: we use some hint
2067 switch (v->m_varKind) {
2068 case VarTree::VKstruct:
2069 tip += "{...}";
2070 break;
2071 case VarTree::VKarray:
2072 tip += "[...]";
2073 break;
2074 default:
2075 tip += "?""?""?"; // 2 question marks in a row would be a trigraph
2076 break;
2079 emit valuePopup(tip);
2082 void KDebugger::slotDisassemble(const QString& fileName, int lineNo)
2084 if (m_haveExecutable) {
2085 CmdQueueItem* cmd = m_d->queueCmd(DCinfoline, fileName, lineNo,
2086 DebuggerDriver::QMoverrideMoreEqual);
2087 cmd->m_fileName = fileName;
2088 cmd->m_lineNo = lineNo;
2092 void KDebugger::handleInfoLine(CmdQueueItem* cmd, const char* output)
2094 QString addrFrom, addrTo;
2095 if (cmd->m_lineNo >= 0) {
2096 // disassemble
2097 if (m_d->parseInfoLine(output, addrFrom, addrTo)) {
2098 // got the address range, now get the real code
2099 CmdQueueItem* c = m_d->queueCmd(DCdisassemble, addrFrom, addrTo,
2100 DebuggerDriver::QMoverrideMoreEqual);
2101 c->m_fileName = cmd->m_fileName;
2102 c->m_lineNo = cmd->m_lineNo;
2103 } else {
2104 // no code
2105 emit disassembled(cmd->m_fileName, cmd->m_lineNo, std::list<DisassembledCode>());
2107 } else {
2108 // set program counter
2109 if (m_d->parseInfoLine(output, addrFrom, addrTo)) {
2110 // move the program counter to the start address
2111 m_d->executeCmd(DCsetpc, addrFrom);
2116 void KDebugger::handleDisassemble(CmdQueueItem* cmd, const char* output)
2118 emit disassembled(cmd->m_fileName, cmd->m_lineNo,
2119 m_d->parseDisassemble(output));
2122 void KDebugger::handleThreadList(const char* output)
2124 emit threadsChanged(m_d->parseThreadList(output));
2127 void KDebugger::setThread(int id)
2129 m_d->queueCmd(DCthread, id, DebuggerDriver::QMoverrideMoreEqual);
2132 void KDebugger::setMemoryExpression(const QString& memexpr)
2134 m_memoryExpression = memexpr;
2136 // queue the new expression
2137 if (!m_memoryExpression.isEmpty() &&
2138 isProgramActive() &&
2139 !isProgramRunning())
2141 queueMemoryDump(true);
2145 void KDebugger::queueMemoryDump(bool immediate)
2147 m_d->queueCmd(DCexamine, m_memoryExpression, m_memoryFormat,
2148 immediate ? DebuggerDriver::QMoverrideMoreEqual :
2149 DebuggerDriver::QMoverride);
2152 void KDebugger::handleMemoryDump(const char* output)
2154 std::list<MemoryDump> memdump;
2155 QString msg = m_d->parseMemoryDump(output, memdump);
2156 emit memoryDumpChanged(msg, memdump);
2159 void KDebugger::setProgramCounter(const QString& file, int line, const DbgAddr& addr)
2161 if (addr.isEmpty()) {
2162 // find address of the specified line
2163 CmdQueueItem* cmd = m_d->executeCmd(DCinfoline, file, line);
2164 cmd->m_lineNo = -1; /* indicates "Set PC" UI command */
2165 } else {
2166 // move the program counter to that address
2167 m_d->executeCmd(DCsetpc, addr.asString());
2171 void KDebugger::handleSetPC(const char* /*output*/)
2173 // TODO: handle errors
2175 // now go to the top-most frame
2176 // this also modifies the program counter indicator in the UI
2177 gotoFrame(0);
2180 void KDebugger::slotValueEdited(VarTree* expr, const QString& text)
2182 if (text.simplifyWhiteSpace().isEmpty())
2183 return; /* no text entered: ignore request */
2185 ExprWnd* wnd = static_cast<ExprWnd*>(expr->listView());
2186 TRACE(QString().sprintf("Changing %s to ",
2187 wnd->name()) + text);
2189 // determine the lvalue to edit
2190 QString lvalue = expr->computeExpr();
2191 CmdQueueItem* cmd = m_d->executeCmd(DCsetvariable, lvalue, text);
2192 cmd->m_expr = expr;
2193 cmd->m_exprWnd = wnd;
2196 void KDebugger::handleSetVariable(CmdQueueItem* cmd, const char* output)
2198 QString msg = m_d->parseSetVariable(output);
2199 if (!msg.isEmpty())
2201 // there was an error; display it in the status bar
2202 m_statusMessage = msg;
2203 emit updateStatusMessage();
2204 return;
2207 // get the new value
2208 QString expr = cmd->m_expr->computeExpr();
2209 CmdQueueItem* printCmd =
2210 m_d->queueCmd(DCprint, expr, DebuggerDriver::QMoverrideMoreEqual);
2211 printCmd->m_expr = cmd->m_expr;
2212 printCmd->m_exprWnd = cmd->m_exprWnd;
2216 #include "debugger.moc"