Show threads when attaching to a remote target.
[kdbg.git] / kdbg / debugger.cpp
blob9bac13a76ccb6059c74d6d05a0aae5d0b6ea1f86
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 <QFileInfo>
14 #include <QListWidget>
15 #include <QApplication>
16 #include <kcodecs.h> // KMD5
17 #include <kconfig.h>
18 #include <klocale.h> /* i18n */
19 #include <kmessagebox.h>
20 #include <kstandarddirs.h>
21 #include <ctype.h>
22 #include <stdlib.h> /* strtol, atoi */
23 #include <unistd.h> /* sleep(3) */
24 #include <algorithm>
25 #include "mydebug.h"
28 KDebugger::KDebugger(QWidget* parent,
29 ExprWnd* localVars,
30 ExprWnd* watchVars,
31 QListWidget* backtrace) :
32 QObject(parent),
33 m_ttyLevel(ttyFull),
34 m_memoryFormat(MDTword | MDThex),
35 m_haveExecutable(false),
36 m_programActive(false),
37 m_programRunning(false),
38 m_sharedLibsListed(false),
39 m_typeTable(0),
40 m_programConfig(0),
41 m_d(0),
42 m_localVariables(*localVars),
43 m_watchVariables(*watchVars),
44 m_btWindow(*backtrace)
46 connect(&m_localVariables, SIGNAL(itemExpanded(QTreeWidgetItem*)),
47 SLOT(slotExpanding(QTreeWidgetItem*)));
48 connect(&m_watchVariables, SIGNAL(itemExpanded(QTreeWidgetItem*)),
49 SLOT(slotExpanding(QTreeWidgetItem*)));
50 connect(&m_localVariables, SIGNAL(editValueCommitted(VarTree*, const QString&)),
51 SLOT(slotValueEdited(VarTree*, const QString&)));
52 connect(&m_watchVariables, SIGNAL(editValueCommitted(VarTree*, const QString&)),
53 SLOT(slotValueEdited(VarTree*, const QString&)));
55 connect(&m_btWindow, SIGNAL(currentRowChanged(int)), this, SLOT(gotoFrame(int)));
57 emit updateUI();
60 KDebugger::~KDebugger()
62 if (m_programConfig != 0) {
63 saveProgramSettings();
64 m_programConfig->sync();
65 delete m_programConfig;
68 delete m_typeTable;
72 void KDebugger::saveSettings(KConfig* /*config*/)
76 void KDebugger::restoreSettings(KConfig* /*config*/)
81 //////////////////////////////////////////////////////////////////////
82 // external interface
84 const char GeneralGroup[] = "General";
85 const char DebuggerCmdStr[] = "DebuggerCmdStr";
86 const char TTYLevelEntry[] = "TTYLevel";
87 const char KDebugger::DriverNameEntry[] = "DriverName";
89 bool KDebugger::debugProgram(const QString& name,
90 DebuggerDriver* driver)
92 if (m_d != 0 && m_d->isRunning())
94 QApplication::setOverrideCursor(Qt::WaitCursor);
96 stopDriver();
98 QApplication::restoreOverrideCursor();
100 if (m_d->isRunning() || m_haveExecutable) {
101 /* timed out! We can't really do anything useful now */
102 TRACE("timed out while waiting for gdb to die!");
103 return false;
105 delete m_d;
106 m_d = 0;
109 // wire up the driver
110 connect(driver, SIGNAL(activateFileLine(const QString&,int,const DbgAddr&)),
111 this, SIGNAL(activateFileLine(const QString&,int,const DbgAddr&)));
112 connect(driver, SIGNAL(finished(int, QProcess::ExitStatus)),
113 SLOT(gdbExited()));
114 connect(driver, SIGNAL(commandReceived(CmdQueueItem*,const char*)),
115 SLOT(parse(CmdQueueItem*,const char*)));
116 connect(driver, SIGNAL(bytesWritten(qint64)), SIGNAL(updateUI()));
117 connect(driver, SIGNAL(inferiorRunning()), SLOT(slotInferiorRunning()));
118 connect(driver, SIGNAL(enterIdleState()), SLOT(backgroundUpdate()));
119 connect(driver, SIGNAL(enterIdleState()), SIGNAL(updateUI()));
120 connect(&m_localVariables, SIGNAL(removingItem(VarTree*)),
121 driver, SLOT(dequeueCmdByVar(VarTree*)));
122 connect(&m_watchVariables, SIGNAL(removingItem(VarTree*)),
123 driver, SLOT(dequeueCmdByVar(VarTree*)));
125 // create the program settings object
126 openProgramConfig(name);
128 // get debugger command from per-program settings
129 if (m_programConfig != 0) {
130 KConfigGroup g = m_programConfig->group(GeneralGroup);
131 m_debuggerCmd = readDebuggerCmd(g);
132 // get terminal emulation level
133 m_ttyLevel = TTYLevel(g.readEntry(TTYLevelEntry, int(ttyFull)));
135 // the rest is read in later in the handler of DCexecutable
137 m_d = driver;
139 if (!startDriver()) {
140 TRACE("startDriver failed");
141 m_d = 0;
142 return false;
145 TRACE("before file cmd");
146 m_d->executeCmd(DCexecutable, name);
147 m_executable = name;
149 // set remote target
150 if (!m_remoteDevice.isEmpty()) {
151 m_d->executeCmd(DCtargetremote, m_remoteDevice);
152 m_d->queueCmd(DCbt, DebuggerDriver::QMoverride);
153 m_d->queueCmd(DCinfothreads, DebuggerDriver::QMoverride);
154 m_d->queueCmd(DCframe, 0, DebuggerDriver::QMnormal);
155 m_programActive = true;
156 m_haveExecutable = true;
159 // create a type table
160 m_typeTable = new ProgramTypeTable;
161 m_sharedLibsListed = false;
163 emit updateUI();
165 return true;
168 void KDebugger::shutdown()
170 // shut down debugger driver
171 if (m_d != 0 && m_d->isRunning())
173 stopDriver();
177 void KDebugger::useCoreFile(QString corefile, bool batch)
179 m_corefile = corefile;
180 if (!batch) {
181 CmdQueueItem* cmd = loadCoreFile();
182 cmd->m_byUser = true;
186 void KDebugger::setAttachPid(const QString& pid)
188 m_attachedPid = pid;
191 void KDebugger::programRun()
193 if (!isReady())
194 return;
196 // when program is active, but not a core file, continue
197 // otherwise run the program
198 if (m_programActive && m_corefile.isEmpty()) {
199 // gdb command: continue
200 m_d->executeCmd(DCcont, true);
201 } else {
202 // gdb command: run
203 m_d->executeCmd(DCrun, true);
204 m_corefile = QString();
205 m_programActive = true;
207 m_programRunning = true;
210 void KDebugger::attachProgram(const QString& pid)
212 if (!isReady())
213 return;
215 m_attachedPid = pid;
216 TRACE("Attaching to " + m_attachedPid);
217 m_d->executeCmd(DCattach, m_attachedPid);
218 m_programActive = true;
219 m_programRunning = true;
222 void KDebugger::programRunAgain()
224 if (canSingleStep()) {
225 m_d->executeCmd(DCrun, true);
226 m_corefile = QString();
227 m_programRunning = true;
231 void KDebugger::programStep()
233 if (canSingleStep()) {
234 m_d->executeCmd(DCstep, true);
235 m_programRunning = true;
239 void KDebugger::programNext()
241 if (canSingleStep()) {
242 m_d->executeCmd(DCnext, true);
243 m_programRunning = true;
247 void KDebugger::programStepi()
249 if (canSingleStep()) {
250 m_d->executeCmd(DCstepi, true);
251 m_programRunning = true;
255 void KDebugger::programNexti()
257 if (canSingleStep()) {
258 m_d->executeCmd(DCnexti, true);
259 m_programRunning = true;
263 void KDebugger::programFinish()
265 if (canSingleStep()) {
266 m_d->executeCmd(DCfinish, true);
267 m_programRunning = true;
271 void KDebugger::programKill()
273 if (haveExecutable() && isProgramActive()) {
274 if (m_programRunning) {
275 m_d->interruptInferior();
277 // this is an emergency command; flush queues
278 m_d->flushCommands(true);
279 m_d->executeCmd(DCkill, true);
283 bool KDebugger::runUntil(const QString& fileName, int lineNo)
285 if (isReady() && m_programActive && !m_programRunning) {
286 // strip off directory part of file name
287 QFileInfo fi(fileName);
288 m_d->executeCmd(DCuntil, fi.fileName(), lineNo, true);
289 m_programRunning = true;
290 return true;
291 } else {
292 return false;
296 void KDebugger::programBreak()
298 if (m_haveExecutable && m_programRunning) {
299 m_d->interruptInferior();
303 void KDebugger::programArgs(QWidget* parent)
305 if (m_haveExecutable) {
306 QStringList allOptions = m_d->boolOptionList();
307 PgmArgs dlg(parent, m_executable, m_envVars, allOptions);
308 dlg.setArgs(m_programArgs);
309 dlg.setWd(m_programWD);
310 dlg.setOptions(m_boolOptions);
311 if (dlg.exec()) {
312 updateProgEnvironment(dlg.args(), dlg.wd(),
313 dlg.envVars(), dlg.options());
318 void KDebugger::programSettings(QWidget* parent)
320 if (!m_haveExecutable)
321 return;
323 ProgramSettings dlg(parent, m_executable);
325 dlg.m_chooseDriver.setDebuggerCmd(m_debuggerCmd);
326 dlg.m_output.setTTYLevel(m_ttyLevel);
328 if (dlg.exec() == QDialog::Accepted)
330 m_debuggerCmd = dlg.m_chooseDriver.debuggerCmd();
331 m_ttyLevel = TTYLevel(dlg.m_output.ttyLevel());
335 bool KDebugger::setBreakpoint(QString file, int lineNo,
336 const DbgAddr& address, bool temporary)
338 if (!isReady()) {
339 return false;
342 BrkptIterator bp = breakpointByFilePos(file, lineNo, address);
343 if (bp == m_brkpts.end())
346 * No such breakpoint, so set a new one. If we have an address, we
347 * set the breakpoint exactly there. Otherwise we use the file name
348 * plus line no.
350 Breakpoint* bp = new Breakpoint;
351 bp->temporary = temporary;
353 if (address.isEmpty())
355 bp->fileName = file;
356 bp->lineNo = lineNo;
358 else
360 bp->address = address;
362 setBreakpoint(bp, false);
364 else
367 * If the breakpoint is disabled, enable it; if it's enabled,
368 * delete that breakpoint.
370 if (bp->enabled) {
371 deleteBreakpoint(bp);
372 } else {
373 enableDisableBreakpoint(bp);
376 return true;
379 void KDebugger::setBreakpoint(Breakpoint* bp, bool queueOnly)
381 CmdQueueItem* cmd = executeBreakpoint(bp, queueOnly);
382 cmd->m_brkpt = bp; // used in newBreakpoint()
385 CmdQueueItem* KDebugger::executeBreakpoint(const Breakpoint* bp, bool queueOnly)
387 CmdQueueItem* cmd;
388 if (!bp->text.isEmpty())
391 * The breakpoint was set using the text box in the breakpoint
392 * list. This is the only way in which watchpoints are set.
394 if (bp->type == Breakpoint::watchpoint) {
395 cmd = m_d->executeCmd(DCwatchpoint, bp->text);
396 } else {
397 cmd = m_d->executeCmd(DCbreaktext, bp->text);
400 else if (bp->address.isEmpty())
402 // strip off directory part of file name
403 QString file = QFileInfo(bp->fileName).fileName();
404 if (queueOnly) {
405 cmd = m_d->queueCmd(bp->temporary ? DCtbreakline : DCbreakline,
406 file, bp->lineNo, DebuggerDriver::QMoverride);
407 } else {
408 cmd = m_d->executeCmd(bp->temporary ? DCtbreakline : DCbreakline,
409 file, bp->lineNo);
412 else
414 if (queueOnly) {
415 cmd = m_d->queueCmd(bp->temporary ? DCtbreakaddr : DCbreakaddr,
416 bp->address.asString(), DebuggerDriver::QMoverride);
417 } else {
418 cmd = m_d->executeCmd(bp->temporary ? DCtbreakaddr : DCbreakaddr,
419 bp->address.asString());
422 return cmd;
425 bool KDebugger::infoLine(QString file, int lineNo, const DbgAddr& addr)
427 if (isReady() && !m_programRunning) {
428 CmdQueueItem* cmd = m_d->executeCmd(DCinfoline, file, lineNo);
429 cmd->m_addr = addr;
430 return true;
431 } else {
432 return false;
436 bool KDebugger::enableDisableBreakpoint(QString file, int lineNo,
437 const DbgAddr& address)
439 BrkptIterator bp = breakpointByFilePos(file, lineNo, address);
440 return enableDisableBreakpoint(bp);
443 bool KDebugger::enableDisableBreakpoint(BrkptIterator bp)
445 if (bp == m_brkpts.end())
446 return false;
449 * Toggle enabled/disabled state.
451 * The driver is not bothered if we are modifying an orphaned
452 * breakpoint.
454 if (!bp->isOrphaned()) {
455 if (!canChangeBreakpoints()) {
456 return false;
458 m_d->executeCmd(bp->enabled ? DCdisable : DCenable, bp->id);
459 } else {
460 bp->enabled = !bp->enabled;
461 emit breakpointsChanged();
463 return true;
466 bool KDebugger::conditionalBreakpoint(BrkptIterator bp,
467 const QString& condition,
468 int ignoreCount)
470 if (bp == m_brkpts.end())
471 return false;
474 * Change the condition and ignore count.
476 * The driver is not bothered if we are removing an orphaned
477 * breakpoint.
480 if (!bp->isOrphaned()) {
481 if (!canChangeBreakpoints()) {
482 return false;
485 bool changed = false;
487 if (bp->condition != condition) {
488 // change condition
489 m_d->executeCmd(DCcondition, condition, bp->id);
490 changed = true;
492 if (bp->ignoreCount != ignoreCount) {
493 // change ignore count
494 m_d->executeCmd(DCignore, bp->id, ignoreCount);
495 changed = true;
497 if (changed) {
498 // get the changes
499 m_d->queueCmd(DCinfobreak, DebuggerDriver::QMoverride);
501 } else {
502 bp->condition = condition;
503 bp->ignoreCount = ignoreCount;
504 emit breakpointsChanged();
506 return true;
509 bool KDebugger::deleteBreakpoint(BrkptIterator bp)
511 if (bp == m_brkpts.end())
512 return false;
515 * Remove the breakpoint.
517 * The driver is not bothered if we are removing an orphaned
518 * breakpoint.
520 if (!bp->isOrphaned()) {
521 if (!canChangeBreakpoints()) {
522 return false;
524 m_d->executeCmd(DCdelete, bp->id);
525 } else {
526 m_brkpts.erase(bp);
527 emit breakpointsChanged();
529 return false;
532 bool KDebugger::canSingleStep()
534 return isReady() && m_programActive && !m_programRunning;
537 bool KDebugger::canChangeBreakpoints()
539 return isReady() && !m_programRunning;
542 bool KDebugger::canStart()
544 return isReady() && !m_programActive;
547 bool KDebugger::isReady() const
549 return m_haveExecutable &&
550 m_d != 0 && m_d->canExecuteImmediately();
553 bool KDebugger::isIdle() const
555 return m_d == 0 || m_d->isIdle();
559 //////////////////////////////////////////////////////////
560 // debugger driver
562 bool KDebugger::startDriver()
564 emit debuggerStarting(); /* must set m_inferiorTerminal */
567 * If the per-program command string is empty, use the global setting
568 * (which might also be empty, in which case the driver uses its
569 * default).
571 m_explicitKill = false;
572 if (!m_d->startup(m_debuggerCmd)) {
573 return false;
577 * If we have an output terminal, we use it. Otherwise we will run the
578 * program with input and output redirected to /dev/null. Other
579 * redirections are also necessary depending on the tty emulation
580 * level.
582 int redirect = RDNstdin|RDNstdout|RDNstderr; /* redirect everything */
583 if (!m_inferiorTerminal.isEmpty()) {
584 switch (m_ttyLevel) {
585 default:
586 case ttyNone:
587 // redirect everything
588 break;
589 case ttySimpleOutputOnly:
590 redirect = RDNstdin;
591 break;
592 case ttyFull:
593 redirect = 0;
594 break;
597 m_d->executeCmd(DCtty, m_inferiorTerminal, redirect);
599 return true;
602 void KDebugger::stopDriver()
604 m_explicitKill = true;
606 if (m_attachedPid.isEmpty()) {
607 m_d->terminate();
608 } else {
609 m_d->detachAndTerminate();
613 * We MUST wait until the slot gdbExited() has been called. But to
614 * avoid a deadlock, we wait only for some certain maximum time. Should
615 * this timeout be reached, the only reasonable thing one could do then
616 * is exiting kdbg.
618 QApplication::processEvents(QEventLoop::AllEvents, 1000);
619 int maxTime = 20; /* about 20 seconds */
620 while (m_haveExecutable && maxTime > 0) {
621 // give gdb time to die (and send a SIGCLD)
622 ::sleep(1);
623 --maxTime;
624 QApplication::processEvents(QEventLoop::AllEvents, 1000);
628 void KDebugger::gdbExited()
631 * Save settings, but only if gdb has already processed "info line
632 * main", otherwise we would save an empty config file, because it
633 * isn't read in until then!
635 if (m_programConfig != 0) {
636 if (m_haveExecutable) {
637 saveProgramSettings();
638 m_programConfig->sync();
640 delete m_programConfig;
641 m_programConfig = 0;
644 // erase types
645 delete m_typeTable;
646 m_typeTable = 0;
648 if (m_explicitKill) {
649 TRACE(m_d->driverName() + " exited normally");
650 } else {
651 QString msg = i18n("%1 exited unexpectedly.\n"
652 "Restart the session (e.g. with File|Executable).");
653 KMessageBox::error(parentWidget(), msg.arg(m_d->driverName()));
656 // reset state
657 m_haveExecutable = false;
658 m_executable = "";
659 m_programActive = false;
660 m_programRunning = false;
661 m_explicitKill = false;
662 m_debuggerCmd = QString(); /* use global setting at next start! */
663 m_attachedPid = QString(); /* we are no longer attached to a process */
664 m_ttyLevel = ttyFull;
665 m_brkpts.clear();
667 // erase PC
668 emit updatePC(QString(), -1, DbgAddr(), 0);
671 QString KDebugger::getConfigForExe(const QString& name)
673 QFileInfo fi(name);
674 QString dir = fi.absolutePath();
676 // The session file for the given executable consists of
677 // a hash of the directory, followed by the program name.
678 // Assume that the first 15 positions of the hash are unique;
679 // this keeps the file names short.
680 QString hash = KMD5(dir.toUtf8()).base64Digest();
681 hash.replace('/', QString()); // avoid directory separators
682 QString pgmConfigFile = hash.left(15) + "-" + fi.fileName();
683 pgmConfigFile = KStandardDirs::locateLocal("sessions", pgmConfigFile);
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 KConfig(pgmConfigFile);
696 // this leaves a clue behind in the config file which
697 // executable it applies to; it is mostly intended for
698 // users peeking into the file
699 KConfigGroup g = m_programConfig->group(GeneralGroup);
700 g.writeEntry("ExecutableFile", name);
703 const char EnvironmentGroup[] = "Environment";
704 const char WatchGroup[] = "Watches";
705 const char FileVersion[] = "FileVersion";
706 const char ProgramArgs[] = "ProgramArgs";
707 const char WorkingDirectory[] = "WorkingDirectory";
708 const char OptionsSelected[] = "OptionsSelected";
709 const char Variable[] = "Var%d";
710 const char Value[] = "Value%d";
711 const char ExprFmt[] = "Expr%d";
713 void KDebugger::saveProgramSettings()
715 ASSERT(m_programConfig != 0);
716 KConfigGroup gg = m_programConfig->group(GeneralGroup);
717 gg.writeEntry(FileVersion, 1);
718 gg.writeEntry(ProgramArgs, m_programArgs);
719 gg.writeEntry(WorkingDirectory, m_programWD);
720 gg.writeEntry(OptionsSelected, m_boolOptions.toList());
721 gg.writeEntry(DebuggerCmdStr, m_debuggerCmd);
722 gg.writeEntry(TTYLevelEntry, int(m_ttyLevel));
723 QString driverName;
724 if (m_d != 0)
725 driverName = m_d->driverName();
726 gg.writeEntry(DriverNameEntry, driverName);
728 // write environment variables
729 m_programConfig->deleteGroup(EnvironmentGroup);
730 KConfigGroup eg = m_programConfig->group(EnvironmentGroup);
731 QString varName;
732 QString varValue;
733 int i = 0;
734 for (std::map<QString,QString>::iterator it = m_envVars.begin(); it != m_envVars.end(); ++it, ++i)
736 varName.sprintf(Variable, i);
737 varValue.sprintf(Value, i);
738 eg.writeEntry(varName, it->first);
739 eg.writeEntry(varValue, it->second);
742 saveBreakpoints(m_programConfig);
744 // watch expressions
745 // first get rid of whatever was in this group
746 m_programConfig->deleteGroup(WatchGroup);
747 // then start a new group
748 KConfigGroup wg = m_programConfig->group(WatchGroup);
749 int watchNum = 0;
750 foreach (QString expr, m_watchVariables.exprList()) {
751 varName.sprintf(ExprFmt, watchNum++);
752 wg.writeEntry(varName, expr);
755 // give others a chance
756 emit saveProgramSpecific(m_programConfig);
759 void KDebugger::overrideProgramArguments(const QString& args)
761 ASSERT(m_programConfig != 0);
762 KConfigGroup g = m_programConfig->group(GeneralGroup);
763 g.writeEntry(ProgramArgs, args);
766 void KDebugger::restoreProgramSettings()
768 ASSERT(m_programConfig != 0);
769 KConfigGroup gg = m_programConfig->group(GeneralGroup);
771 * We ignore file version for now we will use it in the future to
772 * distinguish different versions of this configuration file.
774 // m_debuggerCmd has been read in already
775 // m_ttyLevel has been read in already
776 QString pgmArgs = gg.readEntry(ProgramArgs);
777 QString pgmWd = gg.readEntry(WorkingDirectory);
778 QSet<QString> boolOptions = QSet<QString>::fromList(gg.readEntry(OptionsSelected, QStringList()));
779 m_boolOptions.clear();
781 // read environment variables
782 KConfigGroup eg = m_programConfig->group(EnvironmentGroup);
783 m_envVars.clear();
784 std::map<QString,EnvVar> pgmVars;
785 QString varName;
786 QString varValue;
787 for (int i = 0;; ++i) {
788 varName.sprintf(Variable, i);
789 varValue.sprintf(Value, i);
790 if (!eg.hasKey(varName)) {
791 /* entry not present, assume that we've hit them all */
792 break;
794 QString name = eg.readEntry(varName, QString());
795 if (name.isEmpty()) {
796 // skip empty names
797 continue;
799 EnvVar* var = &pgmVars[name];
800 var->value = eg.readEntry(varValue, QString());
801 var->status = EnvVar::EVnew;
804 updateProgEnvironment(pgmArgs, pgmWd, pgmVars, boolOptions);
806 restoreBreakpoints(m_programConfig);
808 // watch expressions
809 KConfigGroup wg = m_programConfig->group(WatchGroup);
810 m_watchVariables.clear();
811 for (int i = 0;; ++i) {
812 varName.sprintf(ExprFmt, i);
813 if (!wg.hasKey(varName)) {
814 /* entry not present, assume that we've hit them all */
815 break;
817 QString expr = wg.readEntry(varName, QString());
818 if (expr.isEmpty()) {
819 // skip empty expressions
820 continue;
822 addWatch(expr);
825 // give others a chance
826 emit restoreProgramSpecific(m_programConfig);
830 * Reads the debugger command line from the program settings. The config
831 * group must have been set by the caller.
833 QString KDebugger::readDebuggerCmd(const KConfigGroup& g)
835 QString debuggerCmd = g.readEntry(DebuggerCmdStr);
837 // always let the user confirm the debugger cmd if we are root
838 if (::geteuid() == 0)
840 if (!debuggerCmd.isEmpty()) {
841 QString msg = i18n(
842 "The settings for this program specify "
843 "the following debugger command:\n%1\n"
844 "Shall this command be used?");
845 if (KMessageBox::warningYesNo(parentWidget(), msg.arg(debuggerCmd))
846 != KMessageBox::Yes)
848 // don't use it
849 debuggerCmd = QString();
853 return debuggerCmd;
857 * Breakpoints are saved one per group.
859 const char BPGroup[] = "Breakpoint %d";
860 const char File[] = "File";
861 const char Line[] = "Line";
862 const char Text[] = "Text";
863 const char Address[] = "Address";
864 const char Temporary[] = "Temporary";
865 const char Enabled[] = "Enabled";
866 const char Condition[] = "Condition";
868 void KDebugger::saveBreakpoints(KConfig* config)
870 QString groupName;
871 int i = 0;
872 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
874 if (bp->type == Breakpoint::watchpoint)
875 continue; /* don't save watchpoints */
876 groupName.sprintf(BPGroup, i++);
878 /* remove remmants */
879 config->deleteGroup(groupName);
881 KConfigGroup g = config->group(groupName);
882 if (!bp->text.isEmpty()) {
884 * The breakpoint was set using the text box in the breakpoint
885 * list. We do not save the location by filename+line number,
886 * but instead honor what the user typed (a function name, for
887 * example, which could move between sessions).
889 g.writeEntry(Text, bp->text);
890 } else if (!bp->fileName.isEmpty()) {
891 g.writeEntry(File, bp->fileName);
892 g.writeEntry(Line, bp->lineNo);
894 * Addresses are hardly correct across sessions, so we don't
895 * save it.
897 } else {
898 g.writeEntry(Address, bp->address.asString());
900 g.writeEntry(Temporary, bp->temporary);
901 g.writeEntry(Enabled, bp->enabled);
902 if (!bp->condition.isEmpty())
903 g.writeEntry(Condition, bp->condition);
904 // we do not save the ignore count
906 // delete remaining groups
907 // we recognize that a group is present if there is an Enabled entry
908 for (;; i++) {
909 groupName.sprintf(BPGroup, i);
910 if (!config->group(groupName).hasKey(Enabled)) {
911 /* group not present, assume that we've hit them all */
912 break;
914 config->deleteGroup(groupName);
918 void KDebugger::restoreBreakpoints(KConfig* config)
920 QString groupName;
922 * We recognize the end of the list if there is no Enabled entry
923 * present.
925 for (int i = 0;; i++) {
926 groupName.sprintf(BPGroup, i);
927 KConfigGroup g = config->group(groupName);
928 if (!g.hasKey(Enabled)) {
929 /* group not present, assume that we've hit them all */
930 break;
932 Breakpoint* bp = new Breakpoint;
933 bp->fileName = g.readEntry(File);
934 bp->lineNo = g.readEntry(Line, -1);
935 bp->text = g.readEntry(Text);
936 bp->address = g.readEntry(Address);
937 // check consistency
938 if ((bp->fileName.isEmpty() || bp->lineNo < 0) &&
939 bp->text.isEmpty() &&
940 bp->address.isEmpty())
942 delete bp;
943 continue;
945 bp->enabled = g.readEntry(Enabled, true);
946 bp->temporary = g.readEntry(Temporary, false);
947 bp->condition = g.readEntry(Condition);
950 * Add the breakpoint.
952 setBreakpoint(bp, false);
953 // the new breakpoint is disabled or conditionalized later
954 // in newBreakpoint()
956 m_d->queueCmd(DCinfobreak, DebuggerDriver::QMoverride);
960 // parse output of command cmd
961 void KDebugger::parse(CmdQueueItem* cmd, const char* output)
963 ASSERT(cmd != 0); /* queue mustn't be empty */
965 TRACE(QString(__PRETTY_FUNCTION__) + " parsing " + output);
967 switch (cmd->m_cmd) {
968 case DCtargetremote:
969 // the output (if any) is uninteresting
970 case DCsetargs:
971 case DCtty:
972 // there is no output
973 case DCsetenv:
974 case DCunsetenv:
975 case DCsetoption:
976 /* if value is empty, we see output, but we don't care */
977 break;
978 case DCcd:
979 /* display gdb's message in the status bar */
980 m_d->parseChangeWD(output, m_statusMessage);
981 emit updateStatusMessage();
982 break;
983 case DCinitialize:
984 break;
985 case DCexecutable:
986 if (m_d->parseChangeExecutable(output, m_statusMessage))
988 // success; restore breakpoints etc.
989 if (m_programConfig != 0) {
990 restoreProgramSettings();
992 // load file containing main() or core file
993 if (!m_corefile.isEmpty())
995 // load core file
996 loadCoreFile();
998 else if (!m_attachedPid.isEmpty())
1000 m_d->queueCmd(DCattach, m_attachedPid, DebuggerDriver::QMoverride);
1001 m_programActive = true;
1002 m_programRunning = true;
1004 else if (!m_remoteDevice.isEmpty())
1006 // handled elsewhere
1008 else
1010 m_d->queueCmd(DCinfolinemain, DebuggerDriver::QMnormal);
1012 if (!m_statusMessage.isEmpty())
1013 emit updateStatusMessage();
1014 } else {
1015 QString msg = m_d->driverName() + ": " + m_statusMessage;
1016 KMessageBox::sorry(parentWidget(), msg);
1017 m_executable = "";
1018 m_corefile = ""; /* don't process core file */
1019 m_haveExecutable = false;
1021 break;
1022 case DCcorefile:
1023 // in any event we have an executable at this point
1024 m_haveExecutable = true;
1025 if (m_d->parseCoreFile(output)) {
1026 // loading a core is like stopping at a breakpoint
1027 m_programActive = true;
1028 handleRunCommands(output);
1029 // do not reset m_corefile
1030 } else {
1031 // report error
1032 QString msg = m_d->driverName() + ": " + QString(output);
1033 KMessageBox::sorry(parentWidget(), msg);
1035 // if core file was loaded from command line, revert to info line main
1036 if (!cmd->m_byUser) {
1037 m_d->queueCmd(DCinfolinemain, DebuggerDriver::QMnormal);
1039 m_corefile = QString(); /* core file not available any more */
1041 break;
1042 case DCinfolinemain:
1043 // ignore the output, marked file info follows
1044 m_haveExecutable = true;
1045 break;
1046 case DCinfolocals:
1047 // parse local variables
1048 if (output[0] != '\0') {
1049 handleLocals(output);
1051 break;
1052 case DCinforegisters:
1053 handleRegisters(output);
1054 break;
1055 case DCexamine:
1056 handleMemoryDump(output);
1057 break;
1058 case DCinfoline:
1059 handleInfoLine(cmd, output);
1060 break;
1061 case DCdisassemble:
1062 handleDisassemble(cmd, output);
1063 break;
1064 case DCframe:
1065 handleFrameChange(output);
1066 updateAllExprs();
1067 break;
1068 case DCbt:
1069 handleBacktrace(output);
1070 updateAllExprs();
1071 break;
1072 case DCprint:
1073 handlePrint(cmd, output);
1074 break;
1075 case DCprintDeref:
1076 handlePrintDeref(cmd, output);
1077 break;
1078 case DCattach:
1079 m_haveExecutable = true;
1080 // fall through
1081 case DCrun:
1082 case DCcont:
1083 case DCstep:
1084 case DCstepi:
1085 case DCnext:
1086 case DCnexti:
1087 case DCfinish:
1088 case DCuntil:
1089 case DCthread:
1090 handleRunCommands(output);
1091 break;
1092 case DCkill:
1093 m_programRunning = m_programActive = false;
1094 // erase PC
1095 emit updatePC(QString(), -1, DbgAddr(), 0);
1096 break;
1097 case DCbreaktext:
1098 case DCbreakline:
1099 case DCtbreakline:
1100 case DCbreakaddr:
1101 case DCtbreakaddr:
1102 case DCwatchpoint:
1103 newBreakpoint(cmd, output);
1104 // fall through
1105 case DCdelete:
1106 case DCenable:
1107 case DCdisable:
1108 // these commands need immediate response
1109 m_d->queueCmd(DCinfobreak, DebuggerDriver::QMoverrideMoreEqual);
1110 break;
1111 case DCinfobreak:
1112 // note: this handler must not enqueue a command, since
1113 // DCinfobreak is used at various different places.
1114 updateBreakList(output);
1115 break;
1116 case DCfindType:
1117 handleFindType(cmd, output);
1118 break;
1119 case DCprintStruct:
1120 case DCprintQStringStruct:
1121 case DCprintWChar:
1122 handlePrintStruct(cmd, output);
1123 break;
1124 case DCinfosharedlib:
1125 handleSharedLibs(output);
1126 break;
1127 case DCcondition:
1128 case DCignore:
1129 // we are not interested in the output
1130 break;
1131 case DCinfothreads:
1132 handleThreadList(output);
1133 break;
1134 case DCsetpc:
1135 handleSetPC(output);
1136 break;
1137 case DCsetvariable:
1138 handleSetVariable(cmd, output);
1139 break;
1143 void KDebugger::backgroundUpdate()
1146 * If there are still expressions that need to be updated, then do so.
1148 if (m_programActive)
1149 evalExpressions();
1152 void KDebugger::handleRunCommands(const char* output)
1154 uint flags = m_d->parseProgramStopped(output, m_statusMessage);
1155 emit updateStatusMessage();
1157 m_programActive = flags & DebuggerDriver::SFprogramActive;
1159 // refresh files if necessary
1160 if (flags & DebuggerDriver::SFrefreshSource) {
1161 TRACE("re-reading files");
1162 emit executableUpdated();
1166 * Try to set any orphaned breakpoints now.
1168 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
1170 if (bp->isOrphaned()) {
1171 TRACE(QString("re-trying brkpt loc: %2 file: %3 line: %1")
1172 .arg(bp->lineNo).arg(bp->location, bp->fileName));
1173 CmdQueueItem* cmd = executeBreakpoint(&*bp, true);
1174 cmd->m_existingBrkpt = bp->id; // used in newBreakpoint()
1175 flags |= DebuggerDriver::SFrefreshBreak;
1180 * If we stopped at a breakpoint, we must update the breakpoint list
1181 * because the hit count changes. Also, if the breakpoint was temporary
1182 * it would go away now.
1184 if ((flags & (DebuggerDriver::SFrefreshBreak|DebuggerDriver::SFrefreshSource)) ||
1185 stopMayChangeBreakList())
1187 m_d->queueCmd(DCinfobreak, DebuggerDriver::QMoverride);
1191 * If we haven't listed the shared libraries yet, do so. We must do
1192 * this before we emit any commands that list variables, since the type
1193 * libraries depend on the shared libraries.
1195 if (!m_sharedLibsListed) {
1196 // must be a high-priority command!
1197 m_d->executeCmd(DCinfosharedlib);
1200 // get the backtrace if the program is running
1201 if (m_programActive) {
1202 m_d->queueCmd(DCbt, DebuggerDriver::QMoverride);
1203 } else {
1204 // program finished: erase PC
1205 emit updatePC(QString(), -1, DbgAddr(), 0);
1206 // dequeue any commands in the queues
1207 m_d->flushCommands();
1210 /* Update threads list */
1211 if (m_programActive && (flags & DebuggerDriver::SFrefreshThreads)) {
1212 m_d->queueCmd(DCinfothreads, DebuggerDriver::QMoverride);
1215 m_programRunning = false;
1216 emit programStopped();
1219 void KDebugger::slotInferiorRunning()
1221 m_programRunning = true;
1224 void KDebugger::updateAllExprs()
1226 if (!m_programActive)
1227 return;
1229 // retrieve local variables
1230 m_d->queueCmd(DCinfolocals, DebuggerDriver::QMoverride);
1232 // retrieve registers
1233 m_d->queueCmd(DCinforegisters, DebuggerDriver::QMoverride);
1235 // get new memory dump
1236 if (!m_memoryExpression.isEmpty()) {
1237 queueMemoryDump(false);
1240 // update watch expressions
1241 foreach (QString expr, m_watchVariables.exprList()) {
1242 m_watchEvalExpr.push_back(expr);
1246 void KDebugger::updateProgEnvironment(const QString& args, const QString& wd,
1247 const std::map<QString,EnvVar>& newVars,
1248 const QSet<QString>& newOptions)
1250 m_programArgs = args;
1251 m_d->executeCmd(DCsetargs, m_programArgs);
1252 TRACE("new pgm args: " + m_programArgs + "\n");
1254 m_programWD = wd.trimmed();
1255 if (!m_programWD.isEmpty()) {
1256 m_d->executeCmd(DCcd, m_programWD);
1257 TRACE("new wd: " + m_programWD + "\n");
1260 // update environment variables
1261 for (std::map<QString,EnvVar>::const_iterator i = newVars.begin(); i != newVars.end(); ++i)
1263 QString var = i->first;
1264 const EnvVar* val = &i->second;
1265 switch (val->status) {
1266 case EnvVar::EVnew:
1267 case EnvVar::EVdirty:
1268 m_envVars[var] = val->value;
1269 // update value
1270 m_d->executeCmd(DCsetenv, var, val->value);
1271 break;
1272 case EnvVar::EVdeleted:
1273 // delete value
1274 m_d->executeCmd(DCunsetenv, var);
1275 m_envVars.erase(var);
1276 break;
1277 default:
1278 ASSERT(false);
1279 case EnvVar::EVclean:
1280 // variable not changed
1281 break;
1285 // update options
1286 foreach (QString opt, newOptions - m_boolOptions)
1288 // option is not set, set it
1289 m_d->executeCmd(DCsetoption, opt, 1);
1291 foreach (QString opt, m_boolOptions - newOptions)
1293 // option is set, unset it
1294 m_d->executeCmd(DCsetoption, opt, 0);
1296 m_boolOptions = newOptions;
1299 void KDebugger::handleLocals(const char* output)
1301 // retrieve old list of local variables
1302 QStringList oldVars = m_localVariables.exprList();
1305 * Get local variables.
1307 std::list<ExprValue*> newVars;
1308 parseLocals(output, newVars);
1311 * Clear any old VarTree item pointers, so that later we don't access
1312 * dangling pointers.
1314 m_localVariables.clearPendingUpdates();
1317 * Match old variables against new ones.
1319 for (QStringList::ConstIterator n = oldVars.begin(); n != oldVars.end(); ++n) {
1320 // lookup this variable in the list of new variables
1321 std::list<ExprValue*>::iterator v = newVars.begin();
1322 while (v != newVars.end() && (*v)->m_name != *n)
1323 ++v;
1324 if (v == newVars.end()) {
1325 // old variable not in the new variables
1326 TRACE("old var deleted: " + *n);
1327 VarTree* v = m_localVariables.topLevelExprByName(*n);
1328 if (v != 0) {
1329 m_localVariables.removeExpr(v);
1331 } else {
1332 // variable in both old and new lists: update
1333 TRACE("update var: " + *n);
1334 m_localVariables.updateExpr(*v, *m_typeTable);
1335 // remove the new variable from the list
1336 delete *v;
1337 newVars.erase(v);
1340 // insert all remaining new variables
1341 while (!newVars.empty())
1343 ExprValue* v = newVars.front();
1344 TRACE("new var: " + v->m_name);
1345 m_localVariables.insertExpr(v, *m_typeTable);
1346 delete v;
1347 newVars.pop_front();
1351 void KDebugger::parseLocals(const char* output, std::list<ExprValue*>& newVars)
1353 std::list<ExprValue*> vars;
1354 m_d->parseLocals(output, vars);
1356 QString origName; /* used in renaming variables */
1357 while (!vars.empty())
1359 ExprValue* variable = vars.front();
1360 vars.pop_front();
1362 * When gdb prints local variables, those from the innermost block
1363 * come first. We run through the list of already parsed variables
1364 * to find duplicates (ie. variables that hide local variables from
1365 * a surrounding block). We keep the name of the inner variable, but
1366 * rename those from the outer block so that, when the value is
1367 * updated in the window, the value of the variable that is
1368 * _visible_ changes the color!
1370 int block = 0;
1371 origName = variable->m_name;
1372 for (std::list<ExprValue*>::iterator v = newVars.begin(); v != newVars.end(); ++v) {
1373 if (variable->m_name == (*v)->m_name) {
1374 // we found a duplicate, change name
1375 block++;
1376 QString newName = origName + " (" + QString().setNum(block) + ")";
1377 variable->m_name = newName;
1380 newVars.push_back(variable);
1384 bool KDebugger::handlePrint(CmdQueueItem* cmd, const char* output)
1386 ASSERT(cmd->m_expr != 0);
1388 ExprValue* variable = m_d->parsePrintExpr(output, true);
1389 if (variable == 0)
1390 return false;
1392 // set expression "name"
1393 variable->m_name = cmd->m_expr->getText();
1396 TRACE("update expr: " + cmd->m_expr->getText());
1397 cmd->m_exprWnd->updateExpr(cmd->m_expr, variable, *m_typeTable);
1398 delete variable;
1401 evalExpressions(); /* enqueue dereferenced pointers */
1403 return true;
1406 bool KDebugger::handlePrintDeref(CmdQueueItem* cmd, const char* output)
1408 ASSERT(cmd->m_expr != 0);
1410 ExprValue* variable = m_d->parsePrintExpr(output, true);
1411 if (variable == 0)
1412 return false;
1414 // set expression "name"
1415 variable->m_name = cmd->m_expr->getText();
1419 * We must insert a dummy parent, because otherwise variable's value
1420 * would overwrite cmd->m_expr's value.
1422 ExprValue* dummyParent = new ExprValue(variable->m_name, VarTree::NKplain);
1423 dummyParent->m_varKind = VarTree::VKdummy;
1424 // the name of the parsed variable is the address of the pointer
1425 QString addr = "*" + cmd->m_expr->value();
1426 variable->m_name = addr;
1427 variable->m_nameKind = VarTree::NKaddress;
1429 dummyParent->m_child = variable;
1430 // expand the first level for convenience
1431 variable->m_initiallyExpanded = true;
1432 TRACE("update ptr: " + cmd->m_expr->getText());
1433 cmd->m_exprWnd->updateExpr(cmd->m_expr, dummyParent, *m_typeTable);
1434 delete dummyParent;
1437 evalExpressions(); /* enqueue dereferenced pointers */
1439 return true;
1442 // parse the output of bt
1443 void KDebugger::handleBacktrace(const char* output)
1445 m_btWindow.clear();
1447 std::list<StackFrame> stack;
1448 m_d->parseBackTrace(output, stack);
1450 if (!stack.empty()) {
1451 std::list<StackFrame>::iterator frm = stack.begin();
1452 // first frame must set PC
1453 // note: frm->lineNo is zero-based
1454 emit updatePC(frm->fileName, frm->lineNo, frm->address, frm->frameNo);
1456 for (; frm != stack.end(); ++frm) {
1457 QString func;
1458 if (frm->var != 0)
1459 func = frm->var->m_name;
1460 else
1461 func = frm->fileName + ":" + QString().setNum(frm->lineNo+1);
1463 m_btWindow.addItem(func);
1464 TRACE("frame " + func + " (" + frm->fileName + ":" +
1465 QString().setNum(frm->lineNo+1) + ")");
1471 void KDebugger::gotoFrame(int frame)
1473 m_d->executeCmd(DCframe, frame);
1476 void KDebugger::handleFrameChange(const char* output)
1478 QString fileName;
1479 int frameNo;
1480 int lineNo;
1481 DbgAddr address;
1482 if (m_d->parseFrameChange(output, frameNo, fileName, lineNo, address)) {
1483 /* lineNo can be negative here if we can't find a file name */
1484 emit updatePC(fileName, lineNo, address, frameNo);
1485 } else {
1486 emit updatePC(fileName, -1, address, frameNo);
1490 void KDebugger::evalExpressions()
1492 // evaluate expressions in the following order:
1493 // watch expressions
1494 // pointers in local variables
1495 // pointers in watch expressions
1496 // types in local variables
1497 // types in watch expressions
1498 // struct members in local variables
1499 // struct members in watch expressions
1500 VarTree* exprItem = 0;
1501 if (!m_watchEvalExpr.empty())
1503 QString expr = m_watchEvalExpr.front();
1504 m_watchEvalExpr.pop_front();
1505 exprItem = m_watchVariables.topLevelExprByName(expr);
1507 if (exprItem != 0) {
1508 CmdQueueItem* cmd = m_d->queueCmd(DCprint, exprItem->getText(), DebuggerDriver::QMoverride);
1509 // remember which expr this was
1510 cmd->m_expr = exprItem;
1511 cmd->m_exprWnd = &m_watchVariables;
1512 } else {
1513 ExprWnd* wnd;
1514 #define POINTER(widget) \
1515 wnd = &widget; \
1516 exprItem = widget.nextUpdatePtr(); \
1517 if (exprItem != 0) goto pointer
1518 #define STRUCT(widget) \
1519 wnd = &widget; \
1520 exprItem = widget.nextUpdateStruct(); \
1521 if (exprItem != 0) goto ustruct
1522 #define TYPE(widget) \
1523 wnd = &widget; \
1524 exprItem = widget.nextUpdateType(); \
1525 if (exprItem != 0) goto type
1526 repeat:
1527 POINTER(m_localVariables);
1528 POINTER(m_watchVariables);
1529 STRUCT(m_localVariables);
1530 STRUCT(m_watchVariables);
1531 TYPE(m_localVariables);
1532 TYPE(m_watchVariables);
1533 #undef POINTER
1534 #undef STRUCT
1535 #undef TYPE
1536 return;
1538 pointer:
1539 // we have an expression to send
1540 dereferencePointer(wnd, exprItem, false);
1541 return;
1543 ustruct:
1544 // paranoia
1545 if (exprItem->m_type == 0 || exprItem->m_type == TypeInfo::unknownType())
1546 goto repeat;
1547 evalInitialStructExpression(exprItem, wnd, false);
1548 return;
1550 type:
1552 * Sometimes a VarTree gets registered twice for a type update. So
1553 * it may happen that it has already been updated. Hence, we ignore
1554 * it here and go on to the next task.
1556 if (exprItem->m_type != 0)
1557 goto repeat;
1558 determineType(wnd, exprItem);
1562 void KDebugger::dereferencePointer(ExprWnd* wnd, VarTree* exprItem,
1563 bool immediate)
1565 ASSERT(exprItem->m_varKind == VarTree::VKpointer);
1567 QString expr = exprItem->computeExpr();
1568 TRACE("dereferencing pointer: " + expr);
1569 CmdQueueItem* cmd;
1570 if (immediate) {
1571 cmd = m_d->queueCmd(DCprintDeref, expr, DebuggerDriver::QMoverrideMoreEqual);
1572 } else {
1573 cmd = m_d->queueCmd(DCprintDeref, expr, DebuggerDriver::QMoverride);
1575 // remember which expr this was
1576 cmd->m_expr = exprItem;
1577 cmd->m_exprWnd = wnd;
1580 void KDebugger::determineType(ExprWnd* wnd, VarTree* exprItem)
1582 ASSERT(exprItem->m_varKind == VarTree::VKstruct);
1584 QString expr = exprItem->computeExpr();
1585 TRACE("get type of: " + expr);
1586 CmdQueueItem* cmd;
1587 cmd = m_d->queueCmd(DCfindType, expr, DebuggerDriver::QMoverride);
1589 // remember which expr this was
1590 cmd->m_expr = exprItem;
1591 cmd->m_exprWnd = wnd;
1594 void KDebugger::handleFindType(CmdQueueItem* cmd, const char* output)
1596 QString type;
1597 if (m_d->parseFindType(output, type))
1599 ASSERT(cmd != 0 && cmd->m_expr != 0);
1601 const TypeInfo* info = m_typeTable->lookup(type);
1603 if (info == 0) {
1605 * We've asked gdb for the type of the expression in
1606 * cmd->m_expr, but it returned a name we don't know. The base
1607 * class (and member) types have been checked already (at the
1608 * time when we parsed that particular expression). Now it's
1609 * time to derive the type from the base classes as a last
1610 * resort.
1612 info = cmd->m_expr->inferTypeFromBaseClass();
1613 // if we found a type through this method, register an alias
1614 if (info != 0) {
1615 TRACE("infered alias: " + type);
1616 m_typeTable->registerAlias(type, info);
1619 if (info == 0) {
1620 TRACE("unknown type "+type);
1621 cmd->m_expr->m_type = TypeInfo::unknownType();
1622 } else {
1623 cmd->m_expr->m_type = info;
1624 /* since this node has a new type, we get its value immediately */
1625 evalInitialStructExpression(cmd->m_expr, cmd->m_exprWnd, false);
1626 return;
1630 evalExpressions(); /* queue more of them */
1633 void KDebugger::handlePrintStruct(CmdQueueItem* cmd, const char* output)
1635 VarTree* var = cmd->m_expr;
1636 ASSERT(var != 0);
1637 ASSERT(var->m_varKind == VarTree::VKstruct);
1639 ExprValue* partExpr;
1640 if (cmd->m_cmd == DCprintQStringStruct) {
1641 partExpr = m_d->parseQCharArray(output, false, m_typeTable->qCharIsShort());
1642 } else if (cmd->m_cmd == DCprintWChar) {
1643 partExpr = m_d->parseQCharArray(output, false, true);
1644 } else {
1645 partExpr = m_d->parsePrintExpr(output, false);
1647 bool errorValue =
1648 partExpr == 0 ||
1649 /* we only allow simple values at the moment */
1650 partExpr->m_child != 0;
1652 QString partValue;
1653 if (errorValue)
1655 partValue = "?""?""?"; // 2 question marks in a row would be a trigraph
1656 } else {
1657 partValue = partExpr->m_value;
1659 delete partExpr;
1660 partExpr = 0;
1663 * Updating a struct value works like this: var->m_partialValue holds
1664 * the value that we have gathered so far (it's been initialized with
1665 * var->m_type->m_displayString[0] earlier). Each time we arrive here,
1666 * we append the printed result followed by the next
1667 * var->m_type->m_displayString to var->m_partialValue.
1669 * If the expression we just evaluated was a guard expression, and it
1670 * resulted in an error, we must not evaluate the real expression, but
1671 * go on to the next index. (We must still add the question marks to
1672 * the value).
1674 * Next, if this was the length expression, we still have not seen the
1675 * real expression, but the length of a QString.
1677 ASSERT(var->m_exprIndex >= 0 && var->m_exprIndex <= typeInfoMaxExpr);
1679 if (errorValue || !var->m_exprIndexUseGuard)
1681 // add current partValue (which might be the question marks)
1682 var->m_partialValue += partValue;
1683 var->m_exprIndex++; /* next part */
1684 var->m_exprIndexUseGuard = true;
1685 var->m_partialValue += var->m_type->m_displayString[var->m_exprIndex];
1687 else
1689 // this was a guard expression that succeeded
1690 // go for the real expression
1691 var->m_exprIndexUseGuard = false;
1694 /* go for more sub-expressions if needed */
1695 if (var->m_exprIndex < var->m_type->m_numExprs) {
1696 /* queue a new print command with quite high priority */
1697 evalStructExpression(var, cmd->m_exprWnd, true);
1698 return;
1701 cmd->m_exprWnd->updateStructValue(var);
1703 evalExpressions(); /* enqueue dereferenced pointers */
1706 /* queues the first printStruct command for a struct */
1707 void KDebugger::evalInitialStructExpression(VarTree* var, ExprWnd* wnd, bool immediate)
1709 var->m_exprIndex = 0;
1710 if (var->m_type != TypeInfo::wchartType())
1712 var->m_exprIndexUseGuard = true;
1713 var->m_partialValue = var->m_type->m_displayString[0];
1714 evalStructExpression(var, wnd, immediate);
1716 else
1718 var->m_exprIndexUseGuard = false;
1719 QString expr = var->computeExpr();
1720 CmdQueueItem* cmd = m_d->queueCmd(DCprintWChar, expr,
1721 immediate ? DebuggerDriver::QMoverrideMoreEqual
1722 : DebuggerDriver::QMoverride);
1723 // remember which expression this was
1724 cmd->m_expr = var;
1725 cmd->m_exprWnd = wnd;
1729 /** queues a printStruct command; var must have been initialized correctly */
1730 void KDebugger::evalStructExpression(VarTree* var, ExprWnd* wnd, bool immediate)
1732 QString base = var->computeExpr();
1733 QString expr;
1734 if (var->m_exprIndexUseGuard) {
1735 expr = var->m_type->m_guardStrings[var->m_exprIndex];
1736 if (expr.isEmpty()) {
1737 // no guard, omit it and go to expression
1738 var->m_exprIndexUseGuard = false;
1741 if (!var->m_exprIndexUseGuard) {
1742 expr = var->m_type->m_exprStrings[var->m_exprIndex];
1745 expr.replace("%s", base);
1747 DbgCommand dbgCmd = DCprintStruct;
1748 // check if this is a QString::Data
1749 if (expr.left(15) == "/QString::Data ")
1751 if (m_typeTable->parseQt2QStrings())
1753 expr = expr.mid(15, expr.length()); /* strip off /QString::Data */
1754 dbgCmd = DCprintQStringStruct;
1755 } else {
1757 * This should not happen: the type libraries should be set up
1758 * in a way that this can't happen. If this happens
1759 * nevertheless it means that, eg., kdecore was loaded but qt2
1760 * was not (only qt2 enables the QString feature).
1762 // TODO: remove this "print"; queue the next printStruct instead
1763 expr = "*0";
1766 TRACE("evalStruct: " + expr + (var->m_exprIndexUseGuard ? " // guard" : " // real"));
1767 CmdQueueItem* cmd = m_d->queueCmd(dbgCmd, expr,
1768 immediate ? DebuggerDriver::QMoverrideMoreEqual
1769 : DebuggerDriver::QMnormal);
1771 // remember which expression this was
1772 cmd->m_expr = var;
1773 cmd->m_exprWnd = wnd;
1776 void KDebugger::handleSharedLibs(const char* output)
1778 // parse the table of shared libraries
1779 m_sharedLibs = m_d->parseSharedLibs(output);
1780 m_sharedLibsListed = true;
1782 // get type libraries
1783 m_typeTable->loadLibTypes(m_sharedLibs);
1785 // hand over the QString data cmd
1786 m_d->setPrintQStringDataCmd(m_typeTable->printQStringDataCmd());
1789 CmdQueueItem* KDebugger::loadCoreFile()
1791 return m_d->queueCmd(DCcorefile, m_corefile, DebuggerDriver::QMoverride);
1794 void KDebugger::slotExpanding(QTreeWidgetItem* item)
1796 VarTree* exprItem = static_cast<VarTree*>(item);
1797 if (exprItem->m_varKind != VarTree::VKpointer) {
1798 return;
1800 ExprWnd* wnd = static_cast<ExprWnd*>(item->treeWidget());
1801 dereferencePointer(wnd, exprItem, true);
1804 // add the expression in the edit field to the watch expressions
1805 void KDebugger::addWatch(const QString& t)
1807 QString expr = t.trimmed();
1808 // don't add a watched expression again
1809 if (expr.isEmpty() || m_watchVariables.topLevelExprByName(expr) != 0)
1810 return;
1811 ExprValue e(expr, VarTree::NKplain);
1812 m_watchVariables.insertExpr(&e, *m_typeTable);
1814 // if we are boring ourselves, send down the command
1815 if (m_programActive) {
1816 m_watchEvalExpr.push_back(expr);
1817 if (m_d->isIdle()) {
1818 evalExpressions();
1823 // delete a toplevel watch expression
1824 void KDebugger::slotDeleteWatch()
1826 // delete only allowed while debugger is idle; or else we might delete
1827 // the very expression the debugger is currently working on...
1828 if (m_d == 0 || !m_d->isIdle())
1829 return;
1831 VarTree* item = m_watchVariables.selectedItem();
1832 if (item == 0 || !item->isToplevelExpr())
1833 return;
1835 // remove the variable from the list to evaluate
1836 std::list<QString>::iterator i =
1837 std::find(m_watchEvalExpr.begin(), m_watchEvalExpr.end(), item->getText());
1838 if (i != m_watchEvalExpr.end()) {
1839 m_watchEvalExpr.erase(i);
1841 m_watchVariables.removeExpr(item);
1842 // item is invalid at this point!
1845 void KDebugger::handleRegisters(const char* output)
1847 emit registersChanged(m_d->parseRegisters(output));
1851 * The output of the DCbreak* commands has more accurate information about
1852 * the file and the line number.
1854 * All newly set breakpoints are inserted in the m_brkpts, even those that
1855 * were not set sucessfully. The unsuccessful breakpoints ("orphaned
1856 * breakpoints") are assigned negative ids, and they are tried to set later
1857 * when the program stops again at a breakpoint.
1859 void KDebugger::newBreakpoint(CmdQueueItem* cmd, const char* output)
1861 BrkptIterator bp;
1862 if (cmd->m_brkpt != 0) {
1863 // a new breakpoint, put it in the list
1864 assert(cmd->m_brkpt->id == 0);
1865 m_brkpts.push_back(*cmd->m_brkpt);
1866 delete cmd->m_brkpt;
1867 bp = m_brkpts.end();
1868 --bp;
1869 } else {
1870 // an existing breakpoint was retried
1871 assert(cmd->m_existingBrkpt != 0);
1872 bp = breakpointById(cmd->m_existingBrkpt);
1873 if (bp == m_brkpts.end())
1874 return;
1877 // parse the output to determine success or failure
1878 int id;
1879 QString file;
1880 int lineNo;
1881 QString address;
1882 if (!m_d->parseBreakpoint(output, id, file, lineNo, address))
1885 * Failure, the breakpoint could not be set. If this is a new
1886 * breakpoint, assign it a negative id. We look for the minimal id
1887 * of all breakpoints (that are already in the list) to get the new
1888 * id.
1890 if (bp->id == 0)
1892 int minId = 0;
1893 for (BrkptIterator i = m_brkpts.begin(); i != m_brkpts.end(); ++i) {
1894 if (i->id < minId)
1895 minId = i->id;
1897 bp->id = minId-1;
1899 return;
1902 // The breakpoint was successfully set.
1903 if (bp->id <= 0)
1905 // this is a new or orphaned breakpoint:
1906 // set the remaining properties
1907 if (!bp->enabled) {
1908 m_d->executeCmd(DCdisable, id);
1910 if (!bp->condition.isEmpty()) {
1911 m_d->executeCmd(DCcondition, bp->condition, id);
1915 bp->id = id;
1916 bp->fileName = file;
1917 bp->lineNo = lineNo;
1918 if (!address.isEmpty())
1919 bp->address = address;
1922 void KDebugger::updateBreakList(const char* output)
1924 // get the new list
1925 std::list<Breakpoint> brks;
1926 m_d->parseBreakList(output, brks);
1928 // merge existing information into the new list
1929 // then swap the old and new lists
1931 for (BrkptIterator bp = brks.begin(); bp != brks.end(); ++bp)
1933 BrkptIterator i = breakpointById(bp->id);
1934 if (i != m_brkpts.end())
1936 // preserve accurate location information
1937 // note that xsldbg doesn't have a location in
1938 // the listed breakpoint if it has just been set
1939 // therefore, we copy it as well if necessary
1940 bp->text = i->text;
1941 if (!i->fileName.isEmpty()) {
1942 bp->fileName = i->fileName;
1943 bp->lineNo = i->lineNo;
1948 // orphaned breakpoints must be copied
1949 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
1951 if (bp->isOrphaned())
1952 brks.push_back(*bp);
1955 m_brkpts.swap(brks);
1956 emit breakpointsChanged();
1959 // look if there is at least one temporary breakpoint
1960 // or a watchpoint
1961 bool KDebugger::stopMayChangeBreakList() const
1963 for (BrkptROIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
1965 if (bp->temporary || bp->type == Breakpoint::watchpoint)
1966 return true;
1968 return false;
1971 KDebugger::BrkptIterator KDebugger::breakpointByFilePos(QString file, int lineNo,
1972 const DbgAddr& address)
1974 // look for exact file name match
1975 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
1977 if (bp->lineNo == lineNo &&
1978 bp->fileName == file &&
1979 (address.isEmpty() || bp->address == address))
1981 return bp;
1984 // not found, so try basename
1985 file = QFileInfo(file).fileName();
1987 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
1989 // get base name of breakpoint's file
1990 QString basename = QFileInfo(bp->fileName).fileName();
1992 if (bp->lineNo == lineNo &&
1993 basename == file &&
1994 (address.isEmpty() || bp->address == address))
1996 return bp;
2000 // not found
2001 return m_brkpts.end();
2004 KDebugger::BrkptIterator KDebugger::breakpointById(int id)
2006 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
2008 if (bp->id == id) {
2009 return bp;
2012 // not found
2013 return m_brkpts.end();
2016 void KDebugger::slotValuePopup(const QString& expr)
2018 // search the local variables for a match
2019 VarTree* v = m_localVariables.topLevelExprByName(expr);
2020 if (v == 0) {
2021 // not found, check watch expressions
2022 v = m_watchVariables.topLevelExprByName(expr);
2023 if (v == 0) {
2024 // try a member of 'this'
2025 v = m_localVariables.topLevelExprByName("this");
2026 if (v != 0)
2027 v = ExprWnd::ptrMemberByName(v, expr);
2028 if (v == 0) {
2029 // nothing found; do nothing
2030 return;
2035 // construct the tip
2036 QString tip = v->getText() + " = ";
2037 if (!v->value().isEmpty())
2039 tip += v->value();
2041 else
2043 // no value: we use some hint
2044 switch (v->m_varKind) {
2045 case VarTree::VKstruct:
2046 tip += "{...}";
2047 break;
2048 case VarTree::VKarray:
2049 tip += "[...]";
2050 break;
2051 default:
2052 tip += "?""?""?"; // 2 question marks in a row would be a trigraph
2053 break;
2056 emit valuePopup(tip);
2059 void KDebugger::slotDisassemble(const QString& fileName, int lineNo)
2061 if (m_haveExecutable) {
2062 CmdQueueItem* cmd = m_d->queueCmd(DCinfoline, fileName, lineNo,
2063 DebuggerDriver::QMoverrideMoreEqual);
2064 cmd->m_fileName = fileName;
2065 cmd->m_lineNo = lineNo;
2069 void KDebugger::handleInfoLine(CmdQueueItem* cmd, const char* output)
2071 QString addrFrom, addrTo;
2072 if (cmd->m_lineNo >= 0) {
2073 // disassemble
2074 if (m_d->parseInfoLine(output, addrFrom, addrTo)) {
2075 // got the address range, now get the real code
2076 CmdQueueItem* c = m_d->queueCmd(DCdisassemble, addrFrom, addrTo,
2077 DebuggerDriver::QMoverrideMoreEqual);
2078 c->m_fileName = cmd->m_fileName;
2079 c->m_lineNo = cmd->m_lineNo;
2080 } else {
2081 // no code
2082 emit disassembled(cmd->m_fileName, cmd->m_lineNo, std::list<DisassembledCode>());
2084 } else {
2085 // set program counter
2086 if (m_d->parseInfoLine(output, addrFrom, addrTo)) {
2087 // move the program counter to the start address
2088 m_d->executeCmd(DCsetpc, addrFrom);
2093 void KDebugger::handleDisassemble(CmdQueueItem* cmd, const char* output)
2095 emit disassembled(cmd->m_fileName, cmd->m_lineNo,
2096 m_d->parseDisassemble(output));
2099 void KDebugger::handleThreadList(const char* output)
2101 emit threadsChanged(m_d->parseThreadList(output));
2104 void KDebugger::setThread(int id)
2106 m_d->queueCmd(DCthread, id, DebuggerDriver::QMoverrideMoreEqual);
2109 void KDebugger::setMemoryExpression(const QString& memexpr)
2111 m_memoryExpression = memexpr;
2113 // queue the new expression
2114 if (!m_memoryExpression.isEmpty() &&
2115 isProgramActive() &&
2116 !isProgramRunning())
2118 queueMemoryDump(true);
2122 void KDebugger::queueMemoryDump(bool immediate)
2124 m_d->queueCmd(DCexamine, m_memoryExpression, m_memoryFormat,
2125 immediate ? DebuggerDriver::QMoverrideMoreEqual :
2126 DebuggerDriver::QMoverride);
2129 void KDebugger::handleMemoryDump(const char* output)
2131 std::list<MemoryDump> memdump;
2132 QString msg = m_d->parseMemoryDump(output, memdump);
2133 emit memoryDumpChanged(msg, memdump);
2136 void KDebugger::setProgramCounter(const QString& file, int line, const DbgAddr& addr)
2138 if (addr.isEmpty()) {
2139 // find address of the specified line
2140 CmdQueueItem* cmd = m_d->executeCmd(DCinfoline, file, line);
2141 cmd->m_lineNo = -1; /* indicates "Set PC" UI command */
2142 } else {
2143 // move the program counter to that address
2144 m_d->executeCmd(DCsetpc, addr.asString());
2148 void KDebugger::handleSetPC(const char* /*output*/)
2150 // TODO: handle errors
2152 // now go to the top-most frame
2153 // this also modifies the program counter indicator in the UI
2154 gotoFrame(0);
2157 void KDebugger::slotValueEdited(VarTree* expr, const QString& text)
2159 if (text.simplified().isEmpty())
2160 return; /* no text entered: ignore request */
2162 ExprWnd* wnd = static_cast<ExprWnd*>(expr->treeWidget());
2163 TRACE(QString().sprintf("Changing %s to ",
2164 wnd->name()) + text);
2166 // determine the lvalue to edit
2167 QString lvalue = expr->computeExpr();
2168 CmdQueueItem* cmd = m_d->executeCmd(DCsetvariable, lvalue, text);
2169 cmd->m_expr = expr;
2170 cmd->m_exprWnd = wnd;
2173 void KDebugger::handleSetVariable(CmdQueueItem* cmd, const char* output)
2175 QString msg = m_d->parseSetVariable(output);
2176 if (!msg.isEmpty())
2178 // there was an error; display it in the status bar
2179 m_statusMessage = msg;
2180 emit updateStatusMessage();
2181 return;
2184 // get the new value
2185 QString expr = cmd->m_expr->computeExpr();
2186 CmdQueueItem* printCmd =
2187 m_d->queueCmd(DCprint, expr, DebuggerDriver::QMoverrideMoreEqual);
2188 printCmd->m_expr = cmd->m_expr;
2189 printCmd->m_exprWnd = cmd->m_exprWnd;
2193 #include "debugger.moc"