Extend copyright to 2018.
[kdbg.git] / kdbg / debugger.cpp
blob3751e4c879eaa93c63f93c1dc7b51d19a0cd2332
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 <QCryptographicHash>
17 #include <QStandardPaths>
18 #include <kconfig.h>
19 #include <kconfiggroup.h>
20 #include <klocalizedstring.h> /* i18n */
21 #include <kmessagebox.h>
22 #include <ctype.h>
23 #include <stdlib.h> /* strtol, atoi */
24 #include <unistd.h> /* sleep(3) */
25 #include <algorithm>
26 #include "mydebug.h"
28 /**
29 * Returns expression value for a tooltip.
31 template <class T>
32 QString formatPopupValue(const T* v)
34 QString tip;
36 if (!v->value().isEmpty())
38 tip += v->value();
40 else
42 // no value: we use some hint
43 switch (v->m_varKind) {
44 case VarTree::VKstruct:
45 tip += "{...}";
46 break;
47 case VarTree::VKarray:
48 tip += "[...]";
49 break;
50 default:
51 tip += "?""?""?"; // 2 question marks in a row would be a trigraph
52 break;
56 return tip;
59 KDebugger::KDebugger(QWidget* parent,
60 ExprWnd* localVars,
61 ExprWnd* watchVars,
62 QListWidget* backtrace) :
63 QObject(parent),
64 m_ttyLevel(ttyFull),
65 m_memoryFormat(MDTword | MDThex),
66 m_memoryLength(16),
67 m_haveExecutable(false),
68 m_programActive(false),
69 m_programRunning(false),
70 m_sharedLibsListed(false),
71 m_typeTable(0),
72 m_programConfig(0),
73 m_d(0),
74 m_localVariables(*localVars),
75 m_watchVariables(*watchVars),
76 m_btWindow(*backtrace)
78 connect(&m_localVariables, SIGNAL(itemExpanded(QTreeWidgetItem*)),
79 SLOT(slotExpanding(QTreeWidgetItem*)));
80 connect(&m_watchVariables, SIGNAL(itemExpanded(QTreeWidgetItem*)),
81 SLOT(slotExpanding(QTreeWidgetItem*)));
82 connect(&m_localVariables, SIGNAL(editValueCommitted(VarTree*, const QString&)),
83 SLOT(slotValueEdited(VarTree*, const QString&)));
84 connect(&m_watchVariables, SIGNAL(editValueCommitted(VarTree*, const QString&)),
85 SLOT(slotValueEdited(VarTree*, const QString&)));
87 connect(&m_btWindow, SIGNAL(currentRowChanged(int)), this, SLOT(gotoFrame(int)));
89 emit updateUI();
92 KDebugger::~KDebugger()
94 if (m_programConfig != 0) {
95 saveProgramSettings();
96 m_programConfig->sync();
97 delete m_programConfig;
100 delete m_typeTable;
104 void KDebugger::saveSettings(KConfig* /*config*/)
108 void KDebugger::restoreSettings(KConfig* /*config*/)
113 //////////////////////////////////////////////////////////////////////
114 // external interface
116 const char GeneralGroup[] = "General";
117 const char DebuggerCmdStr[] = "DebuggerCmdStr";
118 const char TTYLevelEntry[] = "TTYLevel";
119 const char KDebugger::DriverNameEntry[] = "DriverName";
121 bool KDebugger::debugProgram(const QString& name,
122 DebuggerDriver* driver)
124 if (m_d != 0 && m_d->isRunning())
126 QApplication::setOverrideCursor(Qt::WaitCursor);
128 stopDriver();
130 QApplication::restoreOverrideCursor();
132 if (m_d->isRunning() || m_haveExecutable) {
133 /* timed out! We can't really do anything useful now */
134 TRACE("timed out while waiting for gdb to die!");
135 return false;
137 delete m_d;
138 m_d = 0;
141 // wire up the driver
142 connect(driver, SIGNAL(activateFileLine(const QString&,int,const DbgAddr&)),
143 this, SIGNAL(activateFileLine(const QString&,int,const DbgAddr&)));
144 connect(driver, SIGNAL(finished(int, QProcess::ExitStatus)),
145 SLOT(gdbExited()));
146 connect(driver, SIGNAL(commandReceived(CmdQueueItem*,const char*)),
147 SLOT(parse(CmdQueueItem*,const char*)));
148 connect(driver, SIGNAL(bytesWritten(qint64)), SIGNAL(updateUI()));
149 connect(driver, SIGNAL(inferiorRunning()), SLOT(slotInferiorRunning()));
150 connect(driver, SIGNAL(enterIdleState()), SLOT(backgroundUpdate()));
151 connect(driver, SIGNAL(enterIdleState()), SIGNAL(updateUI()));
152 connect(&m_localVariables, SIGNAL(removingItem(VarTree*)),
153 driver, SLOT(dequeueCmdByVar(VarTree*)));
154 connect(&m_watchVariables, SIGNAL(removingItem(VarTree*)),
155 driver, SLOT(dequeueCmdByVar(VarTree*)));
157 // create the program settings object
158 openProgramConfig(name);
160 // get debugger command from per-program settings
161 if (m_programConfig != 0) {
162 KConfigGroup g = m_programConfig->group(GeneralGroup);
163 m_debuggerCmd = readDebuggerCmd(g);
164 // get terminal emulation level
165 m_ttyLevel = TTYLevel(g.readEntry(TTYLevelEntry, int(ttyFull)));
167 // the rest is read in later in the handler of DCexecutable
169 m_d = driver;
171 if (!startDriver()) {
172 TRACE("startDriver failed");
173 m_d = 0;
174 return false;
177 TRACE("before file cmd");
178 m_d->executeCmd(DCexecutable, name);
179 m_executable = name;
181 // set remote target
182 if (!m_remoteDevice.isEmpty()) {
183 m_d->executeCmd(DCtargetremote, m_remoteDevice);
184 m_d->queueCmd(DCbt);
185 m_d->queueCmd(DCinfothreads);
186 m_d->queueCmdAgain(DCframe, 0);
187 m_programActive = true;
188 m_haveExecutable = true;
191 // create a type table
192 m_typeTable = new ProgramTypeTable;
193 m_sharedLibsListed = false;
195 emit updateUI();
197 return true;
200 void KDebugger::shutdown()
202 // shut down debugger driver
203 if (m_d != 0 && m_d->isRunning())
205 stopDriver();
209 void KDebugger::useCoreFile(QString corefile, bool batch)
211 m_corefile = corefile;
212 if (!batch) {
213 CmdQueueItem* cmd = loadCoreFile();
214 cmd->m_byUser = true;
218 void KDebugger::setAttachPid(const QString& pid)
220 m_attachedPid = pid;
223 void KDebugger::programRun()
225 if (!isReady())
226 return;
228 // when program is active, but not a core file, continue
229 // otherwise run the program
230 if (m_programActive && m_corefile.isEmpty()) {
231 // gdb command: continue
232 m_d->executeCmdOnce(DCcont);
233 } else {
234 // gdb command: run
235 m_d->executeCmdOnce(DCrun);
236 m_corefile = QString();
237 m_programActive = true;
239 m_programRunning = true;
242 void KDebugger::attachProgram(const QString& pid)
244 if (!isReady())
245 return;
247 m_attachedPid = pid;
248 TRACE("Attaching to " + m_attachedPid);
249 m_d->executeCmd(DCattach, m_attachedPid);
250 m_programActive = true;
251 m_programRunning = true;
254 void KDebugger::programRunAgain()
256 if (canSingleStep()) {
257 m_d->executeCmdOnce(DCrun);
258 m_corefile = QString();
259 m_programRunning = true;
263 void KDebugger::programStep()
265 if (canSingleStep()) {
266 m_d->executeCmdOnce(DCstep);
267 m_programRunning = true;
271 void KDebugger::programNext()
273 if (canSingleStep()) {
274 m_d->executeCmdOnce(DCnext);
275 m_programRunning = true;
279 void KDebugger::programStepi()
281 if (canSingleStep()) {
282 m_d->executeCmdOnce(DCstepi);
283 m_programRunning = true;
287 void KDebugger::programNexti()
289 if (canSingleStep()) {
290 m_d->executeCmdOnce(DCnexti);
291 m_programRunning = true;
295 void KDebugger::programFinish()
297 if (canSingleStep()) {
298 m_d->executeCmdOnce(DCfinish);
299 m_programRunning = true;
303 void KDebugger::programKill()
305 if (haveExecutable() && isProgramActive()) {
306 if (m_programRunning) {
307 m_d->interruptInferior();
309 // this is an emergency command; flush queues
310 m_d->flushCommands(true);
311 m_d->executeCmdOnce(DCkill);
315 void KDebugger::programDetach()
317 if (haveExecutable() && isProgramActive()) {
318 if (m_programRunning) {
319 m_d->interruptInferior();
321 // this is an emergency command; flush queues
322 m_d->flushCommands(true);
323 m_d->executeCmdOnce(DCdetach);
327 bool KDebugger::runUntil(const QString& fileName, int lineNo)
329 if (isReady() && m_programActive && !m_programRunning) {
330 // strip off directory part of file name
331 QFileInfo fi(fileName);
332 m_d->executeCmdOnce(DCuntil, fi.fileName(), lineNo);
333 m_programRunning = true;
334 return true;
335 } else {
336 return false;
340 void KDebugger::programBreak()
342 if (m_haveExecutable && m_programRunning) {
343 m_d->interruptInferior();
347 void KDebugger::programArgs(QWidget* parent)
349 if (m_haveExecutable) {
350 QStringList allOptions = m_d->boolOptionList();
351 PgmArgs dlg(parent, m_executable, m_envVars, allOptions);
352 dlg.setArgs(m_programArgs);
353 dlg.setWd(m_programWD);
354 dlg.setOptions(m_boolOptions);
355 if (dlg.exec()) {
356 updateProgEnvironment(dlg.args(), dlg.wd(),
357 dlg.envVars(), dlg.options());
362 void KDebugger::programSettings(QWidget* parent)
364 if (!m_haveExecutable)
365 return;
367 ProgramSettings dlg(parent, m_executable);
369 dlg.m_chooseDriver.setDebuggerCmd(m_debuggerCmd);
370 dlg.m_output.setTTYLevel(m_ttyLevel);
372 if (dlg.exec() == QDialog::Accepted)
374 m_debuggerCmd = dlg.m_chooseDriver.debuggerCmd();
375 m_ttyLevel = TTYLevel(dlg.m_output.ttyLevel());
379 bool KDebugger::setBreakpoint(QString file, int lineNo,
380 const DbgAddr& address, bool temporary)
382 if (!isReady()) {
383 return false;
386 BrkptIterator bp = breakpointByFilePos(file, lineNo, address);
387 if (bp == m_brkpts.end())
390 * No such breakpoint, so set a new one. If we have an address, we
391 * set the breakpoint exactly there. Otherwise we use the file name
392 * plus line no.
394 Breakpoint* bp = new Breakpoint;
395 bp->temporary = temporary;
397 if (address.isEmpty())
399 bp->fileName = file;
400 bp->lineNo = lineNo;
402 else
404 bp->address = address;
406 setBreakpoint(bp, false);
408 else
411 * If the breakpoint is disabled, enable it; if it's enabled,
412 * delete that breakpoint.
414 if (bp->enabled) {
415 deleteBreakpoint(bp);
416 } else {
417 enableDisableBreakpoint(bp);
420 return true;
423 void KDebugger::setBreakpoint(Breakpoint* bp, bool queueOnly)
425 CmdQueueItem* cmd = executeBreakpoint(bp, queueOnly);
426 cmd->m_brkpt = bp; // used in newBreakpoint()
429 CmdQueueItem* KDebugger::executeBreakpoint(const Breakpoint* bp, bool queueOnly)
431 CmdQueueItem* cmd;
432 if (!bp->text.isEmpty())
435 * The breakpoint was set using the text box in the breakpoint
436 * list. This is the only way in which watchpoints are set.
438 if (bp->type == Breakpoint::watchpoint) {
439 cmd = m_d->executeCmd(DCwatchpoint, bp->text);
440 } else {
441 cmd = m_d->executeCmd(DCbreaktext, bp->text);
444 else if (bp->address.isEmpty())
446 // strip off directory part of file name
447 QString file = QFileInfo(bp->fileName).fileName();
448 if (queueOnly) {
449 cmd = m_d->queueCmd(bp->temporary ? DCtbreakline : DCbreakline,
450 file, bp->lineNo);
451 } else {
452 cmd = m_d->executeCmd(bp->temporary ? DCtbreakline : DCbreakline,
453 file, bp->lineNo);
456 else
458 if (queueOnly) {
459 cmd = m_d->queueCmd(bp->temporary ? DCtbreakaddr : DCbreakaddr,
460 bp->address.asString());
461 } else {
462 cmd = m_d->executeCmd(bp->temporary ? DCtbreakaddr : DCbreakaddr,
463 bp->address.asString());
466 return cmd;
469 bool KDebugger::infoLine(QString file, int lineNo, const DbgAddr& addr)
471 if (isReady() && !m_programRunning) {
472 CmdQueueItem* cmd = m_d->executeCmd(DCinfoline, file, lineNo);
473 cmd->m_addr = addr;
474 return true;
475 } else {
476 return false;
480 bool KDebugger::enableDisableBreakpoint(QString file, int lineNo,
481 const DbgAddr& address)
483 BrkptIterator bp = breakpointByFilePos(file, lineNo, address);
484 return enableDisableBreakpoint(bp);
487 bool KDebugger::enableDisableBreakpoint(BrkptIterator bp)
489 if (bp == m_brkpts.end())
490 return false;
493 * Toggle enabled/disabled state.
495 * The driver is not bothered if we are modifying an orphaned
496 * breakpoint.
498 if (!bp->isOrphaned()) {
499 if (!canChangeBreakpoints()) {
500 return false;
502 m_d->executeCmd(bp->enabled ? DCdisable : DCenable, bp->id);
503 } else {
504 bp->enabled = !bp->enabled;
505 emit breakpointsChanged();
507 return true;
510 bool KDebugger::conditionalBreakpoint(BrkptIterator bp,
511 const QString& condition,
512 int ignoreCount)
514 if (bp == m_brkpts.end())
515 return false;
518 * Change the condition and ignore count.
520 * The driver is not bothered if we are removing an orphaned
521 * breakpoint.
524 if (!bp->isOrphaned()) {
525 if (!canChangeBreakpoints()) {
526 return false;
529 bool changed = false;
531 if (bp->condition != condition) {
532 // change condition
533 m_d->executeCmd(DCcondition, condition, bp->id);
534 changed = true;
536 if (bp->ignoreCount != ignoreCount) {
537 // change ignore count
538 m_d->executeCmd(DCignore, bp->id, ignoreCount);
539 changed = true;
541 if (changed) {
542 // get the changes
543 m_d->queueCmd(DCinfobreak);
545 } else {
546 bp->condition = condition;
547 bp->ignoreCount = ignoreCount;
548 emit breakpointsChanged();
550 return true;
553 bool KDebugger::deleteBreakpoint(BrkptIterator bp)
555 if (bp == m_brkpts.end())
556 return false;
559 * Remove the breakpoint.
561 * The driver is not bothered if we are removing an orphaned
562 * breakpoint.
564 if (!bp->isOrphaned()) {
565 if (!canChangeBreakpoints()) {
566 return false;
568 m_d->executeCmd(DCdelete, bp->id);
569 } else {
570 m_brkpts.erase(bp);
571 emit breakpointsChanged();
573 return false;
576 bool KDebugger::canSingleStep()
578 return isReady() && m_programActive && !m_programRunning;
581 bool KDebugger::canChangeBreakpoints()
583 return isReady() && !m_programRunning;
586 bool KDebugger::canStart()
588 return isReady() && !m_programActive;
591 bool KDebugger::isReady() const
593 return m_haveExecutable &&
594 m_d != 0 && m_d->canExecuteImmediately();
597 bool KDebugger::isIdle() const
599 return m_d == 0 || m_d->isIdle();
603 //////////////////////////////////////////////////////////
604 // debugger driver
606 bool KDebugger::startDriver()
608 emit debuggerStarting(); /* must set m_inferiorTerminal */
611 * If the per-program command string is empty, use the global setting
612 * (which might also be empty, in which case the driver uses its
613 * default).
615 m_explicitKill = false;
616 if (!m_d->startup(m_debuggerCmd)) {
617 return false;
621 * If we have an output terminal, we use it. Otherwise we will run the
622 * program with input and output redirected to /dev/null. Other
623 * redirections are also necessary depending on the tty emulation
624 * level.
626 int redirect = RDNstdin|RDNstdout|RDNstderr; /* redirect everything */
627 if (!m_inferiorTerminal.isEmpty()) {
628 switch (m_ttyLevel) {
629 default:
630 case ttyNone:
631 // redirect everything
632 break;
633 case ttySimpleOutputOnly:
634 redirect = RDNstdin;
635 break;
636 case ttyFull:
637 redirect = 0;
638 break;
641 m_d->executeCmd(DCtty, m_inferiorTerminal, redirect);
643 return true;
646 void KDebugger::stopDriver()
648 m_explicitKill = true;
650 if (m_attachedPid.isEmpty()) {
651 m_d->terminate();
652 } else {
653 m_d->detachAndTerminate();
657 * We MUST wait until the slot gdbExited() has been called. But to
658 * avoid a deadlock, we wait only for some certain maximum time. Should
659 * this timeout be reached, the only reasonable thing one could do then
660 * is exiting kdbg.
662 QApplication::processEvents(QEventLoop::AllEvents, 1000);
663 int maxTime = 20; /* about 20 seconds */
664 while (m_haveExecutable && maxTime > 0) {
665 // give gdb time to die (and send a SIGCLD)
666 ::sleep(1);
667 --maxTime;
668 QApplication::processEvents(QEventLoop::AllEvents, 1000);
672 void KDebugger::gdbExited()
675 * Save settings, but only if gdb has already processed "info line
676 * main", otherwise we would save an empty config file, because it
677 * isn't read in until then!
679 if (m_programConfig != 0) {
680 if (m_haveExecutable) {
681 saveProgramSettings();
682 m_programConfig->sync();
684 delete m_programConfig;
685 m_programConfig = 0;
688 // erase types
689 delete m_typeTable;
690 m_typeTable = 0;
692 if (m_explicitKill) {
693 TRACE(m_d->driverName() + " exited normally");
694 } else {
695 QString msg = i18n("%1 exited unexpectedly.\n"
696 "Restart the session (e.g. with File|Load Executable).");
697 KMessageBox::error(parentWidget(), msg.arg(m_d->driverName()));
700 // reset state
701 m_haveExecutable = false;
702 m_executable = "";
703 m_programActive = false;
704 m_programRunning = false;
705 m_explicitKill = false;
706 m_debuggerCmd = QString(); /* use global setting at next start! */
707 m_attachedPid = QString(); /* we are no longer attached to a process */
708 m_ttyLevel = ttyFull;
709 m_brkpts.clear();
711 // erase PC
712 emit updatePC(QString(), -1, DbgAddr(), 0);
715 QString KDebugger::getConfigForExe(const QString& name)
717 QFileInfo fi(name);
718 QString dir = fi.absolutePath();
720 // The session file for the given executable consists of
721 // a hash of the directory, followed by the program name.
722 // Assume that the first 15 positions of the hash are unique;
723 // this keeps the file names short.
724 QCryptographicHash dirDigest(QCryptographicHash::Md5);
725 dirDigest.addData(dir.toUtf8());
726 QString hash = dirDigest.result().toBase64();
727 hash.replace('/', QString()); // avoid directory separators
728 return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)
729 + "/sessions/"
730 + hash.left(15) + "-" + fi.fileName();
733 void KDebugger::openProgramConfig(const QString& name)
735 ASSERT(m_programConfig == 0);
737 QString pgmConfigFile = getConfigForExe(name);
739 m_programConfig = new KConfig(pgmConfigFile);
741 // this leaves a clue behind in the config file which
742 // executable it applies to; it is mostly intended for
743 // users peeking into the file
744 KConfigGroup g = m_programConfig->group(GeneralGroup);
745 g.writeEntry("ExecutableFile", name);
748 const char EnvironmentGroup[] = "Environment";
749 const char WatchGroup[] = "Watches";
750 const char FileVersion[] = "FileVersion";
751 const char ProgramArgs[] = "ProgramArgs";
752 const char WorkingDirectory[] = "WorkingDirectory";
753 const char OptionsSelected[] = "OptionsSelected";
754 const char Variable[] = "Var%d";
755 const char Value[] = "Value%d";
756 const char ExprFmt[] = "Expr%d";
758 void KDebugger::saveProgramSettings()
760 ASSERT(m_programConfig != 0);
761 KConfigGroup gg = m_programConfig->group(GeneralGroup);
762 gg.writeEntry(FileVersion, 1);
763 gg.writeEntry(ProgramArgs, m_programArgs);
764 gg.writeEntry(WorkingDirectory, m_programWD);
765 gg.writeEntry(OptionsSelected, m_boolOptions.toList());
766 gg.writeEntry(DebuggerCmdStr, m_debuggerCmd);
767 gg.writeEntry(TTYLevelEntry, int(m_ttyLevel));
768 QString driverName;
769 if (m_d != 0)
770 driverName = m_d->driverName();
771 gg.writeEntry(DriverNameEntry, driverName);
773 // write environment variables
774 m_programConfig->deleteGroup(EnvironmentGroup);
775 KConfigGroup eg = m_programConfig->group(EnvironmentGroup);
776 QString varName;
777 QString varValue;
778 int i = 0;
779 for (std::map<QString,QString>::iterator it = m_envVars.begin(); it != m_envVars.end(); ++it, ++i)
781 varName.sprintf(Variable, i);
782 varValue.sprintf(Value, i);
783 eg.writeEntry(varName, it->first);
784 eg.writeEntry(varValue, it->second);
787 saveBreakpoints(m_programConfig);
789 // watch expressions
790 // first get rid of whatever was in this group
791 m_programConfig->deleteGroup(WatchGroup);
792 // then start a new group
793 KConfigGroup wg = m_programConfig->group(WatchGroup);
794 int watchNum = 0;
795 foreach (QString expr, m_watchVariables.exprList()) {
796 varName.sprintf(ExprFmt, watchNum++);
797 wg.writeEntry(varName, expr);
800 // give others a chance
801 emit saveProgramSpecific(m_programConfig);
804 void KDebugger::overrideProgramArguments(const QString& args)
806 ASSERT(m_programConfig != 0);
807 KConfigGroup g = m_programConfig->group(GeneralGroup);
808 g.writeEntry(ProgramArgs, args);
811 void KDebugger::restoreProgramSettings()
813 ASSERT(m_programConfig != 0);
814 KConfigGroup gg = m_programConfig->group(GeneralGroup);
816 * We ignore file version for now we will use it in the future to
817 * distinguish different versions of this configuration file.
819 // m_debuggerCmd has been read in already
820 // m_ttyLevel has been read in already
821 QString pgmArgs = gg.readEntry(ProgramArgs);
822 QString pgmWd = gg.readEntry(WorkingDirectory);
823 QSet<QString> boolOptions = QSet<QString>::fromList(gg.readEntry(OptionsSelected, QStringList()));
824 m_boolOptions.clear();
826 // read environment variables
827 KConfigGroup eg = m_programConfig->group(EnvironmentGroup);
828 m_envVars.clear();
829 std::map<QString,EnvVar> pgmVars;
830 QString varName;
831 QString varValue;
832 for (int i = 0;; ++i) {
833 varName.sprintf(Variable, i);
834 varValue.sprintf(Value, i);
835 if (!eg.hasKey(varName)) {
836 /* entry not present, assume that we've hit them all */
837 break;
839 QString name = eg.readEntry(varName, QString());
840 if (name.isEmpty()) {
841 // skip empty names
842 continue;
844 EnvVar* var = &pgmVars[name];
845 var->value = eg.readEntry(varValue, QString());
846 var->status = EnvVar::EVnew;
849 updateProgEnvironment(pgmArgs, pgmWd, pgmVars, boolOptions);
851 restoreBreakpoints(m_programConfig);
853 // watch expressions
854 KConfigGroup wg = m_programConfig->group(WatchGroup);
855 m_watchVariables.clear();
856 for (int i = 0;; ++i) {
857 varName.sprintf(ExprFmt, i);
858 if (!wg.hasKey(varName)) {
859 /* entry not present, assume that we've hit them all */
860 break;
862 QString expr = wg.readEntry(varName, QString());
863 if (expr.isEmpty()) {
864 // skip empty expressions
865 continue;
867 addWatch(expr);
870 // give others a chance
871 emit restoreProgramSpecific(m_programConfig);
875 * Reads the debugger command line from the program settings. The config
876 * group must have been set by the caller.
878 QString KDebugger::readDebuggerCmd(const KConfigGroup& g)
880 QString debuggerCmd = g.readEntry(DebuggerCmdStr);
882 // always let the user confirm the debugger cmd if we are root
883 if (::geteuid() == 0)
885 if (!debuggerCmd.isEmpty()) {
886 QString msg = i18n(
887 "The settings for this program specify "
888 "the following debugger command:\n%1\n"
889 "Shall this command be used?");
890 if (KMessageBox::warningYesNo(parentWidget(), msg.arg(debuggerCmd))
891 != KMessageBox::Yes)
893 // don't use it
894 debuggerCmd = QString();
898 return debuggerCmd;
902 * Breakpoints are saved one per group.
904 const char BPGroup[] = "Breakpoint %d";
905 const char File[] = "File";
906 const char Line[] = "Line";
907 const char Text[] = "Text";
908 const char Address[] = "Address";
909 const char Temporary[] = "Temporary";
910 const char Enabled[] = "Enabled";
911 const char Condition[] = "Condition";
913 void KDebugger::saveBreakpoints(KConfig* config)
915 QString groupName;
916 int i = 0;
917 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
919 if (bp->type == Breakpoint::watchpoint)
920 continue; /* don't save watchpoints */
921 groupName.sprintf(BPGroup, i++);
923 /* remove remmants */
924 config->deleteGroup(groupName);
926 KConfigGroup g = config->group(groupName);
927 if (!bp->text.isEmpty()) {
929 * The breakpoint was set using the text box in the breakpoint
930 * list. We do not save the location by filename+line number,
931 * but instead honor what the user typed (a function name, for
932 * example, which could move between sessions).
934 g.writeEntry(Text, bp->text);
935 } else if (!bp->fileName.isEmpty()) {
936 g.writeEntry(File, bp->fileName);
937 g.writeEntry(Line, bp->lineNo);
939 * Addresses are hardly correct across sessions, so we don't
940 * save it.
942 } else {
943 g.writeEntry(Address, bp->address.asString());
945 g.writeEntry(Temporary, bp->temporary);
946 g.writeEntry(Enabled, bp->enabled);
947 if (!bp->condition.isEmpty())
948 g.writeEntry(Condition, bp->condition);
949 // we do not save the ignore count
951 // delete remaining groups
952 // we recognize that a group is present if there is an Enabled entry
953 for (;; i++) {
954 groupName.sprintf(BPGroup, i);
955 if (!config->group(groupName).hasKey(Enabled)) {
956 /* group not present, assume that we've hit them all */
957 break;
959 config->deleteGroup(groupName);
963 void KDebugger::restoreBreakpoints(KConfig* config)
965 QString groupName;
967 * We recognize the end of the list if there is no Enabled entry
968 * present.
970 for (int i = 0;; i++) {
971 groupName.sprintf(BPGroup, i);
972 KConfigGroup g = config->group(groupName);
973 if (!g.hasKey(Enabled)) {
974 /* group not present, assume that we've hit them all */
975 break;
977 Breakpoint* bp = new Breakpoint;
978 bp->fileName = g.readEntry(File);
979 bp->lineNo = g.readEntry(Line, -1);
980 bp->text = g.readEntry(Text);
981 bp->address = g.readEntry(Address);
982 // check consistency
983 if ((bp->fileName.isEmpty() || bp->lineNo < 0) &&
984 bp->text.isEmpty() &&
985 bp->address.isEmpty())
987 delete bp;
988 continue;
990 bp->enabled = g.readEntry(Enabled, true);
991 bp->temporary = g.readEntry(Temporary, false);
992 bp->condition = g.readEntry(Condition);
995 * Add the breakpoint.
997 setBreakpoint(bp, false);
998 // the new breakpoint is disabled or conditionalized later
999 // in newBreakpoint()
1001 m_d->queueCmd(DCinfobreak);
1005 // parse output of command cmd
1006 void KDebugger::parse(CmdQueueItem* cmd, const char* output)
1008 ASSERT(cmd != 0); /* queue mustn't be empty */
1010 TRACE(QString(__PRETTY_FUNCTION__) + " parsing " + output);
1012 switch (cmd->m_cmd) {
1013 case DCtargetremote:
1014 // the output (if any) is uninteresting
1015 case DCsetargs:
1016 case DCtty:
1017 // there is no output
1018 case DCsetenv:
1019 case DCunsetenv:
1020 case DCsetoption:
1021 /* if value is empty, we see output, but we don't care */
1022 break;
1023 case DCcd:
1024 /* display gdb's message in the status bar */
1025 m_d->parseChangeWD(output, m_statusMessage);
1026 emit updateStatusMessage();
1027 break;
1028 case DCinitialize:
1029 break;
1030 case DCexecutable:
1031 if (m_d->parseChangeExecutable(output, m_statusMessage))
1033 // success; restore breakpoints etc.
1034 if (m_programConfig != 0) {
1035 restoreProgramSettings();
1037 // load file containing main() or core file
1038 if (!m_corefile.isEmpty())
1040 // load core file
1041 loadCoreFile();
1043 else if (!m_attachedPid.isEmpty())
1045 m_d->queueCmd(DCattach, m_attachedPid);
1046 m_programActive = true;
1047 m_programRunning = true;
1049 else if (!m_remoteDevice.isEmpty())
1051 // handled elsewhere
1053 else
1055 m_d->queueCmdAgain(DCinfolinemain);
1057 if (!m_statusMessage.isEmpty())
1058 emit updateStatusMessage();
1059 } else {
1060 QString msg = m_d->driverName() + ": " + m_statusMessage;
1061 KMessageBox::sorry(parentWidget(), msg);
1062 m_executable = "";
1063 m_corefile = ""; /* don't process core file */
1064 m_haveExecutable = false;
1066 break;
1067 case DCcorefile:
1068 // in any event we have an executable at this point
1069 m_haveExecutable = true;
1070 if (m_d->parseCoreFile(output)) {
1071 // loading a core is like stopping at a breakpoint
1072 m_programActive = true;
1073 handleRunCommands(output);
1074 // do not reset m_corefile
1075 } else {
1076 // report error
1077 QString msg = m_d->driverName() + ": " + QString(output);
1078 KMessageBox::sorry(parentWidget(), msg);
1080 // if core file was loaded from command line, revert to info line main
1081 if (!cmd->m_byUser) {
1082 m_d->queueCmdAgain(DCinfolinemain);
1084 m_corefile = QString(); /* core file not available any more */
1086 break;
1087 case DCinfolinemain:
1088 // ignore the output, marked file info follows
1089 m_haveExecutable = true;
1090 break;
1091 case DCinfolocals:
1092 // parse local variables
1093 if (output[0] != '\0') {
1094 handleLocals(output);
1096 break;
1097 case DCinforegisters:
1098 handleRegisters(output);
1099 break;
1100 case DCexamine:
1101 handleMemoryDump(output);
1102 break;
1103 case DCinfoline:
1104 handleInfoLine(cmd, output);
1105 break;
1106 case DCdisassemble:
1107 handleDisassemble(cmd, output);
1108 break;
1109 case DCframe:
1110 handleFrameChange(output);
1111 updateAllExprs();
1112 break;
1113 case DCbt:
1114 handleBacktrace(output);
1115 updateAllExprs();
1116 break;
1117 case DCprint:
1118 handlePrint(cmd, output);
1119 break;
1120 case DCprintPopup:
1121 handlePrintPopup(cmd, output);
1122 break;
1123 case DCprintDeref:
1124 handlePrintDeref(cmd, output);
1125 break;
1126 case DCattach:
1127 m_haveExecutable = true;
1128 // fall through
1129 case DCrun:
1130 case DCcont:
1131 case DCstep:
1132 case DCstepi:
1133 case DCnext:
1134 case DCnexti:
1135 case DCfinish:
1136 case DCuntil:
1137 case DCthread:
1138 handleRunCommands(output);
1139 break;
1140 case DCkill:
1141 case DCdetach:
1142 m_programRunning = m_programActive = false;
1143 // erase PC
1144 emit updatePC(QString(), -1, DbgAddr(), 0);
1145 break;
1146 case DCbreaktext:
1147 case DCbreakline:
1148 case DCtbreakline:
1149 case DCbreakaddr:
1150 case DCtbreakaddr:
1151 case DCwatchpoint:
1152 newBreakpoint(cmd, output);
1153 // fall through
1154 case DCdelete:
1155 case DCenable:
1156 case DCdisable:
1157 // these commands need immediate response
1158 m_d->queueCmdPrio(DCinfobreak);
1159 break;
1160 case DCinfobreak:
1161 // note: this handler must not enqueue a command, since
1162 // DCinfobreak is used at various different places.
1163 updateBreakList(output);
1164 break;
1165 case DCfindType:
1166 handleFindType(cmd, output);
1167 break;
1168 case DCprintStruct:
1169 case DCprintQStringStruct:
1170 case DCprintWChar:
1171 handlePrintStruct(cmd, output);
1172 break;
1173 case DCinfosharedlib:
1174 handleSharedLibs(output);
1175 break;
1176 case DCcondition:
1177 case DCignore:
1178 // we are not interested in the output
1179 break;
1180 case DCinfothreads:
1181 handleThreadList(output);
1182 break;
1183 case DCsetpc:
1184 handleSetPC(output);
1185 break;
1186 case DCsetvariable:
1187 handleSetVariable(cmd, output);
1188 break;
1192 void KDebugger::backgroundUpdate()
1195 * If there are still expressions that need to be updated, then do so.
1197 if (m_programActive)
1198 evalExpressions();
1201 void KDebugger::handleRunCommands(const char* output)
1203 uint flags = m_d->parseProgramStopped(output, !m_corefile.isEmpty(),
1204 m_statusMessage);
1205 emit updateStatusMessage();
1207 m_programActive = flags & DebuggerDriver::SFprogramActive;
1209 // refresh files if necessary
1210 if (flags & DebuggerDriver::SFrefreshSource) {
1211 TRACE("re-reading files");
1212 emit executableUpdated();
1216 * Try to set any orphaned breakpoints now.
1218 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
1220 if (bp->isOrphaned()) {
1221 TRACE(QString("re-trying brkpt loc: %2 file: %3 line: %1")
1222 .arg(bp->lineNo).arg(bp->location, bp->fileName));
1223 CmdQueueItem* cmd = executeBreakpoint(&*bp, true);
1224 cmd->m_existingBrkpt = bp->id; // used in newBreakpoint()
1225 flags |= DebuggerDriver::SFrefreshBreak;
1230 * If we stopped at a breakpoint, we must update the breakpoint list
1231 * because the hit count changes. Also, if the breakpoint was temporary
1232 * it would go away now.
1234 if ((flags & (DebuggerDriver::SFrefreshBreak|DebuggerDriver::SFrefreshSource)) ||
1235 stopMayChangeBreakList())
1237 m_d->queueCmd(DCinfobreak);
1241 * If we haven't listed the shared libraries yet, do so. We must do
1242 * this before we emit any commands that list variables, since the type
1243 * libraries depend on the shared libraries.
1245 if (!m_sharedLibsListed) {
1246 // must be a high-priority command!
1247 m_d->executeCmd(DCinfosharedlib);
1250 // get the backtrace if the program is running
1251 if (m_programActive) {
1252 m_d->queueCmd(DCbt);
1253 } else {
1254 // program finished: erase PC
1255 emit updatePC(QString(), -1, DbgAddr(), 0);
1256 // dequeue any commands in the queues
1257 m_d->flushCommands();
1260 /* Update threads list */
1261 if (m_programActive && (flags & DebuggerDriver::SFrefreshThreads)) {
1262 m_d->queueCmd(DCinfothreads);
1265 m_programRunning = false;
1266 emit programStopped();
1269 void KDebugger::slotInferiorRunning()
1271 m_programRunning = true;
1274 void KDebugger::updateAllExprs()
1276 if (!m_programActive)
1277 return;
1279 // retrieve local variables
1280 m_d->queueCmd(DCinfolocals);
1282 // retrieve registers
1283 m_d->queueCmd(DCinforegisters);
1285 // get new memory dump
1286 if (!m_memoryStartExpression.isEmpty()) {
1287 queueMemoryDump(false, true);
1290 // update watch expressions
1291 foreach (QString expr, m_watchVariables.exprList()) {
1292 m_watchEvalExpr.push_back(expr);
1296 void KDebugger::updateProgEnvironment(const QString& args, const QString& wd,
1297 const std::map<QString,EnvVar>& newVars,
1298 const QSet<QString>& newOptions)
1300 m_programArgs = args;
1301 m_d->executeCmd(DCsetargs, m_programArgs);
1302 TRACE("new pgm args: " + m_programArgs + "\n");
1304 m_programWD = wd.trimmed();
1305 if (!m_programWD.isEmpty()) {
1306 m_d->executeCmd(DCcd, m_programWD);
1307 TRACE("new wd: " + m_programWD + "\n");
1310 // update environment variables
1311 for (std::map<QString,EnvVar>::const_iterator i = newVars.begin(); i != newVars.end(); ++i)
1313 QString var = i->first;
1314 const EnvVar* val = &i->second;
1315 switch (val->status) {
1316 case EnvVar::EVnew:
1317 case EnvVar::EVdirty:
1318 m_envVars[var] = val->value;
1319 // update value
1320 m_d->executeCmd(DCsetenv, var, val->value);
1321 break;
1322 case EnvVar::EVdeleted:
1323 // delete value
1324 m_d->executeCmd(DCunsetenv, var);
1325 m_envVars.erase(var);
1326 break;
1327 default:
1328 ASSERT(false);
1329 case EnvVar::EVclean:
1330 // variable not changed
1331 break;
1335 // update options
1336 foreach (QString opt, newOptions - m_boolOptions)
1338 // option is not set, set it
1339 m_d->executeCmd(DCsetoption, opt, 1);
1341 foreach (QString opt, m_boolOptions - newOptions)
1343 // option is set, unset it
1344 m_d->executeCmd(DCsetoption, opt, 0);
1346 m_boolOptions = newOptions;
1349 void KDebugger::handleLocals(const char* output)
1351 // retrieve old list of local variables
1352 QStringList oldVars = m_localVariables.exprList();
1355 * Get local variables.
1357 std::list<ExprValue*> newVars;
1358 parseLocals(output, newVars);
1361 * Clear any old VarTree item pointers, so that later we don't access
1362 * dangling pointers.
1364 m_localVariables.clearPendingUpdates();
1367 * Match old variables against new ones.
1369 for (QStringList::ConstIterator n = oldVars.begin(); n != oldVars.end(); ++n) {
1370 // lookup this variable in the list of new variables
1371 std::list<ExprValue*>::iterator v = newVars.begin();
1372 while (v != newVars.end() && (*v)->m_name != *n)
1373 ++v;
1374 if (v == newVars.end()) {
1375 // old variable not in the new variables
1376 TRACE("old var deleted: " + *n);
1377 VarTree* v = m_localVariables.topLevelExprByName(*n);
1378 if (v != 0) {
1379 m_localVariables.removeExpr(v);
1381 } else {
1382 // variable in both old and new lists: update
1383 TRACE("update var: " + *n);
1384 m_localVariables.updateExpr(*v, *m_typeTable);
1385 // remove the new variable from the list
1386 delete *v;
1387 newVars.erase(v);
1390 // insert all remaining new variables
1391 while (!newVars.empty())
1393 ExprValue* v = newVars.front();
1394 TRACE("new var: " + v->m_name);
1395 m_localVariables.insertExpr(v, *m_typeTable);
1396 delete v;
1397 newVars.pop_front();
1401 void KDebugger::parseLocals(const char* output, std::list<ExprValue*>& newVars)
1403 std::list<ExprValue*> vars;
1404 m_d->parseLocals(output, vars);
1406 QString origName; /* used in renaming variables */
1407 while (!vars.empty())
1409 ExprValue* variable = vars.front();
1410 vars.pop_front();
1412 * When gdb prints local variables, those from the innermost block
1413 * come first. We run through the list of already parsed variables
1414 * to find duplicates (ie. variables that hide local variables from
1415 * a surrounding block). We keep the name of the inner variable, but
1416 * rename those from the outer block so that, when the value is
1417 * updated in the window, the value of the variable that is
1418 * _visible_ changes the color!
1420 int block = 0;
1421 origName = variable->m_name;
1422 for (std::list<ExprValue*>::iterator v = newVars.begin(); v != newVars.end(); ++v) {
1423 if (variable->m_name == (*v)->m_name) {
1424 // we found a duplicate, change name
1425 block++;
1426 QString newName = origName + " (" + QString().setNum(block) + ")";
1427 variable->m_name = newName;
1430 newVars.push_back(variable);
1434 bool KDebugger::handlePrint(CmdQueueItem* cmd, const char* output)
1436 ASSERT(cmd->m_expr != 0);
1438 ExprValue* variable = m_d->parsePrintExpr(output, true);
1439 if (variable == 0)
1440 return false;
1442 // set expression "name"
1443 variable->m_name = cmd->m_expr->getText();
1446 TRACE("update expr: " + cmd->m_expr->getText());
1447 cmd->m_exprWnd->updateExpr(cmd->m_expr, variable, *m_typeTable);
1448 delete variable;
1451 evalExpressions(); /* enqueue dereferenced pointers */
1453 return true;
1456 bool KDebugger::handlePrintPopup(CmdQueueItem* cmd, const char* output)
1458 ExprValue* value = m_d->parsePrintExpr(output, false);
1459 if (value == 0)
1460 return false;
1462 TRACE("<" + cmd->m_popupExpr + "> = " + value->m_value);
1464 // construct the tip, m_popupExpr contains the variable name
1465 QString tip = cmd->m_popupExpr + " = " + formatPopupValue(value);
1466 emit valuePopup(tip);
1468 return true;
1471 bool KDebugger::handlePrintDeref(CmdQueueItem* cmd, const char* output)
1473 ASSERT(cmd->m_expr != 0);
1475 ExprValue* variable = m_d->parsePrintExpr(output, true);
1476 if (variable == 0)
1477 return false;
1479 // set expression "name"
1480 variable->m_name = cmd->m_expr->getText();
1484 * We must insert a dummy parent, because otherwise variable's value
1485 * would overwrite cmd->m_expr's value.
1487 ExprValue* dummyParent = new ExprValue(variable->m_name, VarTree::NKplain);
1488 dummyParent->m_varKind = VarTree::VKdummy;
1489 // the name of the parsed variable is the address of the pointer
1490 QString addr = "*" + cmd->m_expr->value();
1491 variable->m_name = addr;
1492 variable->m_nameKind = VarTree::NKaddress;
1494 dummyParent->m_child = variable;
1495 // expand the first level for convenience
1496 variable->m_initiallyExpanded = true;
1497 TRACE("update ptr: " + cmd->m_expr->getText());
1498 cmd->m_exprWnd->updateExpr(cmd->m_expr, dummyParent, *m_typeTable);
1499 delete dummyParent;
1502 evalExpressions(); /* enqueue dereferenced pointers */
1504 return true;
1507 // parse the output of bt
1508 void KDebugger::handleBacktrace(const char* output)
1510 m_btWindow.clear();
1512 std::list<StackFrame> stack;
1513 m_d->parseBackTrace(output, stack);
1515 if (!stack.empty()) {
1516 std::list<StackFrame>::iterator frm = stack.begin();
1517 // first frame must set PC
1518 // note: frm->lineNo is zero-based
1519 emit updatePC(frm->fileName, frm->lineNo, frm->address, frm->frameNo);
1521 for (; frm != stack.end(); ++frm) {
1522 QString func;
1523 if (frm->var != 0)
1524 func = frm->var->m_name;
1525 else
1526 func = frm->fileName + ":" + QString().setNum(frm->lineNo+1);
1528 m_btWindow.addItem(func);
1529 TRACE("frame " + func + " (" + frm->fileName + ":" +
1530 QString().setNum(frm->lineNo+1) + ")");
1536 void KDebugger::gotoFrame(int frame)
1538 // frame is negative when the backtrace list is cleared
1539 // ignore this event
1540 if (frame < 0)
1541 return;
1542 m_d->executeCmd(DCframe, frame);
1545 void KDebugger::handleFrameChange(const char* output)
1547 QString fileName;
1548 int frameNo;
1549 int lineNo;
1550 DbgAddr address;
1551 if (m_d->parseFrameChange(output, frameNo, fileName, lineNo, address)) {
1552 /* lineNo can be negative here if we can't find a file name */
1553 emit updatePC(fileName, lineNo, address, frameNo);
1554 } else {
1555 emit updatePC(fileName, -1, address, frameNo);
1559 void KDebugger::evalExpressions()
1561 // evaluate expressions in the following order:
1562 // watch expressions
1563 // pointers in local variables
1564 // pointers in watch expressions
1565 // types in local variables
1566 // types in watch expressions
1567 // struct members in local variables
1568 // struct members in watch expressions
1569 VarTree* exprItem = 0;
1570 if (!m_watchEvalExpr.empty())
1572 QString expr = m_watchEvalExpr.front();
1573 m_watchEvalExpr.pop_front();
1574 exprItem = m_watchVariables.topLevelExprByName(expr);
1576 if (exprItem != 0) {
1577 CmdQueueItem* cmd = m_d->queueCmd(DCprint, exprItem->getText());
1578 // remember which expr this was
1579 cmd->m_expr = exprItem;
1580 cmd->m_exprWnd = &m_watchVariables;
1581 } else {
1582 ExprWnd* wnd;
1583 #define POINTER(widget) \
1584 wnd = &widget; \
1585 exprItem = widget.nextUpdatePtr(); \
1586 if (exprItem != 0) goto pointer
1587 #define STRUCT(widget) \
1588 wnd = &widget; \
1589 exprItem = widget.nextUpdateStruct(); \
1590 if (exprItem != 0) goto ustruct
1591 #define TYPE(widget) \
1592 wnd = &widget; \
1593 exprItem = widget.nextUpdateType(); \
1594 if (exprItem != 0) goto type
1595 repeat:
1596 POINTER(m_localVariables);
1597 POINTER(m_watchVariables);
1598 STRUCT(m_localVariables);
1599 STRUCT(m_watchVariables);
1600 TYPE(m_localVariables);
1601 TYPE(m_watchVariables);
1602 #undef POINTER
1603 #undef STRUCT
1604 #undef TYPE
1605 return;
1607 pointer:
1608 // we have an expression to send
1609 dereferencePointer(wnd, exprItem, false);
1610 return;
1612 ustruct:
1613 // paranoia
1614 if (exprItem->m_type == 0 || exprItem->m_type == TypeInfo::unknownType())
1615 goto repeat;
1616 evalInitialStructExpression(exprItem, wnd, false);
1617 return;
1619 type:
1621 * Sometimes a VarTree gets registered twice for a type update. So
1622 * it may happen that it has already been updated. Hence, we ignore
1623 * it here and go on to the next task.
1625 if (exprItem->m_type != 0)
1626 goto repeat;
1627 determineType(wnd, exprItem);
1631 void KDebugger::dereferencePointer(ExprWnd* wnd, VarTree* exprItem,
1632 bool immediate)
1634 ASSERT(exprItem->m_varKind == VarTree::VKpointer);
1636 QString expr = exprItem->computeExpr();
1637 TRACE("dereferencing pointer: " + expr);
1638 CmdQueueItem* cmd;
1639 if (immediate) {
1640 cmd = m_d->queueCmdPrio(DCprintDeref, expr);
1641 } else {
1642 cmd = m_d->queueCmd(DCprintDeref, expr);
1644 // remember which expr this was
1645 cmd->m_expr = exprItem;
1646 cmd->m_exprWnd = wnd;
1649 void KDebugger::determineType(ExprWnd* wnd, VarTree* exprItem)
1651 ASSERT(exprItem->m_varKind == VarTree::VKstruct);
1653 QString expr = exprItem->computeExpr();
1654 TRACE("get type of: " + expr);
1655 CmdQueueItem* cmd;
1656 cmd = m_d->queueCmd(DCfindType, expr);
1658 // remember which expr this was
1659 cmd->m_expr = exprItem;
1660 cmd->m_exprWnd = wnd;
1663 void KDebugger::handleFindType(CmdQueueItem* cmd, const char* output)
1665 QString type;
1666 if (m_d->parseFindType(output, type))
1668 ASSERT(cmd != 0 && cmd->m_expr != 0);
1670 const TypeInfo* info = m_typeTable->lookup(type);
1672 if (info == 0) {
1674 * We've asked gdb for the type of the expression in
1675 * cmd->m_expr, but it returned a name we don't know. The base
1676 * class (and member) types have been checked already (at the
1677 * time when we parsed that particular expression). Now it's
1678 * time to derive the type from the base classes as a last
1679 * resort.
1681 info = cmd->m_expr->inferTypeFromBaseClass();
1682 // if we found a type through this method, register an alias
1683 if (info != 0) {
1684 TRACE("infered alias: " + type);
1685 m_typeTable->registerAlias(type, info);
1688 if (info == 0) {
1689 TRACE("unknown type "+type);
1690 cmd->m_expr->m_type = TypeInfo::unknownType();
1691 } else {
1692 cmd->m_expr->m_type = info;
1693 /* since this node has a new type, we get its value immediately */
1694 evalInitialStructExpression(cmd->m_expr, cmd->m_exprWnd, false);
1695 return;
1699 evalExpressions(); /* queue more of them */
1702 void KDebugger::handlePrintStruct(CmdQueueItem* cmd, const char* output)
1704 VarTree* var = cmd->m_expr;
1705 ASSERT(var != 0);
1706 ASSERT(var->m_varKind == VarTree::VKstruct);
1708 ExprValue* partExpr;
1709 if (cmd->m_cmd == DCprintQStringStruct) {
1710 partExpr = m_d->parseQCharArray(output, false, m_typeTable->qCharIsShort());
1711 } else if (cmd->m_cmd == DCprintWChar) {
1712 partExpr = m_d->parseQCharArray(output, false, true);
1713 } else {
1714 partExpr = m_d->parsePrintExpr(output, false);
1716 bool errorValue =
1717 partExpr == 0 ||
1718 /* we only allow simple values at the moment */
1719 partExpr->m_child != 0;
1721 QString partValue;
1722 if (errorValue)
1724 partValue = "?""?""?"; // 2 question marks in a row would be a trigraph
1725 } else {
1726 partValue = partExpr->m_value;
1728 delete partExpr;
1729 partExpr = 0;
1732 * Updating a struct value works like this: var->m_partialValue holds
1733 * the value that we have gathered so far (it's been initialized with
1734 * var->m_type->m_displayString[0] earlier). Each time we arrive here,
1735 * we append the printed result followed by the next
1736 * var->m_type->m_displayString to var->m_partialValue.
1738 * If the expression we just evaluated was a guard expression, and it
1739 * resulted in an error, we must not evaluate the real expression, but
1740 * go on to the next index. (We must still add the question marks to
1741 * the value).
1743 * Next, if this was the length expression, we still have not seen the
1744 * real expression, but the length of a QString.
1746 ASSERT(var->m_exprIndex >= 0 && var->m_exprIndex <= typeInfoMaxExpr);
1748 if (errorValue || !var->m_exprIndexUseGuard)
1750 // add current partValue (which might be the question marks)
1751 var->m_partialValue += partValue;
1752 var->m_exprIndex++; /* next part */
1753 var->m_exprIndexUseGuard = true;
1754 var->m_partialValue += var->m_type->m_displayString[var->m_exprIndex];
1756 else
1758 // this was a guard expression that succeeded
1759 // go for the real expression
1760 var->m_exprIndexUseGuard = false;
1763 /* go for more sub-expressions if needed */
1764 if (var->m_exprIndex < var->m_type->m_numExprs) {
1765 /* queue a new print command with quite high priority */
1766 evalStructExpression(var, cmd->m_exprWnd, true);
1767 return;
1770 cmd->m_exprWnd->updateStructValue(var);
1772 evalExpressions(); /* enqueue dereferenced pointers */
1775 /* queues the first printStruct command for a struct */
1776 void KDebugger::evalInitialStructExpression(VarTree* var, ExprWnd* wnd, bool immediate)
1778 var->m_exprIndex = 0;
1779 if (var->m_type != TypeInfo::wchartType())
1781 var->m_exprIndexUseGuard = true;
1782 var->m_partialValue = var->m_type->m_displayString[0];
1783 evalStructExpression(var, wnd, immediate);
1785 else
1787 var->m_exprIndexUseGuard = false;
1788 QString expr = var->computeExpr();
1789 CmdQueueItem* cmd = immediate ?
1790 m_d->queueCmdPrio(DCprintWChar, expr) :
1791 m_d->queueCmd(DCprintWChar, expr) ;
1792 // remember which expression this was
1793 cmd->m_expr = var;
1794 cmd->m_exprWnd = wnd;
1798 /** queues a printStruct command; var must have been initialized correctly */
1799 void KDebugger::evalStructExpression(VarTree* var, ExprWnd* wnd, bool immediate)
1801 QString base = var->computeExpr();
1802 QString expr;
1803 if (var->m_exprIndexUseGuard) {
1804 expr = var->m_type->m_guardStrings[var->m_exprIndex];
1805 if (expr.isEmpty()) {
1806 // no guard, omit it and go to expression
1807 var->m_exprIndexUseGuard = false;
1810 if (!var->m_exprIndexUseGuard) {
1811 expr = var->m_type->m_exprStrings[var->m_exprIndex];
1814 expr.replace("%s", base);
1816 DbgCommand dbgCmd = DCprintStruct;
1817 // check if this is a QString::Data
1818 if (expr.left(15) == "/QString::Data ")
1820 if (m_typeTable->parseQt2QStrings())
1822 expr = expr.mid(15, expr.length()); /* strip off /QString::Data */
1823 dbgCmd = DCprintQStringStruct;
1824 } else {
1826 * This should not happen: the type libraries should be set up
1827 * in a way that this can't happen. If this happens
1828 * nevertheless it means that, eg., kdecore was loaded but qt2
1829 * was not (only qt2 enables the QString feature).
1831 // TODO: remove this "print"; queue the next printStruct instead
1832 expr = "*0";
1835 TRACE("evalStruct: " + expr + (var->m_exprIndexUseGuard ? " // guard" : " // real"));
1836 CmdQueueItem* cmd = immediate ?
1837 m_d->queueCmdPrio(dbgCmd, expr) :
1838 m_d->queueCmd(dbgCmd, expr);
1840 // remember which expression this was
1841 cmd->m_expr = var;
1842 cmd->m_exprWnd = wnd;
1845 void KDebugger::handleSharedLibs(const char* output)
1847 // parse the table of shared libraries
1848 m_sharedLibs = m_d->parseSharedLibs(output);
1849 m_sharedLibsListed = true;
1851 // get type libraries
1852 m_typeTable->loadLibTypes(m_sharedLibs);
1854 // hand over the QString data cmd
1855 m_d->setPrintQStringDataCmd(m_typeTable->printQStringDataCmd());
1858 CmdQueueItem* KDebugger::loadCoreFile()
1860 return m_d->queueCmd(DCcorefile, m_corefile);
1863 void KDebugger::slotExpanding(QTreeWidgetItem* item)
1865 VarTree* exprItem = static_cast<VarTree*>(item);
1866 if (exprItem->m_varKind != VarTree::VKpointer) {
1867 return;
1869 ExprWnd* wnd = static_cast<ExprWnd*>(item->treeWidget());
1870 dereferencePointer(wnd, exprItem, true);
1873 // add the expression in the edit field to the watch expressions
1874 void KDebugger::addWatch(const QString& t)
1876 QString expr = t.trimmed();
1877 // don't add a watched expression again
1878 if (expr.isEmpty() || m_watchVariables.topLevelExprByName(expr) != 0)
1879 return;
1880 ExprValue e(expr, VarTree::NKplain);
1881 m_watchVariables.insertExpr(&e, *m_typeTable);
1883 // if we are boring ourselves, send down the command
1884 if (m_programActive) {
1885 m_watchEvalExpr.push_back(expr);
1886 if (m_d->isIdle()) {
1887 evalExpressions();
1892 // delete a toplevel watch expression
1893 void KDebugger::slotDeleteWatch()
1895 // delete only allowed while debugger is idle; or else we might delete
1896 // the very expression the debugger is currently working on...
1897 if (m_d == 0 || !m_d->isIdle())
1898 return;
1900 VarTree* item = m_watchVariables.selectedItem();
1901 if (item == 0 || !item->isToplevelExpr())
1902 return;
1904 // remove the variable from the list to evaluate
1905 std::list<QString>::iterator i =
1906 std::find(m_watchEvalExpr.begin(), m_watchEvalExpr.end(), item->getText());
1907 if (i != m_watchEvalExpr.end()) {
1908 m_watchEvalExpr.erase(i);
1910 m_watchVariables.removeExpr(item);
1911 // item is invalid at this point!
1914 void KDebugger::handleRegisters(const char* output)
1916 emit registersChanged(m_d->parseRegisters(output));
1920 * The output of the DCbreak* commands has more accurate information about
1921 * the file and the line number.
1923 * All newly set breakpoints are inserted in the m_brkpts, even those that
1924 * were not set sucessfully. The unsuccessful breakpoints ("orphaned
1925 * breakpoints") are assigned negative ids, and they are tried to set later
1926 * when the program stops again at a breakpoint.
1928 void KDebugger::newBreakpoint(CmdQueueItem* cmd, const char* output)
1930 BrkptIterator bp;
1931 if (cmd->m_brkpt != 0) {
1932 // a new breakpoint, put it in the list
1933 assert(cmd->m_brkpt->id == 0);
1934 m_brkpts.push_back(*cmd->m_brkpt);
1935 delete cmd->m_brkpt;
1936 bp = m_brkpts.end();
1937 --bp;
1938 } else {
1939 // an existing breakpoint was retried
1940 assert(cmd->m_existingBrkpt != 0);
1941 bp = breakpointById(cmd->m_existingBrkpt);
1942 if (bp == m_brkpts.end())
1943 return;
1946 // parse the output to determine success or failure
1947 int id;
1948 QString file;
1949 int lineNo;
1950 QString address;
1951 if (!m_d->parseBreakpoint(output, id, file, lineNo, address))
1954 * Failure, the breakpoint could not be set. If this is a new
1955 * breakpoint, assign it a negative id. We look for the minimal id
1956 * of all breakpoints (that are already in the list) to get the new
1957 * id.
1959 if (bp->id == 0)
1961 int minId = 0;
1962 for (BrkptIterator i = m_brkpts.begin(); i != m_brkpts.end(); ++i) {
1963 if (i->id < minId)
1964 minId = i->id;
1966 bp->id = minId-1;
1968 return;
1971 // The breakpoint was successfully set.
1972 if (bp->id <= 0)
1974 // this is a new or orphaned breakpoint:
1975 // set the remaining properties
1976 if (!bp->enabled) {
1977 m_d->executeCmd(DCdisable, id);
1979 if (!bp->condition.isEmpty()) {
1980 m_d->executeCmd(DCcondition, bp->condition, id);
1984 bp->id = id;
1985 bp->fileName = file;
1986 bp->lineNo = lineNo;
1987 if (!address.isEmpty())
1988 bp->address = address;
1991 void KDebugger::updateBreakList(const char* output)
1993 // get the new list
1994 std::list<Breakpoint> brks;
1995 m_d->parseBreakList(output, brks);
1997 // merge existing information into the new list
1998 // then swap the old and new lists
2000 for (BrkptIterator bp = brks.begin(); bp != brks.end(); ++bp)
2002 BrkptIterator i = breakpointById(bp->id);
2003 if (i != m_brkpts.end())
2005 // preserve accurate location information
2006 // note that xsldbg doesn't have a location in
2007 // the listed breakpoint if it has just been set
2008 // therefore, we copy it as well if necessary
2009 bp->text = i->text;
2010 if (!i->fileName.isEmpty()) {
2011 bp->fileName = i->fileName;
2012 bp->lineNo = i->lineNo;
2017 // orphaned breakpoints must be copied
2018 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
2020 if (bp->isOrphaned())
2021 brks.push_back(*bp);
2024 m_brkpts.swap(brks);
2025 emit breakpointsChanged();
2028 // look if there is at least one temporary breakpoint
2029 // or a watchpoint
2030 bool KDebugger::stopMayChangeBreakList() const
2032 for (BrkptROIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
2034 if (bp->temporary || bp->type == Breakpoint::watchpoint)
2035 return true;
2037 return false;
2040 KDebugger::BrkptIterator KDebugger::breakpointByFilePos(QString file, int lineNo,
2041 const DbgAddr& address)
2043 // look for exact file name match
2044 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
2046 if (bp->lineNo == lineNo &&
2047 bp->fileName == file &&
2048 (address.isEmpty() || bp->address == address))
2050 return bp;
2053 // not found, so try basename
2054 file = QFileInfo(file).fileName();
2056 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
2058 // get base name of breakpoint's file
2059 QString basename = QFileInfo(bp->fileName).fileName();
2061 if (bp->lineNo == lineNo &&
2062 basename == file &&
2063 (address.isEmpty() || bp->address == address))
2065 return bp;
2069 // not found
2070 return m_brkpts.end();
2073 KDebugger::BrkptIterator KDebugger::breakpointById(int id)
2075 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
2077 if (bp->id == id) {
2078 return bp;
2081 // not found
2082 return m_brkpts.end();
2085 void KDebugger::slotValuePopup(const QString& expr)
2087 // search the local variables for a match
2088 VarTree* v = m_localVariables.topLevelExprByName(expr);
2089 if (v == 0) {
2090 // not found, check watch expressions
2091 v = m_watchVariables.topLevelExprByName(expr);
2092 if (v == 0) {
2093 // try a member of 'this'
2094 v = m_localVariables.topLevelExprByName("this");
2095 if (v != 0)
2096 v = ExprWnd::ptrMemberByName(v, expr);
2097 if (v == 0) {
2098 // nothing found, try printing variable in gdb
2099 if (m_d) {
2100 CmdQueueItem *cmd = m_d->executeCmd(DCprintPopup, expr);
2101 cmd->m_popupExpr = expr;
2103 return;
2108 // construct the tip
2109 QString tip = v->getText() + " = " + formatPopupValue(v);
2110 emit valuePopup(tip);
2113 void KDebugger::slotDisassemble(const QString& fileName, int lineNo)
2115 if (m_haveExecutable) {
2116 CmdQueueItem* cmd = m_d->queueCmdPrio(DCinfoline, fileName, lineNo);
2117 cmd->m_fileName = fileName;
2118 cmd->m_lineNo = lineNo;
2122 void KDebugger::handleInfoLine(CmdQueueItem* cmd, const char* output)
2124 QString addrFrom, addrTo;
2125 if (cmd->m_lineNo >= 0) {
2126 // disassemble
2127 if (m_d->parseInfoLine(output, addrFrom, addrTo)) {
2128 // got the address range, now get the real code
2129 CmdQueueItem* c = m_d->queueCmdPrio(DCdisassemble, addrFrom, addrTo);
2130 c->m_fileName = cmd->m_fileName;
2131 c->m_lineNo = cmd->m_lineNo;
2132 } else {
2133 // no code
2134 emit disassembled(cmd->m_fileName, cmd->m_lineNo, std::list<DisassembledCode>());
2136 } else {
2137 // set program counter
2138 if (m_d->parseInfoLine(output, addrFrom, addrTo)) {
2139 // move the program counter to the start address
2140 m_d->executeCmd(DCsetpc, addrFrom);
2145 void KDebugger::handleDisassemble(CmdQueueItem* cmd, const char* output)
2147 emit disassembled(cmd->m_fileName, cmd->m_lineNo,
2148 m_d->parseDisassemble(output));
2151 void KDebugger::handleThreadList(const char* output)
2153 emit threadsChanged(m_d->parseThreadList(output));
2156 void KDebugger::setThread(int id)
2158 m_d->queueCmdPrio(DCthread, id);
2161 void KDebugger::setMemoryExpression(const QString& start_memexpr, unsigned total_length,
2162 const QString& current_memexpr, unsigned current_length)
2164 m_memoryExpression = current_memexpr;
2165 m_memoryLength = current_length;
2166 m_memoryStartExpression = start_memexpr;
2167 m_memoryTotalLength = total_length;
2169 // queue the new expression
2170 if (!m_memoryExpression.isEmpty() &&
2171 isProgramActive() &&
2172 !isProgramRunning())
2174 queueMemoryDump(true, false);
2178 void KDebugger::queueMemoryDump(bool immediate, bool update)
2180 if (update) {
2181 if (immediate)
2182 m_d->queueCmdPrio(DCexamine, m_memoryStartExpression, m_memoryFormat, m_memoryTotalLength);
2183 else
2184 m_d->queueCmd(DCexamine, m_memoryStartExpression, m_memoryFormat, m_memoryTotalLength);
2185 } else {
2186 if (immediate)
2187 m_d->queueCmdPrio(DCexamine, m_memoryExpression, m_memoryFormat, m_memoryLength);
2188 else
2189 m_d->queueCmd(DCexamine, m_memoryExpression, m_memoryFormat, m_memoryLength);
2193 void KDebugger::handleMemoryDump(const char* output)
2195 std::list<MemoryDump> memdump;
2196 QString msg = m_d->parseMemoryDump(output, memdump);
2197 emit memoryDumpChanged(msg, memdump);
2200 void KDebugger::setProgramCounter(const QString& file, int line, const DbgAddr& addr)
2202 if (addr.isEmpty()) {
2203 // find address of the specified line
2204 CmdQueueItem* cmd = m_d->executeCmd(DCinfoline, file, line);
2205 cmd->m_lineNo = -1; /* indicates "Set PC" UI command */
2206 } else {
2207 // move the program counter to that address
2208 m_d->executeCmd(DCsetpc, addr.asString());
2212 void KDebugger::handleSetPC(const char* /*output*/)
2214 // TODO: handle errors
2216 // now go to the top-most frame
2217 // this also modifies the program counter indicator in the UI
2218 gotoFrame(0);
2221 void KDebugger::slotValueEdited(VarTree* expr, const QString& text)
2223 if (text.simplified().isEmpty())
2224 return; /* no text entered: ignore request */
2226 ExprWnd* wnd = static_cast<ExprWnd*>(expr->treeWidget());
2227 TRACE(QString().sprintf("Changing %s to ",
2228 wnd->name()) + text);
2230 // determine the lvalue to edit
2231 QString lvalue = expr->computeExpr();
2232 CmdQueueItem* cmd = m_d->executeCmd(DCsetvariable, lvalue, text);
2233 cmd->m_expr = expr;
2234 cmd->m_exprWnd = wnd;
2237 void KDebugger::handleSetVariable(CmdQueueItem* cmd, const char* output)
2239 QString msg = m_d->parseSetVariable(output);
2240 if (!msg.isEmpty())
2242 // there was an error; display it in the status bar
2243 m_statusMessage = msg;
2244 emit updateStatusMessage();
2245 return;
2248 // get the new value
2249 QString expr = cmd->m_expr->computeExpr();
2250 CmdQueueItem* printCmd = m_d->queueCmdPrio(DCprint, expr);
2251 printCmd->m_expr = cmd->m_expr;
2252 printCmd->m_exprWnd = cmd->m_exprWnd;
2256 #include "debugger.moc"