Replace KMD5 by QCryptographicHash.
[kdbg.git] / kdbg / debugger.cpp
bloba678afa3e52c6e883826d9ca35f00c092f33b671
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 <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"
27 /**
28 * Returns expression value for a tooltip.
30 template <class T>
31 QString formatPopupValue(const T* v)
33 QString tip;
35 if (!v->value().isEmpty())
37 tip += v->value();
39 else
41 // no value: we use some hint
42 switch (v->m_varKind) {
43 case VarTree::VKstruct:
44 tip += "{...}";
45 break;
46 case VarTree::VKarray:
47 tip += "[...]";
48 break;
49 default:
50 tip += "?""?""?"; // 2 question marks in a row would be a trigraph
51 break;
55 return tip;
58 KDebugger::KDebugger(QWidget* parent,
59 ExprWnd* localVars,
60 ExprWnd* watchVars,
61 QListWidget* backtrace) :
62 QObject(parent),
63 m_ttyLevel(ttyFull),
64 m_memoryFormat(MDTword | MDThex),
65 m_haveExecutable(false),
66 m_programActive(false),
67 m_programRunning(false),
68 m_sharedLibsListed(false),
69 m_typeTable(0),
70 m_programConfig(0),
71 m_d(0),
72 m_localVariables(*localVars),
73 m_watchVariables(*watchVars),
74 m_btWindow(*backtrace)
76 connect(&m_localVariables, SIGNAL(itemExpanded(QTreeWidgetItem*)),
77 SLOT(slotExpanding(QTreeWidgetItem*)));
78 connect(&m_watchVariables, SIGNAL(itemExpanded(QTreeWidgetItem*)),
79 SLOT(slotExpanding(QTreeWidgetItem*)));
80 connect(&m_localVariables, SIGNAL(editValueCommitted(VarTree*, const QString&)),
81 SLOT(slotValueEdited(VarTree*, const QString&)));
82 connect(&m_watchVariables, SIGNAL(editValueCommitted(VarTree*, const QString&)),
83 SLOT(slotValueEdited(VarTree*, const QString&)));
85 connect(&m_btWindow, SIGNAL(currentRowChanged(int)), this, SLOT(gotoFrame(int)));
87 emit updateUI();
90 KDebugger::~KDebugger()
92 if (m_programConfig != 0) {
93 saveProgramSettings();
94 m_programConfig->sync();
95 delete m_programConfig;
98 delete m_typeTable;
102 void KDebugger::saveSettings(KConfig* /*config*/)
106 void KDebugger::restoreSettings(KConfig* /*config*/)
111 //////////////////////////////////////////////////////////////////////
112 // external interface
114 const char GeneralGroup[] = "General";
115 const char DebuggerCmdStr[] = "DebuggerCmdStr";
116 const char TTYLevelEntry[] = "TTYLevel";
117 const char KDebugger::DriverNameEntry[] = "DriverName";
119 bool KDebugger::debugProgram(const QString& name,
120 DebuggerDriver* driver)
122 if (m_d != 0 && m_d->isRunning())
124 QApplication::setOverrideCursor(Qt::WaitCursor);
126 stopDriver();
128 QApplication::restoreOverrideCursor();
130 if (m_d->isRunning() || m_haveExecutable) {
131 /* timed out! We can't really do anything useful now */
132 TRACE("timed out while waiting for gdb to die!");
133 return false;
135 delete m_d;
136 m_d = 0;
139 // wire up the driver
140 connect(driver, SIGNAL(activateFileLine(const QString&,int,const DbgAddr&)),
141 this, SIGNAL(activateFileLine(const QString&,int,const DbgAddr&)));
142 connect(driver, SIGNAL(finished(int, QProcess::ExitStatus)),
143 SLOT(gdbExited()));
144 connect(driver, SIGNAL(commandReceived(CmdQueueItem*,const char*)),
145 SLOT(parse(CmdQueueItem*,const char*)));
146 connect(driver, SIGNAL(bytesWritten(qint64)), SIGNAL(updateUI()));
147 connect(driver, SIGNAL(inferiorRunning()), SLOT(slotInferiorRunning()));
148 connect(driver, SIGNAL(enterIdleState()), SLOT(backgroundUpdate()));
149 connect(driver, SIGNAL(enterIdleState()), SIGNAL(updateUI()));
150 connect(&m_localVariables, SIGNAL(removingItem(VarTree*)),
151 driver, SLOT(dequeueCmdByVar(VarTree*)));
152 connect(&m_watchVariables, SIGNAL(removingItem(VarTree*)),
153 driver, SLOT(dequeueCmdByVar(VarTree*)));
155 // create the program settings object
156 openProgramConfig(name);
158 // get debugger command from per-program settings
159 if (m_programConfig != 0) {
160 KConfigGroup g = m_programConfig->group(GeneralGroup);
161 m_debuggerCmd = readDebuggerCmd(g);
162 // get terminal emulation level
163 m_ttyLevel = TTYLevel(g.readEntry(TTYLevelEntry, int(ttyFull)));
165 // the rest is read in later in the handler of DCexecutable
167 m_d = driver;
169 if (!startDriver()) {
170 TRACE("startDriver failed");
171 m_d = 0;
172 return false;
175 TRACE("before file cmd");
176 m_d->executeCmd(DCexecutable, name);
177 m_executable = name;
179 // set remote target
180 if (!m_remoteDevice.isEmpty()) {
181 m_d->executeCmd(DCtargetremote, m_remoteDevice);
182 m_d->queueCmd(DCbt, DebuggerDriver::QMoverride);
183 m_d->queueCmd(DCinfothreads, DebuggerDriver::QMoverride);
184 m_d->queueCmd(DCframe, 0, DebuggerDriver::QMnormal);
185 m_programActive = true;
186 m_haveExecutable = true;
189 // create a type table
190 m_typeTable = new ProgramTypeTable;
191 m_sharedLibsListed = false;
193 emit updateUI();
195 return true;
198 void KDebugger::shutdown()
200 // shut down debugger driver
201 if (m_d != 0 && m_d->isRunning())
203 stopDriver();
207 void KDebugger::useCoreFile(QString corefile, bool batch)
209 m_corefile = corefile;
210 if (!batch) {
211 CmdQueueItem* cmd = loadCoreFile();
212 cmd->m_byUser = true;
216 void KDebugger::setAttachPid(const QString& pid)
218 m_attachedPid = pid;
221 void KDebugger::programRun()
223 if (!isReady())
224 return;
226 // when program is active, but not a core file, continue
227 // otherwise run the program
228 if (m_programActive && m_corefile.isEmpty()) {
229 // gdb command: continue
230 m_d->executeCmd(DCcont, true);
231 } else {
232 // gdb command: run
233 m_d->executeCmd(DCrun, true);
234 m_corefile = QString();
235 m_programActive = true;
237 m_programRunning = true;
240 void KDebugger::attachProgram(const QString& pid)
242 if (!isReady())
243 return;
245 m_attachedPid = pid;
246 TRACE("Attaching to " + m_attachedPid);
247 m_d->executeCmd(DCattach, m_attachedPid);
248 m_programActive = true;
249 m_programRunning = true;
252 void KDebugger::programRunAgain()
254 if (canSingleStep()) {
255 m_d->executeCmd(DCrun, true);
256 m_corefile = QString();
257 m_programRunning = true;
261 void KDebugger::programStep()
263 if (canSingleStep()) {
264 m_d->executeCmd(DCstep, true);
265 m_programRunning = true;
269 void KDebugger::programNext()
271 if (canSingleStep()) {
272 m_d->executeCmd(DCnext, true);
273 m_programRunning = true;
277 void KDebugger::programStepi()
279 if (canSingleStep()) {
280 m_d->executeCmd(DCstepi, true);
281 m_programRunning = true;
285 void KDebugger::programNexti()
287 if (canSingleStep()) {
288 m_d->executeCmd(DCnexti, true);
289 m_programRunning = true;
293 void KDebugger::programFinish()
295 if (canSingleStep()) {
296 m_d->executeCmd(DCfinish, true);
297 m_programRunning = true;
301 void KDebugger::programKill()
303 if (haveExecutable() && isProgramActive()) {
304 if (m_programRunning) {
305 m_d->interruptInferior();
307 // this is an emergency command; flush queues
308 m_d->flushCommands(true);
309 m_d->executeCmd(DCkill, true);
313 void KDebugger::programDetach()
315 if (haveExecutable() && isProgramActive()) {
316 if (m_programRunning) {
317 m_d->interruptInferior();
319 // this is an emergency command; flush queues
320 m_d->flushCommands(true);
321 m_d->executeCmd(DCdetach, true);
325 bool KDebugger::runUntil(const QString& fileName, int lineNo)
327 if (isReady() && m_programActive && !m_programRunning) {
328 // strip off directory part of file name
329 QFileInfo fi(fileName);
330 m_d->executeCmd(DCuntil, fi.fileName(), lineNo, true);
331 m_programRunning = true;
332 return true;
333 } else {
334 return false;
338 void KDebugger::programBreak()
340 if (m_haveExecutable && m_programRunning) {
341 m_d->interruptInferior();
345 void KDebugger::programArgs(QWidget* parent)
347 if (m_haveExecutable) {
348 QStringList allOptions = m_d->boolOptionList();
349 PgmArgs dlg(parent, m_executable, m_envVars, allOptions);
350 dlg.setArgs(m_programArgs);
351 dlg.setWd(m_programWD);
352 dlg.setOptions(m_boolOptions);
353 if (dlg.exec()) {
354 updateProgEnvironment(dlg.args(), dlg.wd(),
355 dlg.envVars(), dlg.options());
360 void KDebugger::programSettings(QWidget* parent)
362 if (!m_haveExecutable)
363 return;
365 ProgramSettings dlg(parent, m_executable);
367 dlg.m_chooseDriver.setDebuggerCmd(m_debuggerCmd);
368 dlg.m_output.setTTYLevel(m_ttyLevel);
370 if (dlg.exec() == QDialog::Accepted)
372 m_debuggerCmd = dlg.m_chooseDriver.debuggerCmd();
373 m_ttyLevel = TTYLevel(dlg.m_output.ttyLevel());
377 bool KDebugger::setBreakpoint(QString file, int lineNo,
378 const DbgAddr& address, bool temporary)
380 if (!isReady()) {
381 return false;
384 BrkptIterator bp = breakpointByFilePos(file, lineNo, address);
385 if (bp == m_brkpts.end())
388 * No such breakpoint, so set a new one. If we have an address, we
389 * set the breakpoint exactly there. Otherwise we use the file name
390 * plus line no.
392 Breakpoint* bp = new Breakpoint;
393 bp->temporary = temporary;
395 if (address.isEmpty())
397 bp->fileName = file;
398 bp->lineNo = lineNo;
400 else
402 bp->address = address;
404 setBreakpoint(bp, false);
406 else
409 * If the breakpoint is disabled, enable it; if it's enabled,
410 * delete that breakpoint.
412 if (bp->enabled) {
413 deleteBreakpoint(bp);
414 } else {
415 enableDisableBreakpoint(bp);
418 return true;
421 void KDebugger::setBreakpoint(Breakpoint* bp, bool queueOnly)
423 CmdQueueItem* cmd = executeBreakpoint(bp, queueOnly);
424 cmd->m_brkpt = bp; // used in newBreakpoint()
427 CmdQueueItem* KDebugger::executeBreakpoint(const Breakpoint* bp, bool queueOnly)
429 CmdQueueItem* cmd;
430 if (!bp->text.isEmpty())
433 * The breakpoint was set using the text box in the breakpoint
434 * list. This is the only way in which watchpoints are set.
436 if (bp->type == Breakpoint::watchpoint) {
437 cmd = m_d->executeCmd(DCwatchpoint, bp->text);
438 } else {
439 cmd = m_d->executeCmd(DCbreaktext, bp->text);
442 else if (bp->address.isEmpty())
444 // strip off directory part of file name
445 QString file = QFileInfo(bp->fileName).fileName();
446 if (queueOnly) {
447 cmd = m_d->queueCmd(bp->temporary ? DCtbreakline : DCbreakline,
448 file, bp->lineNo, DebuggerDriver::QMoverride);
449 } else {
450 cmd = m_d->executeCmd(bp->temporary ? DCtbreakline : DCbreakline,
451 file, bp->lineNo);
454 else
456 if (queueOnly) {
457 cmd = m_d->queueCmd(bp->temporary ? DCtbreakaddr : DCbreakaddr,
458 bp->address.asString(), DebuggerDriver::QMoverride);
459 } else {
460 cmd = m_d->executeCmd(bp->temporary ? DCtbreakaddr : DCbreakaddr,
461 bp->address.asString());
464 return cmd;
467 bool KDebugger::infoLine(QString file, int lineNo, const DbgAddr& addr)
469 if (isReady() && !m_programRunning) {
470 CmdQueueItem* cmd = m_d->executeCmd(DCinfoline, file, lineNo);
471 cmd->m_addr = addr;
472 return true;
473 } else {
474 return false;
478 bool KDebugger::enableDisableBreakpoint(QString file, int lineNo,
479 const DbgAddr& address)
481 BrkptIterator bp = breakpointByFilePos(file, lineNo, address);
482 return enableDisableBreakpoint(bp);
485 bool KDebugger::enableDisableBreakpoint(BrkptIterator bp)
487 if (bp == m_brkpts.end())
488 return false;
491 * Toggle enabled/disabled state.
493 * The driver is not bothered if we are modifying an orphaned
494 * breakpoint.
496 if (!bp->isOrphaned()) {
497 if (!canChangeBreakpoints()) {
498 return false;
500 m_d->executeCmd(bp->enabled ? DCdisable : DCenable, bp->id);
501 } else {
502 bp->enabled = !bp->enabled;
503 emit breakpointsChanged();
505 return true;
508 bool KDebugger::conditionalBreakpoint(BrkptIterator bp,
509 const QString& condition,
510 int ignoreCount)
512 if (bp == m_brkpts.end())
513 return false;
516 * Change the condition and ignore count.
518 * The driver is not bothered if we are removing an orphaned
519 * breakpoint.
522 if (!bp->isOrphaned()) {
523 if (!canChangeBreakpoints()) {
524 return false;
527 bool changed = false;
529 if (bp->condition != condition) {
530 // change condition
531 m_d->executeCmd(DCcondition, condition, bp->id);
532 changed = true;
534 if (bp->ignoreCount != ignoreCount) {
535 // change ignore count
536 m_d->executeCmd(DCignore, bp->id, ignoreCount);
537 changed = true;
539 if (changed) {
540 // get the changes
541 m_d->queueCmd(DCinfobreak, DebuggerDriver::QMoverride);
543 } else {
544 bp->condition = condition;
545 bp->ignoreCount = ignoreCount;
546 emit breakpointsChanged();
548 return true;
551 bool KDebugger::deleteBreakpoint(BrkptIterator bp)
553 if (bp == m_brkpts.end())
554 return false;
557 * Remove the breakpoint.
559 * The driver is not bothered if we are removing an orphaned
560 * breakpoint.
562 if (!bp->isOrphaned()) {
563 if (!canChangeBreakpoints()) {
564 return false;
566 m_d->executeCmd(DCdelete, bp->id);
567 } else {
568 m_brkpts.erase(bp);
569 emit breakpointsChanged();
571 return false;
574 bool KDebugger::canSingleStep()
576 return isReady() && m_programActive && !m_programRunning;
579 bool KDebugger::canChangeBreakpoints()
581 return isReady() && !m_programRunning;
584 bool KDebugger::canStart()
586 return isReady() && !m_programActive;
589 bool KDebugger::isReady() const
591 return m_haveExecutable &&
592 m_d != 0 && m_d->canExecuteImmediately();
595 bool KDebugger::isIdle() const
597 return m_d == 0 || m_d->isIdle();
601 //////////////////////////////////////////////////////////
602 // debugger driver
604 bool KDebugger::startDriver()
606 emit debuggerStarting(); /* must set m_inferiorTerminal */
609 * If the per-program command string is empty, use the global setting
610 * (which might also be empty, in which case the driver uses its
611 * default).
613 m_explicitKill = false;
614 if (!m_d->startup(m_debuggerCmd)) {
615 return false;
619 * If we have an output terminal, we use it. Otherwise we will run the
620 * program with input and output redirected to /dev/null. Other
621 * redirections are also necessary depending on the tty emulation
622 * level.
624 int redirect = RDNstdin|RDNstdout|RDNstderr; /* redirect everything */
625 if (!m_inferiorTerminal.isEmpty()) {
626 switch (m_ttyLevel) {
627 default:
628 case ttyNone:
629 // redirect everything
630 break;
631 case ttySimpleOutputOnly:
632 redirect = RDNstdin;
633 break;
634 case ttyFull:
635 redirect = 0;
636 break;
639 m_d->executeCmd(DCtty, m_inferiorTerminal, redirect);
641 return true;
644 void KDebugger::stopDriver()
646 m_explicitKill = true;
648 if (m_attachedPid.isEmpty()) {
649 m_d->terminate();
650 } else {
651 m_d->detachAndTerminate();
655 * We MUST wait until the slot gdbExited() has been called. But to
656 * avoid a deadlock, we wait only for some certain maximum time. Should
657 * this timeout be reached, the only reasonable thing one could do then
658 * is exiting kdbg.
660 QApplication::processEvents(QEventLoop::AllEvents, 1000);
661 int maxTime = 20; /* about 20 seconds */
662 while (m_haveExecutable && maxTime > 0) {
663 // give gdb time to die (and send a SIGCLD)
664 ::sleep(1);
665 --maxTime;
666 QApplication::processEvents(QEventLoop::AllEvents, 1000);
670 void KDebugger::gdbExited()
673 * Save settings, but only if gdb has already processed "info line
674 * main", otherwise we would save an empty config file, because it
675 * isn't read in until then!
677 if (m_programConfig != 0) {
678 if (m_haveExecutable) {
679 saveProgramSettings();
680 m_programConfig->sync();
682 delete m_programConfig;
683 m_programConfig = 0;
686 // erase types
687 delete m_typeTable;
688 m_typeTable = 0;
690 if (m_explicitKill) {
691 TRACE(m_d->driverName() + " exited normally");
692 } else {
693 QString msg = i18n("%1 exited unexpectedly.\n"
694 "Restart the session (e.g. with File|Executable).");
695 KMessageBox::error(parentWidget(), msg.arg(m_d->driverName()));
698 // reset state
699 m_haveExecutable = false;
700 m_executable = "";
701 m_programActive = false;
702 m_programRunning = false;
703 m_explicitKill = false;
704 m_debuggerCmd = QString(); /* use global setting at next start! */
705 m_attachedPid = QString(); /* we are no longer attached to a process */
706 m_ttyLevel = ttyFull;
707 m_brkpts.clear();
709 // erase PC
710 emit updatePC(QString(), -1, DbgAddr(), 0);
713 QString KDebugger::getConfigForExe(const QString& name)
715 QFileInfo fi(name);
716 QString dir = fi.absolutePath();
718 // The session file for the given executable consists of
719 // a hash of the directory, followed by the program name.
720 // Assume that the first 15 positions of the hash are unique;
721 // this keeps the file names short.
722 QCryptographicHash dirDigest(QCryptographicHash::Md5);
723 dirDigest.addData(dir.toUtf8());
724 QString hash = dirDigest.result().toBase64();
725 hash.replace('/', QString()); // avoid directory separators
726 QString pgmConfigFile = hash.left(15) + "-" + fi.fileName();
727 pgmConfigFile = KStandardDirs::locateLocal("sessions", pgmConfigFile);
728 TRACE("program config file = " + pgmConfigFile);
729 return pgmConfigFile;
732 void KDebugger::openProgramConfig(const QString& name)
734 ASSERT(m_programConfig == 0);
736 QString pgmConfigFile = getConfigForExe(name);
738 m_programConfig = new KConfig(pgmConfigFile);
740 // this leaves a clue behind in the config file which
741 // executable it applies to; it is mostly intended for
742 // users peeking into the file
743 KConfigGroup g = m_programConfig->group(GeneralGroup);
744 g.writeEntry("ExecutableFile", name);
747 const char EnvironmentGroup[] = "Environment";
748 const char WatchGroup[] = "Watches";
749 const char FileVersion[] = "FileVersion";
750 const char ProgramArgs[] = "ProgramArgs";
751 const char WorkingDirectory[] = "WorkingDirectory";
752 const char OptionsSelected[] = "OptionsSelected";
753 const char Variable[] = "Var%d";
754 const char Value[] = "Value%d";
755 const char ExprFmt[] = "Expr%d";
757 void KDebugger::saveProgramSettings()
759 ASSERT(m_programConfig != 0);
760 KConfigGroup gg = m_programConfig->group(GeneralGroup);
761 gg.writeEntry(FileVersion, 1);
762 gg.writeEntry(ProgramArgs, m_programArgs);
763 gg.writeEntry(WorkingDirectory, m_programWD);
764 gg.writeEntry(OptionsSelected, m_boolOptions.toList());
765 gg.writeEntry(DebuggerCmdStr, m_debuggerCmd);
766 gg.writeEntry(TTYLevelEntry, int(m_ttyLevel));
767 QString driverName;
768 if (m_d != 0)
769 driverName = m_d->driverName();
770 gg.writeEntry(DriverNameEntry, driverName);
772 // write environment variables
773 m_programConfig->deleteGroup(EnvironmentGroup);
774 KConfigGroup eg = m_programConfig->group(EnvironmentGroup);
775 QString varName;
776 QString varValue;
777 int i = 0;
778 for (std::map<QString,QString>::iterator it = m_envVars.begin(); it != m_envVars.end(); ++it, ++i)
780 varName.sprintf(Variable, i);
781 varValue.sprintf(Value, i);
782 eg.writeEntry(varName, it->first);
783 eg.writeEntry(varValue, it->second);
786 saveBreakpoints(m_programConfig);
788 // watch expressions
789 // first get rid of whatever was in this group
790 m_programConfig->deleteGroup(WatchGroup);
791 // then start a new group
792 KConfigGroup wg = m_programConfig->group(WatchGroup);
793 int watchNum = 0;
794 foreach (QString expr, m_watchVariables.exprList()) {
795 varName.sprintf(ExprFmt, watchNum++);
796 wg.writeEntry(varName, expr);
799 // give others a chance
800 emit saveProgramSpecific(m_programConfig);
803 void KDebugger::overrideProgramArguments(const QString& args)
805 ASSERT(m_programConfig != 0);
806 KConfigGroup g = m_programConfig->group(GeneralGroup);
807 g.writeEntry(ProgramArgs, args);
810 void KDebugger::restoreProgramSettings()
812 ASSERT(m_programConfig != 0);
813 KConfigGroup gg = m_programConfig->group(GeneralGroup);
815 * We ignore file version for now we will use it in the future to
816 * distinguish different versions of this configuration file.
818 // m_debuggerCmd has been read in already
819 // m_ttyLevel has been read in already
820 QString pgmArgs = gg.readEntry(ProgramArgs);
821 QString pgmWd = gg.readEntry(WorkingDirectory);
822 QSet<QString> boolOptions = QSet<QString>::fromList(gg.readEntry(OptionsSelected, QStringList()));
823 m_boolOptions.clear();
825 // read environment variables
826 KConfigGroup eg = m_programConfig->group(EnvironmentGroup);
827 m_envVars.clear();
828 std::map<QString,EnvVar> pgmVars;
829 QString varName;
830 QString varValue;
831 for (int i = 0;; ++i) {
832 varName.sprintf(Variable, i);
833 varValue.sprintf(Value, i);
834 if (!eg.hasKey(varName)) {
835 /* entry not present, assume that we've hit them all */
836 break;
838 QString name = eg.readEntry(varName, QString());
839 if (name.isEmpty()) {
840 // skip empty names
841 continue;
843 EnvVar* var = &pgmVars[name];
844 var->value = eg.readEntry(varValue, QString());
845 var->status = EnvVar::EVnew;
848 updateProgEnvironment(pgmArgs, pgmWd, pgmVars, boolOptions);
850 restoreBreakpoints(m_programConfig);
852 // watch expressions
853 KConfigGroup wg = m_programConfig->group(WatchGroup);
854 m_watchVariables.clear();
855 for (int i = 0;; ++i) {
856 varName.sprintf(ExprFmt, i);
857 if (!wg.hasKey(varName)) {
858 /* entry not present, assume that we've hit them all */
859 break;
861 QString expr = wg.readEntry(varName, QString());
862 if (expr.isEmpty()) {
863 // skip empty expressions
864 continue;
866 addWatch(expr);
869 // give others a chance
870 emit restoreProgramSpecific(m_programConfig);
874 * Reads the debugger command line from the program settings. The config
875 * group must have been set by the caller.
877 QString KDebugger::readDebuggerCmd(const KConfigGroup& g)
879 QString debuggerCmd = g.readEntry(DebuggerCmdStr);
881 // always let the user confirm the debugger cmd if we are root
882 if (::geteuid() == 0)
884 if (!debuggerCmd.isEmpty()) {
885 QString msg = i18n(
886 "The settings for this program specify "
887 "the following debugger command:\n%1\n"
888 "Shall this command be used?");
889 if (KMessageBox::warningYesNo(parentWidget(), msg.arg(debuggerCmd))
890 != KMessageBox::Yes)
892 // don't use it
893 debuggerCmd = QString();
897 return debuggerCmd;
901 * Breakpoints are saved one per group.
903 const char BPGroup[] = "Breakpoint %d";
904 const char File[] = "File";
905 const char Line[] = "Line";
906 const char Text[] = "Text";
907 const char Address[] = "Address";
908 const char Temporary[] = "Temporary";
909 const char Enabled[] = "Enabled";
910 const char Condition[] = "Condition";
912 void KDebugger::saveBreakpoints(KConfig* config)
914 QString groupName;
915 int i = 0;
916 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
918 if (bp->type == Breakpoint::watchpoint)
919 continue; /* don't save watchpoints */
920 groupName.sprintf(BPGroup, i++);
922 /* remove remmants */
923 config->deleteGroup(groupName);
925 KConfigGroup g = config->group(groupName);
926 if (!bp->text.isEmpty()) {
928 * The breakpoint was set using the text box in the breakpoint
929 * list. We do not save the location by filename+line number,
930 * but instead honor what the user typed (a function name, for
931 * example, which could move between sessions).
933 g.writeEntry(Text, bp->text);
934 } else if (!bp->fileName.isEmpty()) {
935 g.writeEntry(File, bp->fileName);
936 g.writeEntry(Line, bp->lineNo);
938 * Addresses are hardly correct across sessions, so we don't
939 * save it.
941 } else {
942 g.writeEntry(Address, bp->address.asString());
944 g.writeEntry(Temporary, bp->temporary);
945 g.writeEntry(Enabled, bp->enabled);
946 if (!bp->condition.isEmpty())
947 g.writeEntry(Condition, bp->condition);
948 // we do not save the ignore count
950 // delete remaining groups
951 // we recognize that a group is present if there is an Enabled entry
952 for (;; i++) {
953 groupName.sprintf(BPGroup, i);
954 if (!config->group(groupName).hasKey(Enabled)) {
955 /* group not present, assume that we've hit them all */
956 break;
958 config->deleteGroup(groupName);
962 void KDebugger::restoreBreakpoints(KConfig* config)
964 QString groupName;
966 * We recognize the end of the list if there is no Enabled entry
967 * present.
969 for (int i = 0;; i++) {
970 groupName.sprintf(BPGroup, i);
971 KConfigGroup g = config->group(groupName);
972 if (!g.hasKey(Enabled)) {
973 /* group not present, assume that we've hit them all */
974 break;
976 Breakpoint* bp = new Breakpoint;
977 bp->fileName = g.readEntry(File);
978 bp->lineNo = g.readEntry(Line, -1);
979 bp->text = g.readEntry(Text);
980 bp->address = g.readEntry(Address);
981 // check consistency
982 if ((bp->fileName.isEmpty() || bp->lineNo < 0) &&
983 bp->text.isEmpty() &&
984 bp->address.isEmpty())
986 delete bp;
987 continue;
989 bp->enabled = g.readEntry(Enabled, true);
990 bp->temporary = g.readEntry(Temporary, false);
991 bp->condition = g.readEntry(Condition);
994 * Add the breakpoint.
996 setBreakpoint(bp, false);
997 // the new breakpoint is disabled or conditionalized later
998 // in newBreakpoint()
1000 m_d->queueCmd(DCinfobreak, DebuggerDriver::QMoverride);
1004 // parse output of command cmd
1005 void KDebugger::parse(CmdQueueItem* cmd, const char* output)
1007 ASSERT(cmd != 0); /* queue mustn't be empty */
1009 TRACE(QString(__PRETTY_FUNCTION__) + " parsing " + output);
1011 switch (cmd->m_cmd) {
1012 case DCtargetremote:
1013 // the output (if any) is uninteresting
1014 case DCsetargs:
1015 case DCtty:
1016 // there is no output
1017 case DCsetenv:
1018 case DCunsetenv:
1019 case DCsetoption:
1020 /* if value is empty, we see output, but we don't care */
1021 break;
1022 case DCcd:
1023 /* display gdb's message in the status bar */
1024 m_d->parseChangeWD(output, m_statusMessage);
1025 emit updateStatusMessage();
1026 break;
1027 case DCinitialize:
1028 break;
1029 case DCexecutable:
1030 if (m_d->parseChangeExecutable(output, m_statusMessage))
1032 // success; restore breakpoints etc.
1033 if (m_programConfig != 0) {
1034 restoreProgramSettings();
1036 // load file containing main() or core file
1037 if (!m_corefile.isEmpty())
1039 // load core file
1040 loadCoreFile();
1042 else if (!m_attachedPid.isEmpty())
1044 m_d->queueCmd(DCattach, m_attachedPid, DebuggerDriver::QMoverride);
1045 m_programActive = true;
1046 m_programRunning = true;
1048 else if (!m_remoteDevice.isEmpty())
1050 // handled elsewhere
1052 else
1054 m_d->queueCmd(DCinfolinemain, DebuggerDriver::QMnormal);
1056 if (!m_statusMessage.isEmpty())
1057 emit updateStatusMessage();
1058 } else {
1059 QString msg = m_d->driverName() + ": " + m_statusMessage;
1060 KMessageBox::sorry(parentWidget(), msg);
1061 m_executable = "";
1062 m_corefile = ""; /* don't process core file */
1063 m_haveExecutable = false;
1065 break;
1066 case DCcorefile:
1067 // in any event we have an executable at this point
1068 m_haveExecutable = true;
1069 if (m_d->parseCoreFile(output)) {
1070 // loading a core is like stopping at a breakpoint
1071 m_programActive = true;
1072 handleRunCommands(output);
1073 // do not reset m_corefile
1074 } else {
1075 // report error
1076 QString msg = m_d->driverName() + ": " + QString(output);
1077 KMessageBox::sorry(parentWidget(), msg);
1079 // if core file was loaded from command line, revert to info line main
1080 if (!cmd->m_byUser) {
1081 m_d->queueCmd(DCinfolinemain, DebuggerDriver::QMnormal);
1083 m_corefile = QString(); /* core file not available any more */
1085 break;
1086 case DCinfolinemain:
1087 // ignore the output, marked file info follows
1088 m_haveExecutable = true;
1089 break;
1090 case DCinfolocals:
1091 // parse local variables
1092 if (output[0] != '\0') {
1093 handleLocals(output);
1095 break;
1096 case DCinforegisters:
1097 handleRegisters(output);
1098 break;
1099 case DCexamine:
1100 handleMemoryDump(output);
1101 break;
1102 case DCinfoline:
1103 handleInfoLine(cmd, output);
1104 break;
1105 case DCdisassemble:
1106 handleDisassemble(cmd, output);
1107 break;
1108 case DCframe:
1109 handleFrameChange(output);
1110 updateAllExprs();
1111 break;
1112 case DCbt:
1113 handleBacktrace(output);
1114 updateAllExprs();
1115 break;
1116 case DCprint:
1117 handlePrint(cmd, output);
1118 break;
1119 case DCprintPopup:
1120 handlePrintPopup(cmd, output);
1121 break;
1122 case DCprintDeref:
1123 handlePrintDeref(cmd, output);
1124 break;
1125 case DCattach:
1126 m_haveExecutable = true;
1127 // fall through
1128 case DCrun:
1129 case DCcont:
1130 case DCstep:
1131 case DCstepi:
1132 case DCnext:
1133 case DCnexti:
1134 case DCfinish:
1135 case DCuntil:
1136 case DCthread:
1137 handleRunCommands(output);
1138 break;
1139 case DCkill:
1140 case DCdetach:
1141 m_programRunning = m_programActive = false;
1142 // erase PC
1143 emit updatePC(QString(), -1, DbgAddr(), 0);
1144 break;
1145 case DCbreaktext:
1146 case DCbreakline:
1147 case DCtbreakline:
1148 case DCbreakaddr:
1149 case DCtbreakaddr:
1150 case DCwatchpoint:
1151 newBreakpoint(cmd, output);
1152 // fall through
1153 case DCdelete:
1154 case DCenable:
1155 case DCdisable:
1156 // these commands need immediate response
1157 m_d->queueCmd(DCinfobreak, DebuggerDriver::QMoverrideMoreEqual);
1158 break;
1159 case DCinfobreak:
1160 // note: this handler must not enqueue a command, since
1161 // DCinfobreak is used at various different places.
1162 updateBreakList(output);
1163 break;
1164 case DCfindType:
1165 handleFindType(cmd, output);
1166 break;
1167 case DCprintStruct:
1168 case DCprintQStringStruct:
1169 case DCprintWChar:
1170 handlePrintStruct(cmd, output);
1171 break;
1172 case DCinfosharedlib:
1173 handleSharedLibs(output);
1174 break;
1175 case DCcondition:
1176 case DCignore:
1177 // we are not interested in the output
1178 break;
1179 case DCinfothreads:
1180 handleThreadList(output);
1181 break;
1182 case DCsetpc:
1183 handleSetPC(output);
1184 break;
1185 case DCsetvariable:
1186 handleSetVariable(cmd, output);
1187 break;
1191 void KDebugger::backgroundUpdate()
1194 * If there are still expressions that need to be updated, then do so.
1196 if (m_programActive)
1197 evalExpressions();
1200 void KDebugger::handleRunCommands(const char* output)
1202 uint flags = m_d->parseProgramStopped(output, m_statusMessage);
1203 emit updateStatusMessage();
1205 m_programActive = flags & DebuggerDriver::SFprogramActive;
1207 // refresh files if necessary
1208 if (flags & DebuggerDriver::SFrefreshSource) {
1209 TRACE("re-reading files");
1210 emit executableUpdated();
1214 * Try to set any orphaned breakpoints now.
1216 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
1218 if (bp->isOrphaned()) {
1219 TRACE(QString("re-trying brkpt loc: %2 file: %3 line: %1")
1220 .arg(bp->lineNo).arg(bp->location, bp->fileName));
1221 CmdQueueItem* cmd = executeBreakpoint(&*bp, true);
1222 cmd->m_existingBrkpt = bp->id; // used in newBreakpoint()
1223 flags |= DebuggerDriver::SFrefreshBreak;
1228 * If we stopped at a breakpoint, we must update the breakpoint list
1229 * because the hit count changes. Also, if the breakpoint was temporary
1230 * it would go away now.
1232 if ((flags & (DebuggerDriver::SFrefreshBreak|DebuggerDriver::SFrefreshSource)) ||
1233 stopMayChangeBreakList())
1235 m_d->queueCmd(DCinfobreak, DebuggerDriver::QMoverride);
1239 * If we haven't listed the shared libraries yet, do so. We must do
1240 * this before we emit any commands that list variables, since the type
1241 * libraries depend on the shared libraries.
1243 if (!m_sharedLibsListed) {
1244 // must be a high-priority command!
1245 m_d->executeCmd(DCinfosharedlib);
1248 // get the backtrace if the program is running
1249 if (m_programActive) {
1250 m_d->queueCmd(DCbt, DebuggerDriver::QMoverride);
1251 } else {
1252 // program finished: erase PC
1253 emit updatePC(QString(), -1, DbgAddr(), 0);
1254 // dequeue any commands in the queues
1255 m_d->flushCommands();
1258 /* Update threads list */
1259 if (m_programActive && (flags & DebuggerDriver::SFrefreshThreads)) {
1260 m_d->queueCmd(DCinfothreads, DebuggerDriver::QMoverride);
1263 m_programRunning = false;
1264 emit programStopped();
1267 void KDebugger::slotInferiorRunning()
1269 m_programRunning = true;
1272 void KDebugger::updateAllExprs()
1274 if (!m_programActive)
1275 return;
1277 // retrieve local variables
1278 m_d->queueCmd(DCinfolocals, DebuggerDriver::QMoverride);
1280 // retrieve registers
1281 m_d->queueCmd(DCinforegisters, DebuggerDriver::QMoverride);
1283 // get new memory dump
1284 if (!m_memoryExpression.isEmpty()) {
1285 queueMemoryDump(false);
1288 // update watch expressions
1289 foreach (QString expr, m_watchVariables.exprList()) {
1290 m_watchEvalExpr.push_back(expr);
1294 void KDebugger::updateProgEnvironment(const QString& args, const QString& wd,
1295 const std::map<QString,EnvVar>& newVars,
1296 const QSet<QString>& newOptions)
1298 m_programArgs = args;
1299 m_d->executeCmd(DCsetargs, m_programArgs);
1300 TRACE("new pgm args: " + m_programArgs + "\n");
1302 m_programWD = wd.trimmed();
1303 if (!m_programWD.isEmpty()) {
1304 m_d->executeCmd(DCcd, m_programWD);
1305 TRACE("new wd: " + m_programWD + "\n");
1308 // update environment variables
1309 for (std::map<QString,EnvVar>::const_iterator i = newVars.begin(); i != newVars.end(); ++i)
1311 QString var = i->first;
1312 const EnvVar* val = &i->second;
1313 switch (val->status) {
1314 case EnvVar::EVnew:
1315 case EnvVar::EVdirty:
1316 m_envVars[var] = val->value;
1317 // update value
1318 m_d->executeCmd(DCsetenv, var, val->value);
1319 break;
1320 case EnvVar::EVdeleted:
1321 // delete value
1322 m_d->executeCmd(DCunsetenv, var);
1323 m_envVars.erase(var);
1324 break;
1325 default:
1326 ASSERT(false);
1327 case EnvVar::EVclean:
1328 // variable not changed
1329 break;
1333 // update options
1334 foreach (QString opt, newOptions - m_boolOptions)
1336 // option is not set, set it
1337 m_d->executeCmd(DCsetoption, opt, 1);
1339 foreach (QString opt, m_boolOptions - newOptions)
1341 // option is set, unset it
1342 m_d->executeCmd(DCsetoption, opt, 0);
1344 m_boolOptions = newOptions;
1347 void KDebugger::handleLocals(const char* output)
1349 // retrieve old list of local variables
1350 QStringList oldVars = m_localVariables.exprList();
1353 * Get local variables.
1355 std::list<ExprValue*> newVars;
1356 parseLocals(output, newVars);
1359 * Clear any old VarTree item pointers, so that later we don't access
1360 * dangling pointers.
1362 m_localVariables.clearPendingUpdates();
1365 * Match old variables against new ones.
1367 for (QStringList::ConstIterator n = oldVars.begin(); n != oldVars.end(); ++n) {
1368 // lookup this variable in the list of new variables
1369 std::list<ExprValue*>::iterator v = newVars.begin();
1370 while (v != newVars.end() && (*v)->m_name != *n)
1371 ++v;
1372 if (v == newVars.end()) {
1373 // old variable not in the new variables
1374 TRACE("old var deleted: " + *n);
1375 VarTree* v = m_localVariables.topLevelExprByName(*n);
1376 if (v != 0) {
1377 m_localVariables.removeExpr(v);
1379 } else {
1380 // variable in both old and new lists: update
1381 TRACE("update var: " + *n);
1382 m_localVariables.updateExpr(*v, *m_typeTable);
1383 // remove the new variable from the list
1384 delete *v;
1385 newVars.erase(v);
1388 // insert all remaining new variables
1389 while (!newVars.empty())
1391 ExprValue* v = newVars.front();
1392 TRACE("new var: " + v->m_name);
1393 m_localVariables.insertExpr(v, *m_typeTable);
1394 delete v;
1395 newVars.pop_front();
1399 void KDebugger::parseLocals(const char* output, std::list<ExprValue*>& newVars)
1401 std::list<ExprValue*> vars;
1402 m_d->parseLocals(output, vars);
1404 QString origName; /* used in renaming variables */
1405 while (!vars.empty())
1407 ExprValue* variable = vars.front();
1408 vars.pop_front();
1410 * When gdb prints local variables, those from the innermost block
1411 * come first. We run through the list of already parsed variables
1412 * to find duplicates (ie. variables that hide local variables from
1413 * a surrounding block). We keep the name of the inner variable, but
1414 * rename those from the outer block so that, when the value is
1415 * updated in the window, the value of the variable that is
1416 * _visible_ changes the color!
1418 int block = 0;
1419 origName = variable->m_name;
1420 for (std::list<ExprValue*>::iterator v = newVars.begin(); v != newVars.end(); ++v) {
1421 if (variable->m_name == (*v)->m_name) {
1422 // we found a duplicate, change name
1423 block++;
1424 QString newName = origName + " (" + QString().setNum(block) + ")";
1425 variable->m_name = newName;
1428 newVars.push_back(variable);
1432 bool KDebugger::handlePrint(CmdQueueItem* cmd, const char* output)
1434 ASSERT(cmd->m_expr != 0);
1436 ExprValue* variable = m_d->parsePrintExpr(output, true);
1437 if (variable == 0)
1438 return false;
1440 // set expression "name"
1441 variable->m_name = cmd->m_expr->getText();
1444 TRACE("update expr: " + cmd->m_expr->getText());
1445 cmd->m_exprWnd->updateExpr(cmd->m_expr, variable, *m_typeTable);
1446 delete variable;
1449 evalExpressions(); /* enqueue dereferenced pointers */
1451 return true;
1454 bool KDebugger::handlePrintPopup(CmdQueueItem* cmd, const char* output)
1456 ExprValue* value = m_d->parsePrintExpr(output, false);
1457 if (value == 0)
1458 return false;
1460 TRACE("<" + cmd->m_popupExpr + "> = " + value->m_value);
1462 // construct the tip, m_popupExpr contains the variable name
1463 QString tip = cmd->m_popupExpr + " = " + formatPopupValue(value);
1464 emit valuePopup(tip);
1466 return true;
1469 bool KDebugger::handlePrintDeref(CmdQueueItem* cmd, const char* output)
1471 ASSERT(cmd->m_expr != 0);
1473 ExprValue* variable = m_d->parsePrintExpr(output, true);
1474 if (variable == 0)
1475 return false;
1477 // set expression "name"
1478 variable->m_name = cmd->m_expr->getText();
1482 * We must insert a dummy parent, because otherwise variable's value
1483 * would overwrite cmd->m_expr's value.
1485 ExprValue* dummyParent = new ExprValue(variable->m_name, VarTree::NKplain);
1486 dummyParent->m_varKind = VarTree::VKdummy;
1487 // the name of the parsed variable is the address of the pointer
1488 QString addr = "*" + cmd->m_expr->value();
1489 variable->m_name = addr;
1490 variable->m_nameKind = VarTree::NKaddress;
1492 dummyParent->m_child = variable;
1493 // expand the first level for convenience
1494 variable->m_initiallyExpanded = true;
1495 TRACE("update ptr: " + cmd->m_expr->getText());
1496 cmd->m_exprWnd->updateExpr(cmd->m_expr, dummyParent, *m_typeTable);
1497 delete dummyParent;
1500 evalExpressions(); /* enqueue dereferenced pointers */
1502 return true;
1505 // parse the output of bt
1506 void KDebugger::handleBacktrace(const char* output)
1508 m_btWindow.clear();
1510 std::list<StackFrame> stack;
1511 m_d->parseBackTrace(output, stack);
1513 if (!stack.empty()) {
1514 std::list<StackFrame>::iterator frm = stack.begin();
1515 // first frame must set PC
1516 // note: frm->lineNo is zero-based
1517 emit updatePC(frm->fileName, frm->lineNo, frm->address, frm->frameNo);
1519 for (; frm != stack.end(); ++frm) {
1520 QString func;
1521 if (frm->var != 0)
1522 func = frm->var->m_name;
1523 else
1524 func = frm->fileName + ":" + QString().setNum(frm->lineNo+1);
1526 m_btWindow.addItem(func);
1527 TRACE("frame " + func + " (" + frm->fileName + ":" +
1528 QString().setNum(frm->lineNo+1) + ")");
1534 void KDebugger::gotoFrame(int frame)
1536 // frame is negative when the backtrace list is cleared
1537 // ignore this event
1538 if (frame < 0)
1539 return;
1540 m_d->executeCmd(DCframe, frame);
1543 void KDebugger::handleFrameChange(const char* output)
1545 QString fileName;
1546 int frameNo;
1547 int lineNo;
1548 DbgAddr address;
1549 if (m_d->parseFrameChange(output, frameNo, fileName, lineNo, address)) {
1550 /* lineNo can be negative here if we can't find a file name */
1551 emit updatePC(fileName, lineNo, address, frameNo);
1552 } else {
1553 emit updatePC(fileName, -1, address, frameNo);
1557 void KDebugger::evalExpressions()
1559 // evaluate expressions in the following order:
1560 // watch expressions
1561 // pointers in local variables
1562 // pointers in watch expressions
1563 // types in local variables
1564 // types in watch expressions
1565 // struct members in local variables
1566 // struct members in watch expressions
1567 VarTree* exprItem = 0;
1568 if (!m_watchEvalExpr.empty())
1570 QString expr = m_watchEvalExpr.front();
1571 m_watchEvalExpr.pop_front();
1572 exprItem = m_watchVariables.topLevelExprByName(expr);
1574 if (exprItem != 0) {
1575 CmdQueueItem* cmd = m_d->queueCmd(DCprint, exprItem->getText(), DebuggerDriver::QMoverride);
1576 // remember which expr this was
1577 cmd->m_expr = exprItem;
1578 cmd->m_exprWnd = &m_watchVariables;
1579 } else {
1580 ExprWnd* wnd;
1581 #define POINTER(widget) \
1582 wnd = &widget; \
1583 exprItem = widget.nextUpdatePtr(); \
1584 if (exprItem != 0) goto pointer
1585 #define STRUCT(widget) \
1586 wnd = &widget; \
1587 exprItem = widget.nextUpdateStruct(); \
1588 if (exprItem != 0) goto ustruct
1589 #define TYPE(widget) \
1590 wnd = &widget; \
1591 exprItem = widget.nextUpdateType(); \
1592 if (exprItem != 0) goto type
1593 repeat:
1594 POINTER(m_localVariables);
1595 POINTER(m_watchVariables);
1596 STRUCT(m_localVariables);
1597 STRUCT(m_watchVariables);
1598 TYPE(m_localVariables);
1599 TYPE(m_watchVariables);
1600 #undef POINTER
1601 #undef STRUCT
1602 #undef TYPE
1603 return;
1605 pointer:
1606 // we have an expression to send
1607 dereferencePointer(wnd, exprItem, false);
1608 return;
1610 ustruct:
1611 // paranoia
1612 if (exprItem->m_type == 0 || exprItem->m_type == TypeInfo::unknownType())
1613 goto repeat;
1614 evalInitialStructExpression(exprItem, wnd, false);
1615 return;
1617 type:
1619 * Sometimes a VarTree gets registered twice for a type update. So
1620 * it may happen that it has already been updated. Hence, we ignore
1621 * it here and go on to the next task.
1623 if (exprItem->m_type != 0)
1624 goto repeat;
1625 determineType(wnd, exprItem);
1629 void KDebugger::dereferencePointer(ExprWnd* wnd, VarTree* exprItem,
1630 bool immediate)
1632 ASSERT(exprItem->m_varKind == VarTree::VKpointer);
1634 QString expr = exprItem->computeExpr();
1635 TRACE("dereferencing pointer: " + expr);
1636 CmdQueueItem* cmd;
1637 if (immediate) {
1638 cmd = m_d->queueCmd(DCprintDeref, expr, DebuggerDriver::QMoverrideMoreEqual);
1639 } else {
1640 cmd = m_d->queueCmd(DCprintDeref, expr, DebuggerDriver::QMoverride);
1642 // remember which expr this was
1643 cmd->m_expr = exprItem;
1644 cmd->m_exprWnd = wnd;
1647 void KDebugger::determineType(ExprWnd* wnd, VarTree* exprItem)
1649 ASSERT(exprItem->m_varKind == VarTree::VKstruct);
1651 QString expr = exprItem->computeExpr();
1652 TRACE("get type of: " + expr);
1653 CmdQueueItem* cmd;
1654 cmd = m_d->queueCmd(DCfindType, expr, DebuggerDriver::QMoverride);
1656 // remember which expr this was
1657 cmd->m_expr = exprItem;
1658 cmd->m_exprWnd = wnd;
1661 void KDebugger::handleFindType(CmdQueueItem* cmd, const char* output)
1663 QString type;
1664 if (m_d->parseFindType(output, type))
1666 ASSERT(cmd != 0 && cmd->m_expr != 0);
1668 const TypeInfo* info = m_typeTable->lookup(type);
1670 if (info == 0) {
1672 * We've asked gdb for the type of the expression in
1673 * cmd->m_expr, but it returned a name we don't know. The base
1674 * class (and member) types have been checked already (at the
1675 * time when we parsed that particular expression). Now it's
1676 * time to derive the type from the base classes as a last
1677 * resort.
1679 info = cmd->m_expr->inferTypeFromBaseClass();
1680 // if we found a type through this method, register an alias
1681 if (info != 0) {
1682 TRACE("infered alias: " + type);
1683 m_typeTable->registerAlias(type, info);
1686 if (info == 0) {
1687 TRACE("unknown type "+type);
1688 cmd->m_expr->m_type = TypeInfo::unknownType();
1689 } else {
1690 cmd->m_expr->m_type = info;
1691 /* since this node has a new type, we get its value immediately */
1692 evalInitialStructExpression(cmd->m_expr, cmd->m_exprWnd, false);
1693 return;
1697 evalExpressions(); /* queue more of them */
1700 void KDebugger::handlePrintStruct(CmdQueueItem* cmd, const char* output)
1702 VarTree* var = cmd->m_expr;
1703 ASSERT(var != 0);
1704 ASSERT(var->m_varKind == VarTree::VKstruct);
1706 ExprValue* partExpr;
1707 if (cmd->m_cmd == DCprintQStringStruct) {
1708 partExpr = m_d->parseQCharArray(output, false, m_typeTable->qCharIsShort());
1709 } else if (cmd->m_cmd == DCprintWChar) {
1710 partExpr = m_d->parseQCharArray(output, false, true);
1711 } else {
1712 partExpr = m_d->parsePrintExpr(output, false);
1714 bool errorValue =
1715 partExpr == 0 ||
1716 /* we only allow simple values at the moment */
1717 partExpr->m_child != 0;
1719 QString partValue;
1720 if (errorValue)
1722 partValue = "?""?""?"; // 2 question marks in a row would be a trigraph
1723 } else {
1724 partValue = partExpr->m_value;
1726 delete partExpr;
1727 partExpr = 0;
1730 * Updating a struct value works like this: var->m_partialValue holds
1731 * the value that we have gathered so far (it's been initialized with
1732 * var->m_type->m_displayString[0] earlier). Each time we arrive here,
1733 * we append the printed result followed by the next
1734 * var->m_type->m_displayString to var->m_partialValue.
1736 * If the expression we just evaluated was a guard expression, and it
1737 * resulted in an error, we must not evaluate the real expression, but
1738 * go on to the next index. (We must still add the question marks to
1739 * the value).
1741 * Next, if this was the length expression, we still have not seen the
1742 * real expression, but the length of a QString.
1744 ASSERT(var->m_exprIndex >= 0 && var->m_exprIndex <= typeInfoMaxExpr);
1746 if (errorValue || !var->m_exprIndexUseGuard)
1748 // add current partValue (which might be the question marks)
1749 var->m_partialValue += partValue;
1750 var->m_exprIndex++; /* next part */
1751 var->m_exprIndexUseGuard = true;
1752 var->m_partialValue += var->m_type->m_displayString[var->m_exprIndex];
1754 else
1756 // this was a guard expression that succeeded
1757 // go for the real expression
1758 var->m_exprIndexUseGuard = false;
1761 /* go for more sub-expressions if needed */
1762 if (var->m_exprIndex < var->m_type->m_numExprs) {
1763 /* queue a new print command with quite high priority */
1764 evalStructExpression(var, cmd->m_exprWnd, true);
1765 return;
1768 cmd->m_exprWnd->updateStructValue(var);
1770 evalExpressions(); /* enqueue dereferenced pointers */
1773 /* queues the first printStruct command for a struct */
1774 void KDebugger::evalInitialStructExpression(VarTree* var, ExprWnd* wnd, bool immediate)
1776 var->m_exprIndex = 0;
1777 if (var->m_type != TypeInfo::wchartType())
1779 var->m_exprIndexUseGuard = true;
1780 var->m_partialValue = var->m_type->m_displayString[0];
1781 evalStructExpression(var, wnd, immediate);
1783 else
1785 var->m_exprIndexUseGuard = false;
1786 QString expr = var->computeExpr();
1787 CmdQueueItem* cmd = m_d->queueCmd(DCprintWChar, expr,
1788 immediate ? DebuggerDriver::QMoverrideMoreEqual
1789 : DebuggerDriver::QMoverride);
1790 // remember which expression this was
1791 cmd->m_expr = var;
1792 cmd->m_exprWnd = wnd;
1796 /** queues a printStruct command; var must have been initialized correctly */
1797 void KDebugger::evalStructExpression(VarTree* var, ExprWnd* wnd, bool immediate)
1799 QString base = var->computeExpr();
1800 QString expr;
1801 if (var->m_exprIndexUseGuard) {
1802 expr = var->m_type->m_guardStrings[var->m_exprIndex];
1803 if (expr.isEmpty()) {
1804 // no guard, omit it and go to expression
1805 var->m_exprIndexUseGuard = false;
1808 if (!var->m_exprIndexUseGuard) {
1809 expr = var->m_type->m_exprStrings[var->m_exprIndex];
1812 expr.replace("%s", base);
1814 DbgCommand dbgCmd = DCprintStruct;
1815 // check if this is a QString::Data
1816 if (expr.left(15) == "/QString::Data ")
1818 if (m_typeTable->parseQt2QStrings())
1820 expr = expr.mid(15, expr.length()); /* strip off /QString::Data */
1821 dbgCmd = DCprintQStringStruct;
1822 } else {
1824 * This should not happen: the type libraries should be set up
1825 * in a way that this can't happen. If this happens
1826 * nevertheless it means that, eg., kdecore was loaded but qt2
1827 * was not (only qt2 enables the QString feature).
1829 // TODO: remove this "print"; queue the next printStruct instead
1830 expr = "*0";
1833 TRACE("evalStruct: " + expr + (var->m_exprIndexUseGuard ? " // guard" : " // real"));
1834 CmdQueueItem* cmd = m_d->queueCmd(dbgCmd, expr,
1835 immediate ? DebuggerDriver::QMoverrideMoreEqual
1836 : DebuggerDriver::QMnormal);
1838 // remember which expression this was
1839 cmd->m_expr = var;
1840 cmd->m_exprWnd = wnd;
1843 void KDebugger::handleSharedLibs(const char* output)
1845 // parse the table of shared libraries
1846 m_sharedLibs = m_d->parseSharedLibs(output);
1847 m_sharedLibsListed = true;
1849 // get type libraries
1850 m_typeTable->loadLibTypes(m_sharedLibs);
1852 // hand over the QString data cmd
1853 m_d->setPrintQStringDataCmd(m_typeTable->printQStringDataCmd());
1856 CmdQueueItem* KDebugger::loadCoreFile()
1858 return m_d->queueCmd(DCcorefile, m_corefile, DebuggerDriver::QMoverride);
1861 void KDebugger::slotExpanding(QTreeWidgetItem* item)
1863 VarTree* exprItem = static_cast<VarTree*>(item);
1864 if (exprItem->m_varKind != VarTree::VKpointer) {
1865 return;
1867 ExprWnd* wnd = static_cast<ExprWnd*>(item->treeWidget());
1868 dereferencePointer(wnd, exprItem, true);
1871 // add the expression in the edit field to the watch expressions
1872 void KDebugger::addWatch(const QString& t)
1874 QString expr = t.trimmed();
1875 // don't add a watched expression again
1876 if (expr.isEmpty() || m_watchVariables.topLevelExprByName(expr) != 0)
1877 return;
1878 ExprValue e(expr, VarTree::NKplain);
1879 m_watchVariables.insertExpr(&e, *m_typeTable);
1881 // if we are boring ourselves, send down the command
1882 if (m_programActive) {
1883 m_watchEvalExpr.push_back(expr);
1884 if (m_d->isIdle()) {
1885 evalExpressions();
1890 // delete a toplevel watch expression
1891 void KDebugger::slotDeleteWatch()
1893 // delete only allowed while debugger is idle; or else we might delete
1894 // the very expression the debugger is currently working on...
1895 if (m_d == 0 || !m_d->isIdle())
1896 return;
1898 VarTree* item = m_watchVariables.selectedItem();
1899 if (item == 0 || !item->isToplevelExpr())
1900 return;
1902 // remove the variable from the list to evaluate
1903 std::list<QString>::iterator i =
1904 std::find(m_watchEvalExpr.begin(), m_watchEvalExpr.end(), item->getText());
1905 if (i != m_watchEvalExpr.end()) {
1906 m_watchEvalExpr.erase(i);
1908 m_watchVariables.removeExpr(item);
1909 // item is invalid at this point!
1912 void KDebugger::handleRegisters(const char* output)
1914 emit registersChanged(m_d->parseRegisters(output));
1918 * The output of the DCbreak* commands has more accurate information about
1919 * the file and the line number.
1921 * All newly set breakpoints are inserted in the m_brkpts, even those that
1922 * were not set sucessfully. The unsuccessful breakpoints ("orphaned
1923 * breakpoints") are assigned negative ids, and they are tried to set later
1924 * when the program stops again at a breakpoint.
1926 void KDebugger::newBreakpoint(CmdQueueItem* cmd, const char* output)
1928 BrkptIterator bp;
1929 if (cmd->m_brkpt != 0) {
1930 // a new breakpoint, put it in the list
1931 assert(cmd->m_brkpt->id == 0);
1932 m_brkpts.push_back(*cmd->m_brkpt);
1933 delete cmd->m_brkpt;
1934 bp = m_brkpts.end();
1935 --bp;
1936 } else {
1937 // an existing breakpoint was retried
1938 assert(cmd->m_existingBrkpt != 0);
1939 bp = breakpointById(cmd->m_existingBrkpt);
1940 if (bp == m_brkpts.end())
1941 return;
1944 // parse the output to determine success or failure
1945 int id;
1946 QString file;
1947 int lineNo;
1948 QString address;
1949 if (!m_d->parseBreakpoint(output, id, file, lineNo, address))
1952 * Failure, the breakpoint could not be set. If this is a new
1953 * breakpoint, assign it a negative id. We look for the minimal id
1954 * of all breakpoints (that are already in the list) to get the new
1955 * id.
1957 if (bp->id == 0)
1959 int minId = 0;
1960 for (BrkptIterator i = m_brkpts.begin(); i != m_brkpts.end(); ++i) {
1961 if (i->id < minId)
1962 minId = i->id;
1964 bp->id = minId-1;
1966 return;
1969 // The breakpoint was successfully set.
1970 if (bp->id <= 0)
1972 // this is a new or orphaned breakpoint:
1973 // set the remaining properties
1974 if (!bp->enabled) {
1975 m_d->executeCmd(DCdisable, id);
1977 if (!bp->condition.isEmpty()) {
1978 m_d->executeCmd(DCcondition, bp->condition, id);
1982 bp->id = id;
1983 bp->fileName = file;
1984 bp->lineNo = lineNo;
1985 if (!address.isEmpty())
1986 bp->address = address;
1989 void KDebugger::updateBreakList(const char* output)
1991 // get the new list
1992 std::list<Breakpoint> brks;
1993 m_d->parseBreakList(output, brks);
1995 // merge existing information into the new list
1996 // then swap the old and new lists
1998 for (BrkptIterator bp = brks.begin(); bp != brks.end(); ++bp)
2000 BrkptIterator i = breakpointById(bp->id);
2001 if (i != m_brkpts.end())
2003 // preserve accurate location information
2004 // note that xsldbg doesn't have a location in
2005 // the listed breakpoint if it has just been set
2006 // therefore, we copy it as well if necessary
2007 bp->text = i->text;
2008 if (!i->fileName.isEmpty()) {
2009 bp->fileName = i->fileName;
2010 bp->lineNo = i->lineNo;
2015 // orphaned breakpoints must be copied
2016 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
2018 if (bp->isOrphaned())
2019 brks.push_back(*bp);
2022 m_brkpts.swap(brks);
2023 emit breakpointsChanged();
2026 // look if there is at least one temporary breakpoint
2027 // or a watchpoint
2028 bool KDebugger::stopMayChangeBreakList() const
2030 for (BrkptROIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
2032 if (bp->temporary || bp->type == Breakpoint::watchpoint)
2033 return true;
2035 return false;
2038 KDebugger::BrkptIterator KDebugger::breakpointByFilePos(QString file, int lineNo,
2039 const DbgAddr& address)
2041 // look for exact file name match
2042 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
2044 if (bp->lineNo == lineNo &&
2045 bp->fileName == file &&
2046 (address.isEmpty() || bp->address == address))
2048 return bp;
2051 // not found, so try basename
2052 file = QFileInfo(file).fileName();
2054 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
2056 // get base name of breakpoint's file
2057 QString basename = QFileInfo(bp->fileName).fileName();
2059 if (bp->lineNo == lineNo &&
2060 basename == file &&
2061 (address.isEmpty() || bp->address == address))
2063 return bp;
2067 // not found
2068 return m_brkpts.end();
2071 KDebugger::BrkptIterator KDebugger::breakpointById(int id)
2073 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
2075 if (bp->id == id) {
2076 return bp;
2079 // not found
2080 return m_brkpts.end();
2083 void KDebugger::slotValuePopup(const QString& expr)
2085 // search the local variables for a match
2086 VarTree* v = m_localVariables.topLevelExprByName(expr);
2087 if (v == 0) {
2088 // not found, check watch expressions
2089 v = m_watchVariables.topLevelExprByName(expr);
2090 if (v == 0) {
2091 // try a member of 'this'
2092 v = m_localVariables.topLevelExprByName("this");
2093 if (v != 0)
2094 v = ExprWnd::ptrMemberByName(v, expr);
2095 if (v == 0) {
2096 // nothing found, try printing variable in gdb
2098 CmdQueueItem *cmd = m_d->executeCmd(DCprintPopup, expr, false);
2099 cmd->m_popupExpr = expr;
2101 return;
2106 // construct the tip
2107 QString tip = v->getText() + " = " + formatPopupValue(v);
2108 emit valuePopup(tip);
2111 void KDebugger::slotDisassemble(const QString& fileName, int lineNo)
2113 if (m_haveExecutable) {
2114 CmdQueueItem* cmd = m_d->queueCmd(DCinfoline, fileName, lineNo,
2115 DebuggerDriver::QMoverrideMoreEqual);
2116 cmd->m_fileName = fileName;
2117 cmd->m_lineNo = lineNo;
2121 void KDebugger::handleInfoLine(CmdQueueItem* cmd, const char* output)
2123 QString addrFrom, addrTo;
2124 if (cmd->m_lineNo >= 0) {
2125 // disassemble
2126 if (m_d->parseInfoLine(output, addrFrom, addrTo)) {
2127 // got the address range, now get the real code
2128 CmdQueueItem* c = m_d->queueCmd(DCdisassemble, addrFrom, addrTo,
2129 DebuggerDriver::QMoverrideMoreEqual);
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->queueCmd(DCthread, id, DebuggerDriver::QMoverrideMoreEqual);
2161 void KDebugger::setMemoryExpression(const QString& memexpr)
2163 m_memoryExpression = memexpr;
2165 // queue the new expression
2166 if (!m_memoryExpression.isEmpty() &&
2167 isProgramActive() &&
2168 !isProgramRunning())
2170 queueMemoryDump(true);
2174 void KDebugger::queueMemoryDump(bool immediate)
2176 m_d->queueCmd(DCexamine, m_memoryExpression, m_memoryFormat,
2177 immediate ? DebuggerDriver::QMoverrideMoreEqual :
2178 DebuggerDriver::QMoverride);
2181 void KDebugger::handleMemoryDump(const char* output)
2183 std::list<MemoryDump> memdump;
2184 QString msg = m_d->parseMemoryDump(output, memdump);
2185 emit memoryDumpChanged(msg, memdump);
2188 void KDebugger::setProgramCounter(const QString& file, int line, const DbgAddr& addr)
2190 if (addr.isEmpty()) {
2191 // find address of the specified line
2192 CmdQueueItem* cmd = m_d->executeCmd(DCinfoline, file, line);
2193 cmd->m_lineNo = -1; /* indicates "Set PC" UI command */
2194 } else {
2195 // move the program counter to that address
2196 m_d->executeCmd(DCsetpc, addr.asString());
2200 void KDebugger::handleSetPC(const char* /*output*/)
2202 // TODO: handle errors
2204 // now go to the top-most frame
2205 // this also modifies the program counter indicator in the UI
2206 gotoFrame(0);
2209 void KDebugger::slotValueEdited(VarTree* expr, const QString& text)
2211 if (text.simplified().isEmpty())
2212 return; /* no text entered: ignore request */
2214 ExprWnd* wnd = static_cast<ExprWnd*>(expr->treeWidget());
2215 TRACE(QString().sprintf("Changing %s to ",
2216 wnd->name()) + text);
2218 // determine the lvalue to edit
2219 QString lvalue = expr->computeExpr();
2220 CmdQueueItem* cmd = m_d->executeCmd(DCsetvariable, lvalue, text);
2221 cmd->m_expr = expr;
2222 cmd->m_exprWnd = wnd;
2225 void KDebugger::handleSetVariable(CmdQueueItem* cmd, const char* output)
2227 QString msg = m_d->parseSetVariable(output);
2228 if (!msg.isEmpty())
2230 // there was an error; display it in the status bar
2231 m_statusMessage = msg;
2232 emit updateStatusMessage();
2233 return;
2236 // get the new value
2237 QString expr = cmd->m_expr->computeExpr();
2238 CmdQueueItem* printCmd =
2239 m_d->queueCmd(DCprint, expr, DebuggerDriver::QMoverrideMoreEqual);
2240 printCmd->m_expr = cmd->m_expr;
2241 printCmd->m_exprWnd = cmd->m_exprWnd;
2245 #include "debugger.moc"