Convert parseSharedLibs() from QStrList to QStringList.
[kdbg.git] / kdbg / debugger.cpp
blob6a09cf15d2d42d1b3be080a23f82ccf603e1a8a2
1 /*
2 * Copyright Johannes Sixt
3 * This file is licensed under the GNU General Public License Version 2.
4 * See the file COPYING in the toplevel directory of the source directory.
5 */
7 #include "debugger.h"
8 #include "dbgdriver.h"
9 #include "pgmargs.h"
10 #include "typetable.h"
11 #include "exprwnd.h"
12 #include "pgmsettings.h"
13 #include "programconfig.h"
14 #include <qregexp.h>
15 #include <qfileinfo.h>
16 #include <qlistbox.h>
17 #include <qstringlist.h>
18 #include <kapplication.h>
19 #include <kconfig.h>
20 #include <klocale.h> /* i18n */
21 #include <kmessagebox.h>
22 #include <ctype.h>
23 #include <stdlib.h> /* strtol, atoi */
24 #ifdef HAVE_UNISTD_H
25 #include <unistd.h> /* sleep(3) */
26 #endif
27 #include "mydebug.h"
30 KDebugger::KDebugger(QWidget* parent,
31 ExprWnd* localVars,
32 ExprWnd* watchVars,
33 QListBox* backtrace) :
34 QObject(parent, "debugger"),
35 m_ttyLevel(ttyFull),
36 m_memoryFormat(MDTword | MDThex),
37 m_haveExecutable(false),
38 m_programActive(false),
39 m_programRunning(false),
40 m_sharedLibsListed(false),
41 m_typeTable(0),
42 m_programConfig(0),
43 m_d(0),
44 m_localVariables(*localVars),
45 m_watchVariables(*watchVars),
46 m_btWindow(*backtrace)
48 m_envVars.setAutoDelete(true);
50 connect(&m_localVariables, SIGNAL(expanded(QListViewItem*)),
51 SLOT(slotExpanding(QListViewItem*)));
52 connect(&m_watchVariables, SIGNAL(expanded(QListViewItem*)),
53 SLOT(slotExpanding(QListViewItem*)));
54 connect(&m_localVariables, SIGNAL(editValueCommitted(VarTree*, const QString&)),
55 SLOT(slotValueEdited(VarTree*, const QString&)));
56 connect(&m_watchVariables, SIGNAL(editValueCommitted(VarTree*, const QString&)),
57 SLOT(slotValueEdited(VarTree*, const QString&)));
59 connect(&m_btWindow, SIGNAL(highlighted(int)), SLOT(gotoFrame(int)));
61 emit updateUI();
64 KDebugger::~KDebugger()
66 if (m_programConfig != 0) {
67 saveProgramSettings();
68 m_programConfig->sync();
69 delete m_programConfig;
72 delete m_typeTable;
76 void KDebugger::saveSettings(KConfig* /*config*/)
80 void KDebugger::restoreSettings(KConfig* /*config*/)
85 //////////////////////////////////////////////////////////////////////
86 // external interface
88 const char GeneralGroup[] = "General";
89 const char DebuggerCmdStr[] = "DebuggerCmdStr";
90 const char TTYLevelEntry[] = "TTYLevel";
91 const char KDebugger::DriverNameEntry[] = "DriverName";
93 bool KDebugger::debugProgram(const QString& name,
94 DebuggerDriver* driver)
96 if (m_d != 0 && m_d->isRunning())
98 QApplication::setOverrideCursor(waitCursor);
100 stopDriver();
102 QApplication::restoreOverrideCursor();
104 if (m_d->isRunning() || m_haveExecutable) {
105 /* timed out! We can't really do anything useful now */
106 TRACE("timed out while waiting for gdb to die!");
107 return false;
109 delete m_d;
110 m_d = 0;
113 // wire up the driver
114 connect(driver, SIGNAL(activateFileLine(const QString&,int,const DbgAddr&)),
115 this, SIGNAL(activateFileLine(const QString&,int,const DbgAddr&)));
116 connect(driver, SIGNAL(processExited(KProcess*)), SLOT(gdbExited(KProcess*)));
117 connect(driver, SIGNAL(commandReceived(CmdQueueItem*,const char*)),
118 SLOT(parse(CmdQueueItem*,const char*)));
119 connect(driver, SIGNAL(wroteStdin(KProcess*)), SIGNAL(updateUI()));
120 connect(driver, SIGNAL(inferiorRunning()), SLOT(slotInferiorRunning()));
121 connect(driver, SIGNAL(enterIdleState()), SLOT(backgroundUpdate()));
122 connect(driver, SIGNAL(enterIdleState()), SIGNAL(updateUI()));
123 connect(&m_localVariables, SIGNAL(removingItem(VarTree*)),
124 driver, SLOT(dequeueCmdByVar(VarTree*)));
125 connect(&m_watchVariables, SIGNAL(removingItem(VarTree*)),
126 driver, SLOT(dequeueCmdByVar(VarTree*)));
128 // create the program settings object
129 openProgramConfig(name);
131 // get debugger command from per-program settings
132 if (m_programConfig != 0) {
133 m_programConfig->setGroup(GeneralGroup);
134 m_debuggerCmd = readDebuggerCmd();
135 // get terminal emulation level
136 m_ttyLevel = TTYLevel(m_programConfig->readNumEntry(TTYLevelEntry, ttyFull));
138 // the rest is read in later in the handler of DCexecutable
140 m_d = driver;
142 if (!startDriver()) {
143 TRACE("startDriver failed");
144 m_d = 0;
145 return false;
148 TRACE("before file cmd");
149 m_d->executeCmd(DCexecutable, name);
150 m_executable = name;
152 // set remote target
153 if (!m_remoteDevice.isEmpty()) {
154 m_d->executeCmd(DCtargetremote, m_remoteDevice);
155 m_d->queueCmd(DCbt, DebuggerDriver::QMoverride);
156 m_d->queueCmd(DCframe, 0, DebuggerDriver::QMnormal);
157 m_programActive = true;
158 m_haveExecutable = true;
161 // create a type table
162 m_typeTable = new ProgramTypeTable;
163 m_sharedLibsListed = false;
165 emit updateUI();
167 return true;
170 void KDebugger::shutdown()
172 // shut down debugger driver
173 if (m_d != 0 && m_d->isRunning())
175 stopDriver();
179 void KDebugger::useCoreFile(QString corefile, bool batch)
181 m_corefile = corefile;
182 if (!batch) {
183 CmdQueueItem* cmd = loadCoreFile();
184 cmd->m_byUser = true;
188 void KDebugger::setAttachPid(const QString& pid)
190 m_attachedPid = pid;
193 void KDebugger::programRun()
195 if (!isReady())
196 return;
198 // when program is active, but not a core file, continue
199 // otherwise run the program
200 if (m_programActive && m_corefile.isEmpty()) {
201 // gdb command: continue
202 m_d->executeCmd(DCcont, true);
203 } else {
204 // gdb command: run
205 m_d->executeCmd(DCrun, true);
206 m_corefile = QString();
207 m_programActive = true;
209 m_programRunning = true;
212 void KDebugger::attachProgram(const QString& pid)
214 if (!isReady())
215 return;
217 m_attachedPid = pid;
218 TRACE("Attaching to " + m_attachedPid);
219 m_d->executeCmd(DCattach, m_attachedPid);
220 m_programActive = true;
221 m_programRunning = true;
224 void KDebugger::programRunAgain()
226 if (canSingleStep()) {
227 m_d->executeCmd(DCrun, true);
228 m_corefile = QString();
229 m_programRunning = true;
233 void KDebugger::programStep()
235 if (canSingleStep()) {
236 m_d->executeCmd(DCstep, true);
237 m_programRunning = true;
241 void KDebugger::programNext()
243 if (canSingleStep()) {
244 m_d->executeCmd(DCnext, true);
245 m_programRunning = true;
249 void KDebugger::programStepi()
251 if (canSingleStep()) {
252 m_d->executeCmd(DCstepi, true);
253 m_programRunning = true;
257 void KDebugger::programNexti()
259 if (canSingleStep()) {
260 m_d->executeCmd(DCnexti, true);
261 m_programRunning = true;
265 void KDebugger::programFinish()
267 if (canSingleStep()) {
268 m_d->executeCmd(DCfinish, true);
269 m_programRunning = true;
273 void KDebugger::programKill()
275 if (haveExecutable() && isProgramActive()) {
276 if (m_programRunning) {
277 m_d->interruptInferior();
279 // this is an emergency command; flush queues
280 m_d->flushCommands(true);
281 m_d->executeCmd(DCkill, true);
285 bool KDebugger::runUntil(const QString& fileName, int lineNo)
287 if (isReady() && m_programActive && !m_programRunning) {
288 // strip off directory part of file name
289 QString file = fileName;
290 int offset = file.findRev("/");
291 if (offset >= 0) {
292 file.remove(0, offset+1);
294 m_d->executeCmd(DCuntil, file, lineNo, true);
295 m_programRunning = true;
296 return true;
297 } else {
298 return false;
302 void KDebugger::programBreak()
304 if (m_haveExecutable && m_programRunning) {
305 m_d->interruptInferior();
309 void KDebugger::programArgs(QWidget* parent)
311 if (m_haveExecutable) {
312 QStringList allOptions = m_d->boolOptionList();
313 PgmArgs dlg(parent, m_executable, m_envVars, allOptions);
314 dlg.setArgs(m_programArgs);
315 dlg.setWd(m_programWD);
316 dlg.setOptions(m_boolOptions);
317 if (dlg.exec()) {
318 updateProgEnvironment(dlg.args(), dlg.wd(),
319 dlg.envVars(), dlg.options());
324 void KDebugger::programSettings(QWidget* parent)
326 if (!m_haveExecutable)
327 return;
329 ProgramSettings dlg(parent, m_executable);
331 dlg.m_chooseDriver.setDebuggerCmd(m_debuggerCmd);
332 dlg.m_output.setTTYLevel(m_ttyLevel);
334 if (dlg.exec() == QDialog::Accepted)
336 m_debuggerCmd = dlg.m_chooseDriver.debuggerCmd();
337 m_ttyLevel = TTYLevel(dlg.m_output.ttyLevel());
341 bool KDebugger::setBreakpoint(QString file, int lineNo,
342 const DbgAddr& address, bool temporary)
344 if (!isReady()) {
345 return false;
348 BrkptIterator bp = breakpointByFilePos(file, lineNo, address);
349 if (bp == m_brkpts.end())
352 * No such breakpoint, so set a new one. If we have an address, we
353 * set the breakpoint exactly there. Otherwise we use the file name
354 * plus line no.
356 Breakpoint* bp = new Breakpoint;
357 bp->temporary = temporary;
359 if (address.isEmpty())
361 bp->fileName = file;
362 bp->lineNo = lineNo;
364 else
366 bp->address = address;
368 setBreakpoint(bp, false);
370 else
373 * If the breakpoint is disabled, enable it; if it's enabled,
374 * delete that breakpoint.
376 if (bp->enabled) {
377 deleteBreakpoint(bp);
378 } else {
379 enableDisableBreakpoint(bp);
382 return true;
385 void KDebugger::setBreakpoint(Breakpoint* bp, bool queueOnly)
387 CmdQueueItem* cmd = executeBreakpoint(bp, queueOnly);
388 cmd->m_brkpt = bp; // used in newBreakpoint()
391 CmdQueueItem* KDebugger::executeBreakpoint(const Breakpoint* bp, bool queueOnly)
393 CmdQueueItem* cmd;
394 if (!bp->text.isEmpty())
397 * The breakpoint was set using the text box in the breakpoint
398 * list. This is the only way in which watchpoints are set.
400 if (bp->type == Breakpoint::watchpoint) {
401 cmd = m_d->executeCmd(DCwatchpoint, bp->text);
402 } else {
403 cmd = m_d->executeCmd(DCbreaktext, bp->text);
406 else if (bp->address.isEmpty())
408 // strip off directory part of file name
409 QString file = bp->fileName;
410 int offset = file.findRev("/");
411 if (offset >= 0) {
412 file.remove(0, offset+1);
414 if (queueOnly) {
415 cmd = m_d->queueCmd(bp->temporary ? DCtbreakline : DCbreakline,
416 file, bp->lineNo, DebuggerDriver::QMoverride);
417 } else {
418 cmd = m_d->executeCmd(bp->temporary ? DCtbreakline : DCbreakline,
419 file, bp->lineNo);
422 else
424 if (queueOnly) {
425 cmd = m_d->queueCmd(bp->temporary ? DCtbreakaddr : DCbreakaddr,
426 bp->address.asString(), DebuggerDriver::QMoverride);
427 } else {
428 cmd = m_d->executeCmd(bp->temporary ? DCtbreakaddr : DCbreakaddr,
429 bp->address.asString());
432 return cmd;
435 bool KDebugger::enableDisableBreakpoint(QString file, int lineNo,
436 const DbgAddr& address)
438 BrkptIterator bp = breakpointByFilePos(file, lineNo, address);
439 return enableDisableBreakpoint(bp);
442 bool KDebugger::enableDisableBreakpoint(BrkptIterator bp)
444 if (bp == m_brkpts.end())
445 return false;
448 * Toggle enabled/disabled state.
450 * The driver is not bothered if we are modifying an orphaned
451 * breakpoint.
453 if (!bp->isOrphaned()) {
454 if (!canChangeBreakpoints()) {
455 return false;
457 m_d->executeCmd(bp->enabled ? DCdisable : DCenable, bp->id);
458 } else {
459 bp->enabled = !bp->enabled;
460 emit breakpointsChanged();
462 return true;
465 bool KDebugger::conditionalBreakpoint(BrkptIterator bp,
466 const QString& condition,
467 int ignoreCount)
469 if (bp == m_brkpts.end())
470 return false;
473 * Change the condition and ignore count.
475 * The driver is not bothered if we are removing an orphaned
476 * breakpoint.
479 if (!bp->isOrphaned()) {
480 if (!canChangeBreakpoints()) {
481 return false;
484 bool changed = false;
486 if (bp->condition != condition) {
487 // change condition
488 m_d->executeCmd(DCcondition, condition, bp->id);
489 changed = true;
491 if (bp->ignoreCount != ignoreCount) {
492 // change ignore count
493 m_d->executeCmd(DCignore, bp->id, ignoreCount);
494 changed = true;
496 if (changed) {
497 // get the changes
498 m_d->queueCmd(DCinfobreak, DebuggerDriver::QMoverride);
500 } else {
501 bp->condition = condition;
502 bp->ignoreCount = ignoreCount;
503 emit breakpointsChanged();
505 return true;
508 bool KDebugger::deleteBreakpoint(BrkptIterator bp)
510 if (bp == m_brkpts.end())
511 return false;
514 * Remove the breakpoint.
516 * The driver is not bothered if we are removing an orphaned
517 * breakpoint.
519 if (!bp->isOrphaned()) {
520 if (!canChangeBreakpoints()) {
521 return false;
523 m_d->executeCmd(DCdelete, bp->id);
524 } else {
525 m_brkpts.erase(bp);
526 emit breakpointsChanged();
528 return false;
531 bool KDebugger::canSingleStep()
533 return isReady() && m_programActive && !m_programRunning;
536 bool KDebugger::canChangeBreakpoints()
538 return isReady() && !m_programRunning;
541 bool KDebugger::canStart()
543 return isReady() && !m_programActive;
546 bool KDebugger::isReady() const
548 return m_haveExecutable &&
549 m_d != 0 && m_d->canExecuteImmediately();
552 bool KDebugger::isIdle() const
554 return m_d == 0 || m_d->isIdle();
558 //////////////////////////////////////////////////////////
559 // debugger driver
561 bool KDebugger::startDriver()
563 emit debuggerStarting(); /* must set m_inferiorTerminal */
566 * If the per-program command string is empty, use the global setting
567 * (which might also be empty, in which case the driver uses its
568 * default).
570 m_explicitKill = false;
571 if (!m_d->startup(m_debuggerCmd)) {
572 return false;
576 * If we have an output terminal, we use it. Otherwise we will run the
577 * program with input and output redirected to /dev/null. Other
578 * redirections are also necessary depending on the tty emulation
579 * level.
581 int redirect = RDNstdin|RDNstdout|RDNstderr; /* redirect everything */
582 if (!m_inferiorTerminal.isEmpty()) {
583 switch (m_ttyLevel) {
584 default:
585 case ttyNone:
586 // redirect everything
587 break;
588 case ttySimpleOutputOnly:
589 redirect = RDNstdin;
590 break;
591 case ttyFull:
592 redirect = 0;
593 break;
596 m_d->executeCmd(DCtty, m_inferiorTerminal, redirect);
598 return true;
601 void KDebugger::stopDriver()
603 m_explicitKill = true;
605 if (m_attachedPid.isEmpty()) {
606 m_d->terminate();
607 } else {
608 m_d->detachAndTerminate();
612 * We MUST wait until the slot gdbExited() has been called. But to
613 * avoid a deadlock, we wait only for some certain maximum time. Should
614 * this timeout be reached, the only reasonable thing one could do then
615 * is exiting kdbg.
617 kapp->processEvents(1000); /* ideally, this will already shut it down */
618 int maxTime = 20; /* about 20 seconds */
619 while (m_haveExecutable && maxTime > 0) {
620 // give gdb time to die (and send a SIGCLD)
621 ::sleep(1);
622 --maxTime;
623 kapp->processEvents(1000);
627 void KDebugger::gdbExited(KProcess*)
630 * Save settings, but only if gdb has already processed "info line
631 * main", otherwise we would save an empty config file, because it
632 * isn't read in until then!
634 if (m_programConfig != 0) {
635 if (m_haveExecutable) {
636 saveProgramSettings();
637 m_programConfig->sync();
639 delete m_programConfig;
640 m_programConfig = 0;
643 // erase types
644 delete m_typeTable;
645 m_typeTable = 0;
647 if (m_explicitKill) {
648 TRACE(m_d->driverName() + " exited normally");
649 } else {
650 QString msg = i18n("%1 exited unexpectedly.\n"
651 "Restart the session (e.g. with File|Executable).");
652 KMessageBox::error(parentWidget(), msg.arg(m_d->driverName()));
655 // reset state
656 m_haveExecutable = false;
657 m_executable = "";
658 m_programActive = false;
659 m_programRunning = false;
660 m_explicitKill = false;
661 m_debuggerCmd = QString(); /* use global setting at next start! */
662 m_attachedPid = QString(); /* we are no longer attached to a process */
663 m_ttyLevel = ttyFull;
664 m_brkpts.clear();
666 // erase PC
667 emit updatePC(QString(), -1, DbgAddr(), 0);
670 QString KDebugger::getConfigForExe(const QString& name)
672 QFileInfo fi(name);
673 QString pgmConfigFile = fi.dirPath(true);
674 if (!pgmConfigFile.isEmpty()) {
675 pgmConfigFile += '/';
677 pgmConfigFile += ".kdbgrc." + fi.fileName();
678 TRACE("program config file = " + pgmConfigFile);
679 return pgmConfigFile;
682 void KDebugger::openProgramConfig(const QString& name)
684 ASSERT(m_programConfig == 0);
686 QString pgmConfigFile = getConfigForExe(name);
688 m_programConfig = new ProgramConfig(pgmConfigFile);
691 const char EnvironmentGroup[] = "Environment";
692 const char WatchGroup[] = "Watches";
693 const char FileVersion[] = "FileVersion";
694 const char ProgramArgs[] = "ProgramArgs";
695 const char WorkingDirectory[] = "WorkingDirectory";
696 const char OptionsSelected[] = "OptionsSelected";
697 const char Variable[] = "Var%d";
698 const char Value[] = "Value%d";
699 const char ExprFmt[] = "Expr%d";
701 void KDebugger::saveProgramSettings()
703 ASSERT(m_programConfig != 0);
704 m_programConfig->setGroup(GeneralGroup);
705 m_programConfig->writeEntry(FileVersion, 1);
706 m_programConfig->writeEntry(ProgramArgs, m_programArgs);
707 m_programConfig->writeEntry(WorkingDirectory, m_programWD);
708 m_programConfig->writeEntry(OptionsSelected, m_boolOptions);
709 m_programConfig->writeEntry(DebuggerCmdStr, m_debuggerCmd);
710 m_programConfig->writeEntry(TTYLevelEntry, int(m_ttyLevel));
711 QString driverName;
712 if (m_d != 0)
713 driverName = m_d->driverName();
714 m_programConfig->writeEntry(DriverNameEntry, driverName);
716 // write environment variables
717 m_programConfig->deleteGroup(EnvironmentGroup);
718 m_programConfig->setGroup(EnvironmentGroup);
719 QDictIterator<EnvVar> it = m_envVars;
720 EnvVar* var;
721 QString varName;
722 QString varValue;
723 for (int i = 0; (var = it) != 0; ++it, ++i) {
724 varName.sprintf(Variable, i);
725 varValue.sprintf(Value, i);
726 m_programConfig->writeEntry(varName, it.currentKey());
727 m_programConfig->writeEntry(varValue, var->value);
730 saveBreakpoints(m_programConfig);
732 // watch expressions
733 // first get rid of whatever was in this group
734 m_programConfig->deleteGroup(WatchGroup);
735 // then start a new group
736 m_programConfig->setGroup(WatchGroup);
737 VarTree* item = m_watchVariables.firstChild();
738 int watchNum = 0;
739 for (; item != 0; item = item->nextSibling(), ++watchNum) {
740 varName.sprintf(ExprFmt, watchNum);
741 m_programConfig->writeEntry(varName, item->getText());
744 // give others a chance
745 emit saveProgramSpecific(m_programConfig);
748 void KDebugger::overrideProgramArguments(const QString& args)
750 ASSERT(m_programConfig != 0);
751 m_programConfig->setGroup(GeneralGroup);
752 m_programConfig->writeEntry(ProgramArgs, args);
755 void KDebugger::restoreProgramSettings()
757 ASSERT(m_programConfig != 0);
758 m_programConfig->setGroup(GeneralGroup);
760 * We ignore file version for now we will use it in the future to
761 * distinguish different versions of this configuration file.
763 // m_debuggerCmd has been read in already
764 // m_ttyLevel has been read in already
765 QString pgmArgs = m_programConfig->readEntry(ProgramArgs);
766 QString pgmWd = m_programConfig->readEntry(WorkingDirectory);
767 QStringList boolOptions = m_programConfig->readListEntry(OptionsSelected);
768 m_boolOptions = QStringList();
770 // read environment variables
771 m_programConfig->setGroup(EnvironmentGroup);
772 m_envVars.clear();
773 QDict<EnvVar> pgmVars;
774 EnvVar* var;
775 QString varName;
776 QString varValue;
777 for (int i = 0;; ++i) {
778 varName.sprintf(Variable, i);
779 varValue.sprintf(Value, i);
780 if (!m_programConfig->hasKey(varName)) {
781 /* entry not present, assume that we've hit them all */
782 break;
784 QString name = m_programConfig->readEntry(varName);
785 if (name.isEmpty()) {
786 // skip empty names
787 continue;
789 var = new EnvVar;
790 var->value = m_programConfig->readEntry(varValue);
791 var->status = EnvVar::EVnew;
792 pgmVars.insert(name, var);
795 updateProgEnvironment(pgmArgs, pgmWd, pgmVars, boolOptions);
797 restoreBreakpoints(m_programConfig);
799 // watch expressions
800 m_programConfig->setGroup(WatchGroup);
801 m_watchVariables.clear();
802 for (int i = 0;; ++i) {
803 varName.sprintf(ExprFmt, i);
804 if (!m_programConfig->hasKey(varName)) {
805 /* entry not present, assume that we've hit them all */
806 break;
808 QString expr = m_programConfig->readEntry(varName);
809 if (expr.isEmpty()) {
810 // skip empty expressions
811 continue;
813 addWatch(expr);
816 // give others a chance
817 emit restoreProgramSpecific(m_programConfig);
821 * Reads the debugger command line from the program settings. The config
822 * group must have been set by the caller.
824 QString KDebugger::readDebuggerCmd()
826 QString debuggerCmd = m_programConfig->readEntry(DebuggerCmdStr);
828 // always let the user confirm the debugger cmd if we are root
829 if (::geteuid() == 0)
831 if (!debuggerCmd.isEmpty()) {
832 QString msg = i18n(
833 "The settings for this program specify "
834 "the following debugger command:\n%1\n"
835 "Shall this command be used?");
836 if (KMessageBox::warningYesNo(parentWidget(), msg.arg(debuggerCmd))
837 != KMessageBox::Yes)
839 // don't use it
840 debuggerCmd = QString();
844 return debuggerCmd;
848 * Breakpoints are saved one per group.
850 const char BPGroup[] = "Breakpoint %d";
851 const char File[] = "File";
852 const char Line[] = "Line";
853 const char Text[] = "Text";
854 const char Address[] = "Address";
855 const char Temporary[] = "Temporary";
856 const char Enabled[] = "Enabled";
857 const char Condition[] = "Condition";
859 void KDebugger::saveBreakpoints(ProgramConfig* config)
861 QString groupName;
862 int i = 0;
863 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
865 if (bp->type == Breakpoint::watchpoint)
866 continue; /* don't save watchpoints */
867 groupName.sprintf(BPGroup, i++);
869 /* remove remmants */
870 config->deleteGroup(groupName);
872 config->setGroup(groupName);
873 if (!bp->text.isEmpty()) {
875 * The breakpoint was set using the text box in the breakpoint
876 * list. We do not save the location by filename+line number,
877 * but instead honor what the user typed (a function name, for
878 * example, which could move between sessions).
880 config->writeEntry(Text, bp->text);
881 } else if (!bp->fileName.isEmpty()) {
882 config->writeEntry(File, bp->fileName);
883 config->writeEntry(Line, bp->lineNo);
885 * Addresses are hardly correct across sessions, so we don't
886 * save it.
888 } else {
889 config->writeEntry(Address, bp->address.asString());
891 config->writeEntry(Temporary, bp->temporary);
892 config->writeEntry(Enabled, bp->enabled);
893 if (!bp->condition.isEmpty())
894 config->writeEntry(Condition, bp->condition);
895 // we do not save the ignore count
897 // delete remaining groups
898 // we recognize that a group is present if there is an Enabled entry
899 for (;; i++) {
900 groupName.sprintf(BPGroup, i);
901 config->setGroup(groupName);
902 if (!config->hasKey(Enabled)) {
903 /* group not present, assume that we've hit them all */
904 break;
906 config->deleteGroup(groupName);
910 void KDebugger::restoreBreakpoints(ProgramConfig* config)
912 QString groupName;
914 * We recognize the end of the list if there is no Enabled entry
915 * present.
917 for (int i = 0;; i++) {
918 groupName.sprintf(BPGroup, i);
919 config->setGroup(groupName);
920 if (!config->hasKey(Enabled)) {
921 /* group not present, assume that we've hit them all */
922 break;
924 Breakpoint* bp = new Breakpoint;
925 bp->fileName = config->readEntry(File);
926 bp->lineNo = config->readNumEntry(Line, -1);
927 bp->text = config->readEntry(Text);
928 bp->address = config->readEntry(Address);
929 // check consistency
930 if ((bp->fileName.isEmpty() || bp->lineNo < 0) &&
931 bp->text.isEmpty() &&
932 bp->address.isEmpty())
934 delete bp;
935 continue;
937 bp->enabled = config->readBoolEntry(Enabled, true);
938 bp->temporary = config->readBoolEntry(Temporary, false);
939 bp->condition = config->readEntry(Condition);
942 * Add the breakpoint.
944 setBreakpoint(bp, false);
945 // the new breakpoint is disabled or conditionalized later
946 // in newBreakpoint()
948 m_d->queueCmd(DCinfobreak, DebuggerDriver::QMoverride);
952 // parse output of command cmd
953 void KDebugger::parse(CmdQueueItem* cmd, const char* output)
955 ASSERT(cmd != 0); /* queue mustn't be empty */
957 TRACE(QString(__PRETTY_FUNCTION__) + " parsing " + output);
959 switch (cmd->m_cmd) {
960 case DCtargetremote:
961 // the output (if any) is uninteresting
962 case DCsetargs:
963 case DCtty:
964 // there is no output
965 case DCsetenv:
966 case DCunsetenv:
967 case DCsetoption:
968 /* if value is empty, we see output, but we don't care */
969 break;
970 case DCcd:
971 /* display gdb's message in the status bar */
972 m_d->parseChangeWD(output, m_statusMessage);
973 emit updateStatusMessage();
974 break;
975 case DCinitialize:
976 break;
977 case DCexecutable:
978 if (m_d->parseChangeExecutable(output, m_statusMessage))
980 // success; restore breakpoints etc.
981 if (m_programConfig != 0) {
982 restoreProgramSettings();
984 // load file containing main() or core file
985 if (!m_corefile.isEmpty())
987 // load core file
988 loadCoreFile();
990 else if (!m_attachedPid.isEmpty())
992 m_d->queueCmd(DCattach, m_attachedPid, DebuggerDriver::QMoverride);
993 m_programActive = true;
994 m_programRunning = true;
996 else if (!m_remoteDevice.isEmpty())
998 // handled elsewhere
1000 else
1002 m_d->queueCmd(DCinfolinemain, DebuggerDriver::QMnormal);
1004 if (!m_statusMessage.isEmpty())
1005 emit updateStatusMessage();
1006 } else {
1007 QString msg = m_d->driverName() + ": " + m_statusMessage;
1008 KMessageBox::sorry(parentWidget(), msg);
1009 m_executable = "";
1010 m_corefile = ""; /* don't process core file */
1011 m_haveExecutable = false;
1013 break;
1014 case DCcorefile:
1015 // in any event we have an executable at this point
1016 m_haveExecutable = true;
1017 if (m_d->parseCoreFile(output)) {
1018 // loading a core is like stopping at a breakpoint
1019 m_programActive = true;
1020 handleRunCommands(output);
1021 // do not reset m_corefile
1022 } else {
1023 // report error
1024 QString msg = m_d->driverName() + ": " + QString(output);
1025 KMessageBox::sorry(parentWidget(), msg);
1027 // if core file was loaded from command line, revert to info line main
1028 if (!cmd->m_byUser) {
1029 m_d->queueCmd(DCinfolinemain, DebuggerDriver::QMnormal);
1031 m_corefile = QString(); /* core file not available any more */
1033 break;
1034 case DCinfolinemain:
1035 // ignore the output, marked file info follows
1036 m_haveExecutable = true;
1037 break;
1038 case DCinfolocals:
1039 // parse local variables
1040 if (output[0] != '\0') {
1041 handleLocals(output);
1043 break;
1044 case DCinforegisters:
1045 handleRegisters(output);
1046 break;
1047 case DCexamine:
1048 handleMemoryDump(output);
1049 break;
1050 case DCinfoline:
1051 handleInfoLine(cmd, output);
1052 break;
1053 case DCdisassemble:
1054 handleDisassemble(cmd, output);
1055 break;
1056 case DCframe:
1057 handleFrameChange(output);
1058 updateAllExprs();
1059 break;
1060 case DCbt:
1061 handleBacktrace(output);
1062 updateAllExprs();
1063 break;
1064 case DCprint:
1065 handlePrint(cmd, output);
1066 break;
1067 case DCprintDeref:
1068 handlePrintDeref(cmd, output);
1069 break;
1070 case DCattach:
1071 m_haveExecutable = true;
1072 // fall through
1073 case DCrun:
1074 case DCcont:
1075 case DCstep:
1076 case DCstepi:
1077 case DCnext:
1078 case DCnexti:
1079 case DCfinish:
1080 case DCuntil:
1081 case DCthread:
1082 handleRunCommands(output);
1083 break;
1084 case DCkill:
1085 m_programRunning = m_programActive = false;
1086 // erase PC
1087 emit updatePC(QString(), -1, DbgAddr(), 0);
1088 break;
1089 case DCbreaktext:
1090 case DCbreakline:
1091 case DCtbreakline:
1092 case DCbreakaddr:
1093 case DCtbreakaddr:
1094 case DCwatchpoint:
1095 newBreakpoint(cmd, output);
1096 // fall through
1097 case DCdelete:
1098 case DCenable:
1099 case DCdisable:
1100 // these commands need immediate response
1101 m_d->queueCmd(DCinfobreak, DebuggerDriver::QMoverrideMoreEqual);
1102 break;
1103 case DCinfobreak:
1104 // note: this handler must not enqueue a command, since
1105 // DCinfobreak is used at various different places.
1106 updateBreakList(output);
1107 break;
1108 case DCfindType:
1109 handleFindType(cmd, output);
1110 break;
1111 case DCprintStruct:
1112 case DCprintQStringStruct:
1113 case DCprintWChar:
1114 handlePrintStruct(cmd, output);
1115 break;
1116 case DCinfosharedlib:
1117 handleSharedLibs(output);
1118 break;
1119 case DCcondition:
1120 case DCignore:
1121 // we are not interested in the output
1122 break;
1123 case DCinfothreads:
1124 handleThreadList(output);
1125 break;
1126 case DCsetpc:
1127 handleSetPC(output);
1128 break;
1129 case DCsetvariable:
1130 handleSetVariable(cmd, output);
1131 break;
1135 void KDebugger::backgroundUpdate()
1138 * If there are still expressions that need to be updated, then do so.
1140 if (m_programActive)
1141 evalExpressions();
1144 void KDebugger::handleRunCommands(const char* output)
1146 uint flags = m_d->parseProgramStopped(output, m_statusMessage);
1147 emit updateStatusMessage();
1149 m_programActive = flags & DebuggerDriver::SFprogramActive;
1151 // refresh files if necessary
1152 if (flags & DebuggerDriver::SFrefreshSource) {
1153 TRACE("re-reading files");
1154 emit executableUpdated();
1158 * Try to set any orphaned breakpoints now.
1160 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
1162 if (bp->isOrphaned()) {
1163 TRACE(QString("re-trying brkpt loc: %2 file: %3 line: %1")
1164 .arg(bp->lineNo).arg(bp->location, bp->fileName));
1165 CmdQueueItem* cmd = executeBreakpoint(&*bp, true);
1166 cmd->m_existingBrkpt = bp->id; // used in newBreakpoint()
1167 flags |= DebuggerDriver::SFrefreshBreak;
1172 * If we stopped at a breakpoint, we must update the breakpoint list
1173 * because the hit count changes. Also, if the breakpoint was temporary
1174 * it would go away now.
1176 if ((flags & (DebuggerDriver::SFrefreshBreak|DebuggerDriver::SFrefreshSource)) ||
1177 stopMayChangeBreakList())
1179 m_d->queueCmd(DCinfobreak, DebuggerDriver::QMoverride);
1183 * If we haven't listed the shared libraries yet, do so. We must do
1184 * this before we emit any commands that list variables, since the type
1185 * libraries depend on the shared libraries.
1187 if (!m_sharedLibsListed) {
1188 // must be a high-priority command!
1189 m_d->executeCmd(DCinfosharedlib);
1192 // get the backtrace if the program is running
1193 if (m_programActive) {
1194 m_d->queueCmd(DCbt, DebuggerDriver::QMoverride);
1195 } else {
1196 // program finished: erase PC
1197 emit updatePC(QString(), -1, DbgAddr(), 0);
1198 // dequeue any commands in the queues
1199 m_d->flushCommands();
1202 /* Update threads list */
1203 if (m_programActive && (flags & DebuggerDriver::SFrefreshThreads)) {
1204 m_d->queueCmd(DCinfothreads, DebuggerDriver::QMoverride);
1207 m_programRunning = false;
1208 emit programStopped();
1211 void KDebugger::slotInferiorRunning()
1213 m_programRunning = true;
1216 void KDebugger::updateAllExprs()
1218 if (!m_programActive)
1219 return;
1221 // retrieve local variables
1222 m_d->queueCmd(DCinfolocals, DebuggerDriver::QMoverride);
1224 // retrieve registers
1225 m_d->queueCmd(DCinforegisters, DebuggerDriver::QMoverride);
1227 // get new memory dump
1228 if (!m_memoryExpression.isEmpty()) {
1229 queueMemoryDump(false);
1232 // update watch expressions
1233 VarTree* item = m_watchVariables.firstChild();
1234 for (; item != 0; item = item->nextSibling()) {
1235 m_watchEvalExpr.push_back(item->getText());
1239 void KDebugger::updateProgEnvironment(const QString& args, const QString& wd,
1240 const QDict<EnvVar>& newVars,
1241 const QStringList& newOptions)
1243 m_programArgs = args;
1244 m_d->executeCmd(DCsetargs, m_programArgs);
1245 TRACE("new pgm args: " + m_programArgs + "\n");
1247 m_programWD = wd.stripWhiteSpace();
1248 if (!m_programWD.isEmpty()) {
1249 m_d->executeCmd(DCcd, m_programWD);
1250 TRACE("new wd: " + m_programWD + "\n");
1253 // update environment variables
1254 QDictIterator<EnvVar> it = newVars;
1255 EnvVar* val;
1256 for (; (val = it) != 0; ++it) {
1257 QString var = it.currentKey();
1258 switch (val->status) {
1259 case EnvVar::EVnew:
1260 m_envVars.insert(var, val);
1261 // fall thru
1262 case EnvVar::EVdirty:
1263 // the value must be in our list
1264 ASSERT(m_envVars[var] == val);
1265 // update value
1266 m_d->executeCmd(DCsetenv, var, val->value);
1267 break;
1268 case EnvVar::EVdeleted:
1269 // must be in our list
1270 ASSERT(m_envVars[var] == val);
1271 // delete value
1272 m_d->executeCmd(DCunsetenv, var);
1273 m_envVars.remove(var);
1274 break;
1275 default:
1276 ASSERT(false);
1277 case EnvVar::EVclean:
1278 // variable not changed
1279 break;
1283 // update options
1284 QStringList::ConstIterator oi;
1285 for (oi = newOptions.begin(); oi != newOptions.end(); ++oi)
1287 if (m_boolOptions.findIndex(*oi) < 0) {
1288 // the options is currently not set, so set it
1289 m_d->executeCmd(DCsetoption, *oi, 1);
1290 } else {
1291 // option is set, no action required, but move it to the end
1292 m_boolOptions.remove(*oi);
1294 m_boolOptions.append(*oi);
1297 * Now all options that should be set are at the end of m_boolOptions.
1298 * If some options need to be unset, they are at the front of the list.
1299 * Here we unset and remove them.
1301 while (m_boolOptions.count() > newOptions.count()) {
1302 m_d->executeCmd(DCsetoption, m_boolOptions.first(), 0);
1303 m_boolOptions.remove(m_boolOptions.begin());
1307 void KDebugger::handleLocals(const char* output)
1309 // retrieve old list of local variables
1310 QStringList oldVars = m_localVariables.exprList();
1313 * Get local variables.
1315 std::list<ExprValue*> newVars;
1316 parseLocals(output, newVars);
1319 * Clear any old VarTree item pointers, so that later we don't access
1320 * dangling pointers.
1322 m_localVariables.clearPendingUpdates();
1325 * Match old variables against new ones.
1327 for (QStringList::ConstIterator n = oldVars.begin(); n != oldVars.end(); ++n) {
1328 // lookup this variable in the list of new variables
1329 std::list<ExprValue*>::iterator v = newVars.begin();
1330 while (v != newVars.end() && (*v)->m_name != *n)
1331 ++v;
1332 if (v == newVars.end()) {
1333 // old variable not in the new variables
1334 TRACE("old var deleted: " + *n);
1335 VarTree* v = m_localVariables.topLevelExprByName(*n);
1336 if (v != 0) {
1337 m_localVariables.removeExpr(v);
1339 } else {
1340 // variable in both old and new lists: update
1341 TRACE("update var: " + *n);
1342 m_localVariables.updateExpr(*v, *m_typeTable);
1343 // remove the new variable from the list
1344 delete *v;
1345 newVars.erase(v);
1348 // insert all remaining new variables
1349 while (!newVars.empty())
1351 ExprValue* v = newVars.front();
1352 TRACE("new var: " + v->m_name);
1353 m_localVariables.insertExpr(v, *m_typeTable);
1354 delete v;
1355 newVars.pop_front();
1359 void KDebugger::parseLocals(const char* output, std::list<ExprValue*>& newVars)
1361 std::list<ExprValue*> vars;
1362 m_d->parseLocals(output, vars);
1364 QString origName; /* used in renaming variables */
1365 while (!vars.empty())
1367 ExprValue* variable = vars.front();
1368 vars.pop_front();
1370 * When gdb prints local variables, those from the innermost block
1371 * come first. We run through the list of already parsed variables
1372 * to find duplicates (ie. variables that hide local variables from
1373 * a surrounding block). We keep the name of the inner variable, but
1374 * rename those from the outer block so that, when the value is
1375 * updated in the window, the value of the variable that is
1376 * _visible_ changes the color!
1378 int block = 0;
1379 origName = variable->m_name;
1380 for (std::list<ExprValue*>::iterator v = newVars.begin(); v != newVars.end(); ++v) {
1381 if (variable->m_name == (*v)->m_name) {
1382 // we found a duplicate, change name
1383 block++;
1384 QString newName = origName + " (" + QString().setNum(block) + ")";
1385 variable->m_name = newName;
1388 newVars.push_back(variable);
1392 bool KDebugger::handlePrint(CmdQueueItem* cmd, const char* output)
1394 ASSERT(cmd->m_expr != 0);
1396 ExprValue* variable = m_d->parsePrintExpr(output, true);
1397 if (variable == 0)
1398 return false;
1400 // set expression "name"
1401 variable->m_name = cmd->m_expr->getText();
1404 TRACE("update expr: " + cmd->m_expr->getText());
1405 cmd->m_exprWnd->updateExpr(cmd->m_expr, variable, *m_typeTable);
1406 delete variable;
1409 evalExpressions(); /* enqueue dereferenced pointers */
1411 return true;
1414 bool KDebugger::handlePrintDeref(CmdQueueItem* cmd, const char* output)
1416 ASSERT(cmd->m_expr != 0);
1418 ExprValue* variable = m_d->parsePrintExpr(output, true);
1419 if (variable == 0)
1420 return false;
1422 // set expression "name"
1423 variable->m_name = cmd->m_expr->getText();
1427 * We must insert a dummy parent, because otherwise variable's value
1428 * would overwrite cmd->m_expr's value.
1430 ExprValue* dummyParent = new ExprValue(variable->m_name, VarTree::NKplain);
1431 dummyParent->m_varKind = VarTree::VKdummy;
1432 // the name of the parsed variable is the address of the pointer
1433 QString addr = "*" + cmd->m_expr->value();
1434 variable->m_name = addr;
1435 variable->m_nameKind = VarTree::NKaddress;
1437 dummyParent->m_child = variable;
1438 // expand the first level for convenience
1439 variable->m_initiallyExpanded = true;
1440 TRACE("update ptr: " + cmd->m_expr->getText());
1441 cmd->m_exprWnd->updateExpr(cmd->m_expr, dummyParent, *m_typeTable);
1442 delete dummyParent;
1445 evalExpressions(); /* enqueue dereferenced pointers */
1447 return true;
1450 // parse the output of bt
1451 void KDebugger::handleBacktrace(const char* output)
1453 // reduce flicker
1454 m_btWindow.setAutoUpdate(false);
1456 m_btWindow.clear();
1458 std::list<StackFrame> stack;
1459 m_d->parseBackTrace(output, stack);
1461 if (!stack.empty()) {
1462 std::list<StackFrame>::iterator frm = stack.begin();
1463 // first frame must set PC
1464 // note: frm->lineNo is zero-based
1465 emit updatePC(frm->fileName, frm->lineNo, frm->address, frm->frameNo);
1467 for (; frm != stack.end(); ++frm) {
1468 QString func;
1469 if (frm->var != 0)
1470 func = frm->var->m_name;
1471 else
1472 func = frm->fileName + ":" + QString().setNum(frm->lineNo+1);
1473 m_btWindow.insertItem(func);
1474 TRACE("frame " + func + " (" + frm->fileName + ":" +
1475 QString().setNum(frm->lineNo+1) + ")");
1479 m_btWindow.setAutoUpdate(true);
1480 m_btWindow.repaint();
1483 void KDebugger::gotoFrame(int frame)
1485 m_d->executeCmd(DCframe, frame);
1488 void KDebugger::handleFrameChange(const char* output)
1490 QString fileName;
1491 int frameNo;
1492 int lineNo;
1493 DbgAddr address;
1494 if (m_d->parseFrameChange(output, frameNo, fileName, lineNo, address)) {
1495 /* lineNo can be negative here if we can't find a file name */
1496 emit updatePC(fileName, lineNo, address, frameNo);
1497 } else {
1498 emit updatePC(fileName, -1, address, frameNo);
1502 void KDebugger::evalExpressions()
1504 // evaluate expressions in the following order:
1505 // watch expressions
1506 // pointers in local variables
1507 // pointers in watch expressions
1508 // types in local variables
1509 // types in watch expressions
1510 // struct members in local variables
1511 // struct members in watch expressions
1512 VarTree* exprItem = 0;
1513 if (!m_watchEvalExpr.empty())
1515 QString expr = m_watchEvalExpr.front();
1516 m_watchEvalExpr.pop_front();
1517 exprItem = m_watchVariables.topLevelExprByName(expr);
1519 if (exprItem != 0) {
1520 CmdQueueItem* cmd = m_d->queueCmd(DCprint, exprItem->getText(), DebuggerDriver::QMoverride);
1521 // remember which expr this was
1522 cmd->m_expr = exprItem;
1523 cmd->m_exprWnd = &m_watchVariables;
1524 } else {
1525 ExprWnd* wnd;
1526 #define POINTER(widget) \
1527 wnd = &widget; \
1528 exprItem = widget.nextUpdatePtr(); \
1529 if (exprItem != 0) goto pointer
1530 #define STRUCT(widget) \
1531 wnd = &widget; \
1532 exprItem = widget.nextUpdateStruct(); \
1533 if (exprItem != 0) goto ustruct
1534 #define TYPE(widget) \
1535 wnd = &widget; \
1536 exprItem = widget.nextUpdateType(); \
1537 if (exprItem != 0) goto type
1538 repeat:
1539 POINTER(m_localVariables);
1540 POINTER(m_watchVariables);
1541 STRUCT(m_localVariables);
1542 STRUCT(m_watchVariables);
1543 TYPE(m_localVariables);
1544 TYPE(m_watchVariables);
1545 #undef POINTER
1546 #undef STRUCT
1547 #undef TYPE
1548 return;
1550 pointer:
1551 // we have an expression to send
1552 dereferencePointer(wnd, exprItem, false);
1553 return;
1555 ustruct:
1556 // paranoia
1557 if (exprItem->m_type == 0 || exprItem->m_type == TypeInfo::unknownType())
1558 goto repeat;
1559 evalInitialStructExpression(exprItem, wnd, false);
1560 return;
1562 type:
1564 * Sometimes a VarTree gets registered twice for a type update. So
1565 * it may happen that it has already been updated. Hence, we ignore
1566 * it here and go on to the next task.
1568 if (exprItem->m_type != 0)
1569 goto repeat;
1570 determineType(wnd, exprItem);
1574 void KDebugger::dereferencePointer(ExprWnd* wnd, VarTree* exprItem,
1575 bool immediate)
1577 ASSERT(exprItem->m_varKind == VarTree::VKpointer);
1579 QString expr = exprItem->computeExpr();
1580 TRACE("dereferencing pointer: " + expr);
1581 CmdQueueItem* cmd;
1582 if (immediate) {
1583 cmd = m_d->queueCmd(DCprintDeref, expr, DebuggerDriver::QMoverrideMoreEqual);
1584 } else {
1585 cmd = m_d->queueCmd(DCprintDeref, expr, DebuggerDriver::QMoverride);
1587 // remember which expr this was
1588 cmd->m_expr = exprItem;
1589 cmd->m_exprWnd = wnd;
1592 void KDebugger::determineType(ExprWnd* wnd, VarTree* exprItem)
1594 ASSERT(exprItem->m_varKind == VarTree::VKstruct);
1596 QString expr = exprItem->computeExpr();
1597 TRACE("get type of: " + expr);
1598 CmdQueueItem* cmd;
1599 cmd = m_d->queueCmd(DCfindType, expr, DebuggerDriver::QMoverride);
1601 // remember which expr this was
1602 cmd->m_expr = exprItem;
1603 cmd->m_exprWnd = wnd;
1606 void KDebugger::handleFindType(CmdQueueItem* cmd, const char* output)
1608 QString type;
1609 if (m_d->parseFindType(output, type))
1611 ASSERT(cmd != 0 && cmd->m_expr != 0);
1613 TypeInfo* info = m_typeTable->lookup(type);
1615 if (info == 0) {
1617 * We've asked gdb for the type of the expression in
1618 * cmd->m_expr, but it returned a name we don't know. The base
1619 * class (and member) types have been checked already (at the
1620 * time when we parsed that particular expression). Now it's
1621 * time to derive the type from the base classes as a last
1622 * resort.
1624 info = cmd->m_expr->inferTypeFromBaseClass();
1625 // if we found a type through this method, register an alias
1626 if (info != 0) {
1627 TRACE("infered alias: " + type);
1628 m_typeTable->registerAlias(type, info);
1631 if (info == 0) {
1632 TRACE("unknown type "+type);
1633 cmd->m_expr->m_type = TypeInfo::unknownType();
1634 } else {
1635 cmd->m_expr->m_type = info;
1636 /* since this node has a new type, we get its value immediately */
1637 evalInitialStructExpression(cmd->m_expr, cmd->m_exprWnd, false);
1638 return;
1642 evalExpressions(); /* queue more of them */
1645 void KDebugger::handlePrintStruct(CmdQueueItem* cmd, const char* output)
1647 VarTree* var = cmd->m_expr;
1648 ASSERT(var != 0);
1649 ASSERT(var->m_varKind == VarTree::VKstruct);
1651 ExprValue* partExpr;
1652 if (cmd->m_cmd == DCprintQStringStruct) {
1653 partExpr = m_d->parseQCharArray(output, false, m_typeTable->qCharIsShort());
1654 } else if (cmd->m_cmd == DCprintWChar) {
1655 partExpr = m_d->parseQCharArray(output, false, true);
1656 } else {
1657 partExpr = m_d->parsePrintExpr(output, false);
1659 bool errorValue =
1660 partExpr == 0 ||
1661 /* we only allow simple values at the moment */
1662 partExpr->m_child != 0;
1664 QString partValue;
1665 if (errorValue)
1667 partValue = "?""?""?"; // 2 question marks in a row would be a trigraph
1668 } else {
1669 partValue = partExpr->m_value;
1671 delete partExpr;
1672 partExpr = 0;
1675 * Updating a struct value works like this: var->m_partialValue holds
1676 * the value that we have gathered so far (it's been initialized with
1677 * var->m_type->m_displayString[0] earlier). Each time we arrive here,
1678 * we append the printed result followed by the next
1679 * var->m_type->m_displayString to var->m_partialValue.
1681 * If the expression we just evaluated was a guard expression, and it
1682 * resulted in an error, we must not evaluate the real expression, but
1683 * go on to the next index. (We must still add the question marks to
1684 * the value).
1686 * Next, if this was the length expression, we still have not seen the
1687 * real expression, but the length of a QString.
1689 ASSERT(var->m_exprIndex >= 0 && var->m_exprIndex <= typeInfoMaxExpr);
1691 if (errorValue || !var->m_exprIndexUseGuard)
1693 // add current partValue (which might be the question marks)
1694 var->m_partialValue += partValue;
1695 var->m_exprIndex++; /* next part */
1696 var->m_exprIndexUseGuard = true;
1697 var->m_partialValue += var->m_type->m_displayString[var->m_exprIndex];
1699 else
1701 // this was a guard expression that succeeded
1702 // go for the real expression
1703 var->m_exprIndexUseGuard = false;
1706 /* go for more sub-expressions if needed */
1707 if (var->m_exprIndex < var->m_type->m_numExprs) {
1708 /* queue a new print command with quite high priority */
1709 evalStructExpression(var, cmd->m_exprWnd, true);
1710 return;
1713 cmd->m_exprWnd->updateStructValue(var);
1715 evalExpressions(); /* enqueue dereferenced pointers */
1718 /* queues the first printStruct command for a struct */
1719 void KDebugger::evalInitialStructExpression(VarTree* var, ExprWnd* wnd, bool immediate)
1721 var->m_exprIndex = 0;
1722 if (var->m_type != TypeInfo::wchartType())
1724 var->m_exprIndexUseGuard = true;
1725 var->m_partialValue = var->m_type->m_displayString[0];
1726 evalStructExpression(var, wnd, immediate);
1728 else
1730 var->m_exprIndexUseGuard = false;
1731 QString expr = var->computeExpr();
1732 CmdQueueItem* cmd = m_d->queueCmd(DCprintWChar, expr,
1733 immediate ? DebuggerDriver::QMoverrideMoreEqual
1734 : DebuggerDriver::QMoverride);
1735 // remember which expression this was
1736 cmd->m_expr = var;
1737 cmd->m_exprWnd = wnd;
1741 /** queues a printStruct command; var must have been initialized correctly */
1742 void KDebugger::evalStructExpression(VarTree* var, ExprWnd* wnd, bool immediate)
1744 QString base = var->computeExpr();
1745 QString expr;
1746 if (var->m_exprIndexUseGuard) {
1747 expr = var->m_type->m_guardStrings[var->m_exprIndex];
1748 if (expr.isEmpty()) {
1749 // no guard, omit it and go to expression
1750 var->m_exprIndexUseGuard = false;
1753 if (!var->m_exprIndexUseGuard) {
1754 expr = var->m_type->m_exprStrings[var->m_exprIndex];
1757 expr.replace("%s", base);
1759 DbgCommand dbgCmd = DCprintStruct;
1760 // check if this is a QString::Data
1761 if (expr.left(15) == "/QString::Data ")
1763 if (m_typeTable->parseQt2QStrings())
1765 expr = expr.mid(15, expr.length()); /* strip off /QString::Data */
1766 dbgCmd = DCprintQStringStruct;
1767 } else {
1769 * This should not happen: the type libraries should be set up
1770 * in a way that this can't happen. If this happens
1771 * nevertheless it means that, eg., kdecore was loaded but qt2
1772 * was not (only qt2 enables the QString feature).
1774 // TODO: remove this "print"; queue the next printStruct instead
1775 expr = "*0";
1778 TRACE("evalStruct: " + expr + (var->m_exprIndexUseGuard ? " // guard" : " // real"));
1779 CmdQueueItem* cmd = m_d->queueCmd(dbgCmd, expr,
1780 immediate ? DebuggerDriver::QMoverrideMoreEqual
1781 : DebuggerDriver::QMnormal);
1783 // remember which expression this was
1784 cmd->m_expr = var;
1785 cmd->m_exprWnd = wnd;
1788 void KDebugger::handleSharedLibs(const char* output)
1790 // parse the table of shared libraries
1791 m_sharedLibs = m_d->parseSharedLibs(output);
1792 m_sharedLibsListed = true;
1794 // get type libraries
1795 m_typeTable->loadLibTypes(m_sharedLibs);
1797 // hand over the QString data cmd
1798 m_d->setPrintQStringDataCmd(m_typeTable->printQStringDataCmd());
1801 CmdQueueItem* KDebugger::loadCoreFile()
1803 return m_d->queueCmd(DCcorefile, m_corefile, DebuggerDriver::QMoverride);
1806 void KDebugger::slotExpanding(QListViewItem* item)
1808 VarTree* exprItem = static_cast<VarTree*>(item);
1809 if (exprItem->m_varKind != VarTree::VKpointer) {
1810 return;
1812 ExprWnd* wnd = static_cast<ExprWnd*>(item->listView());
1813 dereferencePointer(wnd, exprItem, true);
1816 // add the expression in the edit field to the watch expressions
1817 void KDebugger::addWatch(const QString& t)
1819 QString expr = t.stripWhiteSpace();
1820 // don't add a watched expression again
1821 if (expr.isEmpty() || m_watchVariables.topLevelExprByName(expr) != 0)
1822 return;
1823 ExprValue e(expr, VarTree::NKplain);
1824 m_watchVariables.insertExpr(&e, *m_typeTable);
1826 // if we are boring ourselves, send down the command
1827 if (m_programActive) {
1828 m_watchEvalExpr.push_back(expr);
1829 if (m_d->isIdle()) {
1830 evalExpressions();
1835 // delete a toplevel watch expression
1836 void KDebugger::slotDeleteWatch()
1838 // delete only allowed while debugger is idle; or else we might delete
1839 // the very expression the debugger is currently working on...
1840 if (m_d == 0 || !m_d->isIdle())
1841 return;
1843 VarTree* item = m_watchVariables.currentItem();
1844 if (item == 0 || !item->isToplevelExpr())
1845 return;
1847 // remove the variable from the list to evaluate
1848 QStringList::iterator i = m_watchEvalExpr.find(item->getText());
1849 if (i != m_watchEvalExpr.end()) {
1850 m_watchEvalExpr.erase(i);
1852 m_watchVariables.removeExpr(item);
1853 // item is invalid at this point!
1856 void KDebugger::handleRegisters(const char* output)
1858 emit registersChanged(m_d->parseRegisters(output));
1862 * The output of the DCbreak* commands has more accurate information about
1863 * the file and the line number.
1865 * All newly set breakpoints are inserted in the m_brkpts, even those that
1866 * were not set sucessfully. The unsuccessful breakpoints ("orphaned
1867 * breakpoints") are assigned negative ids, and they are tried to set later
1868 * when the program stops again at a breakpoint.
1870 void KDebugger::newBreakpoint(CmdQueueItem* cmd, const char* output)
1872 BrkptIterator bp;
1873 if (cmd->m_brkpt != 0) {
1874 // a new breakpoint, put it in the list
1875 assert(cmd->m_brkpt->id == 0);
1876 m_brkpts.push_back(*cmd->m_brkpt);
1877 delete cmd->m_brkpt;
1878 bp = m_brkpts.end();
1879 --bp;
1880 } else {
1881 // an existing breakpoint was retried
1882 assert(cmd->m_existingBrkpt != 0);
1883 bp = breakpointById(cmd->m_existingBrkpt);
1884 if (bp == m_brkpts.end())
1885 return;
1888 // parse the output to determine success or failure
1889 int id;
1890 QString file;
1891 int lineNo;
1892 QString address;
1893 if (!m_d->parseBreakpoint(output, id, file, lineNo, address))
1896 * Failure, the breakpoint could not be set. If this is a new
1897 * breakpoint, assign it a negative id. We look for the minimal id
1898 * of all breakpoints (that are already in the list) to get the new
1899 * id.
1901 if (bp->id == 0)
1903 int minId = 0;
1904 for (BrkptIterator i = m_brkpts.begin(); i != m_brkpts.end(); ++i) {
1905 if (i->id < minId)
1906 minId = i->id;
1908 bp->id = minId-1;
1910 return;
1913 // The breakpoint was successfully set.
1914 if (bp->id <= 0)
1916 // this is a new or orphaned breakpoint:
1917 // set the remaining properties
1918 if (!bp->enabled) {
1919 m_d->executeCmd(DCdisable, id);
1921 if (!bp->condition.isEmpty()) {
1922 m_d->executeCmd(DCcondition, bp->condition, id);
1926 bp->id = id;
1927 bp->fileName = file;
1928 bp->lineNo = lineNo;
1929 if (!address.isEmpty())
1930 bp->address = address;
1933 void KDebugger::updateBreakList(const char* output)
1935 // get the new list
1936 std::list<Breakpoint> brks;
1937 m_d->parseBreakList(output, brks);
1939 // merge existing information into the new list
1940 // then swap the old and new lists
1942 for (BrkptIterator bp = brks.begin(); bp != brks.end(); ++bp)
1944 BrkptIterator i = breakpointById(bp->id);
1945 if (i != m_brkpts.end())
1947 // preserve accurate location information
1948 // note that xsldbg doesn't have a location in
1949 // the listed breakpoint if it has just been set
1950 // therefore, we copy it as well if necessary
1951 bp->text = i->text;
1952 if (!i->fileName.isEmpty()) {
1953 bp->fileName = i->fileName;
1954 bp->lineNo = i->lineNo;
1959 // orphaned breakpoints must be copied
1960 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
1962 if (bp->isOrphaned())
1963 brks.push_back(*bp);
1966 m_brkpts.swap(brks);
1967 emit breakpointsChanged();
1970 // look if there is at least one temporary breakpoint
1971 // or a watchpoint
1972 bool KDebugger::stopMayChangeBreakList() const
1974 for (BrkptROIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
1976 if (bp->temporary || bp->type == Breakpoint::watchpoint)
1977 return true;
1979 return false;
1982 KDebugger::BrkptIterator KDebugger::breakpointByFilePos(QString file, int lineNo,
1983 const DbgAddr& address)
1985 // look for exact file name match
1986 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
1988 if (bp->lineNo == lineNo &&
1989 bp->fileName == file &&
1990 (address.isEmpty() || bp->address == address))
1992 return bp;
1995 // not found, so try basename
1996 // strip off directory part of file name
1997 int offset = file.findRev("/");
1998 file.remove(0, offset+1);
2000 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
2002 // get base name of breakpoint's file
2003 QString basename = bp->fileName;
2004 int offset = basename.findRev("/");
2005 if (offset >= 0) {
2006 basename.remove(0, offset+1);
2009 if (bp->lineNo == lineNo &&
2010 basename == file &&
2011 (address.isEmpty() || bp->address == address))
2013 return bp;
2017 // not found
2018 return m_brkpts.end();
2021 KDebugger::BrkptIterator KDebugger::breakpointById(int id)
2023 for (BrkptIterator bp = m_brkpts.begin(); bp != m_brkpts.end(); ++bp)
2025 if (bp->id == id) {
2026 return bp;
2029 // not found
2030 return m_brkpts.end();
2033 void KDebugger::slotValuePopup(const QString& expr)
2035 // search the local variables for a match
2036 VarTree* v = m_localVariables.topLevelExprByName(expr);
2037 if (v == 0) {
2038 // not found, check watch expressions
2039 v = m_watchVariables.topLevelExprByName(expr);
2040 if (v == 0) {
2041 // try a member of 'this'
2042 v = m_localVariables.topLevelExprByName("this");
2043 if (v != 0)
2044 v = ExprWnd::ptrMemberByName(v, expr);
2045 if (v == 0) {
2046 // nothing found; do nothing
2047 return;
2052 // construct the tip
2053 QString tip = v->getText() + " = ";
2054 if (!v->value().isEmpty())
2056 tip += v->value();
2058 else
2060 // no value: we use some hint
2061 switch (v->m_varKind) {
2062 case VarTree::VKstruct:
2063 tip += "{...}";
2064 break;
2065 case VarTree::VKarray:
2066 tip += "[...]";
2067 break;
2068 default:
2069 tip += "?""?""?"; // 2 question marks in a row would be a trigraph
2070 break;
2073 emit valuePopup(tip);
2076 void KDebugger::slotDisassemble(const QString& fileName, int lineNo)
2078 if (m_haveExecutable) {
2079 CmdQueueItem* cmd = m_d->queueCmd(DCinfoline, fileName, lineNo,
2080 DebuggerDriver::QMoverrideMoreEqual);
2081 cmd->m_fileName = fileName;
2082 cmd->m_lineNo = lineNo;
2086 void KDebugger::handleInfoLine(CmdQueueItem* cmd, const char* output)
2088 QString addrFrom, addrTo;
2089 if (cmd->m_lineNo >= 0) {
2090 // disassemble
2091 if (m_d->parseInfoLine(output, addrFrom, addrTo)) {
2092 // got the address range, now get the real code
2093 CmdQueueItem* c = m_d->queueCmd(DCdisassemble, addrFrom, addrTo,
2094 DebuggerDriver::QMoverrideMoreEqual);
2095 c->m_fileName = cmd->m_fileName;
2096 c->m_lineNo = cmd->m_lineNo;
2097 } else {
2098 // no code
2099 emit disassembled(cmd->m_fileName, cmd->m_lineNo, std::list<DisassembledCode>());
2101 } else {
2102 // set program counter
2103 if (m_d->parseInfoLine(output, addrFrom, addrTo)) {
2104 // move the program counter to the start address
2105 m_d->executeCmd(DCsetpc, addrFrom);
2110 void KDebugger::handleDisassemble(CmdQueueItem* cmd, const char* output)
2112 emit disassembled(cmd->m_fileName, cmd->m_lineNo,
2113 m_d->parseDisassemble(output));
2116 void KDebugger::handleThreadList(const char* output)
2118 emit threadsChanged(m_d->parseThreadList(output));
2121 void KDebugger::setThread(int id)
2123 m_d->queueCmd(DCthread, id, DebuggerDriver::QMoverrideMoreEqual);
2126 void KDebugger::setMemoryExpression(const QString& memexpr)
2128 m_memoryExpression = memexpr;
2130 // queue the new expression
2131 if (!m_memoryExpression.isEmpty() &&
2132 isProgramActive() &&
2133 !isProgramRunning())
2135 queueMemoryDump(true);
2139 void KDebugger::queueMemoryDump(bool immediate)
2141 m_d->queueCmd(DCexamine, m_memoryExpression, m_memoryFormat,
2142 immediate ? DebuggerDriver::QMoverrideMoreEqual :
2143 DebuggerDriver::QMoverride);
2146 void KDebugger::handleMemoryDump(const char* output)
2148 std::list<MemoryDump> memdump;
2149 QString msg = m_d->parseMemoryDump(output, memdump);
2150 emit memoryDumpChanged(msg, memdump);
2153 void KDebugger::setProgramCounter(const QString& file, int line, const DbgAddr& addr)
2155 if (addr.isEmpty()) {
2156 // find address of the specified line
2157 CmdQueueItem* cmd = m_d->executeCmd(DCinfoline, file, line);
2158 cmd->m_lineNo = -1; /* indicates "Set PC" UI command */
2159 } else {
2160 // move the program counter to that address
2161 m_d->executeCmd(DCsetpc, addr.asString());
2165 void KDebugger::handleSetPC(const char* /*output*/)
2167 // TODO: handle errors
2169 // now go to the top-most frame
2170 // this also modifies the program counter indicator in the UI
2171 gotoFrame(0);
2174 void KDebugger::slotValueEdited(VarTree* expr, const QString& text)
2176 if (text.simplifyWhiteSpace().isEmpty())
2177 return; /* no text entered: ignore request */
2179 ExprWnd* wnd = static_cast<ExprWnd*>(expr->listView());
2180 TRACE(QString().sprintf("Changing %s to ",
2181 wnd->name()) + text);
2183 // determine the lvalue to edit
2184 QString lvalue = expr->computeExpr();
2185 CmdQueueItem* cmd = m_d->executeCmd(DCsetvariable, lvalue, text);
2186 cmd->m_expr = expr;
2187 cmd->m_exprWnd = wnd;
2190 void KDebugger::handleSetVariable(CmdQueueItem* cmd, const char* output)
2192 QString msg = m_d->parseSetVariable(output);
2193 if (!msg.isEmpty())
2195 // there was an error; display it in the status bar
2196 m_statusMessage = msg;
2197 emit updateStatusMessage();
2198 return;
2201 // get the new value
2202 QString expr = cmd->m_expr->computeExpr();
2203 CmdQueueItem* printCmd =
2204 m_d->queueCmd(DCprint, expr, DebuggerDriver::QMoverrideMoreEqual);
2205 printCmd->m_expr = cmd->m_expr;
2206 printCmd->m_exprWnd = cmd->m_exprWnd;
2210 #include "debugger.moc"