Merge wchar_t support.
[kdbg.git] / kdbg / debugger.cpp
blob3a8ed7497602d4ce1a2df330f47ed965cf303f2e
1 // $Id$
3 // Copyright by Johannes Sixt
4 // This file is under GPL, the GNU General Public Licence
6 #include "debugger.h"
7 #include "dbgdriver.h"
8 #include "pgmargs.h"
9 #include "typetable.h"
10 #include "exprwnd.h"
11 #include "pgmsettings.h"
12 #include "programconfig.h"
13 #include "valarray.h"
14 #include <qregexp.h>
15 #include <qfileinfo.h>
16 #include <qlistbox.h>
17 #include <qstringlist.h>
18 #include <kapp.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);
49 m_brkpts.setAutoDelete(true);
51 connect(&m_localVariables, SIGNAL(expanding(KTreeViewItem*,bool&)),
52 SLOT(slotLocalsExpanding(KTreeViewItem*,bool&)));
53 connect(&m_watchVariables, SIGNAL(expanding(KTreeViewItem*,bool&)),
54 SLOT(slotWatchExpanding(KTreeViewItem*,bool&)));
55 connect(&m_localVariables, SIGNAL(editValueCommitted(int, const QString&)),
56 SLOT(slotValueEdited(int, const QString&)));
57 connect(&m_watchVariables, SIGNAL(editValueCommitted(int, const QString&)),
58 SLOT(slotValueEdited(int, const QString&)));
60 connect(&m_btWindow, SIGNAL(highlighted(int)), SLOT(gotoFrame(int)));
62 emit updateUI();
65 KDebugger::~KDebugger()
67 if (m_programConfig != 0) {
68 saveProgramSettings();
69 m_programConfig->sync();
70 delete m_programConfig;
73 delete m_typeTable;
77 void KDebugger::saveSettings(KConfig* /*config*/)
81 void KDebugger::restoreSettings(KConfig* /*config*/)
86 //////////////////////////////////////////////////////////////////////
87 // external interface
89 const char GeneralGroup[] = "General";
90 const char DebuggerCmdStr[] = "DebuggerCmdStr";
91 const char TTYLevelEntry[] = "TTYLevel";
92 const char KDebugger::DriverNameEntry[] = "DriverName";
94 bool KDebugger::debugProgram(const QString& name,
95 DebuggerDriver* driver)
97 if (m_d != 0 && m_d->isRunning())
99 QApplication::setOverrideCursor(waitCursor);
101 stopDriver();
103 QApplication::restoreOverrideCursor();
105 if (m_d->isRunning() || m_haveExecutable) {
106 /* timed out! We can't really do anything useful now */
107 TRACE("timed out while waiting for gdb to die!");
108 return false;
110 delete m_d;
111 m_d = 0;
114 // wire up the driver
115 connect(driver, SIGNAL(activateFileLine(const QString&,int,const DbgAddr&)),
116 this, SIGNAL(activateFileLine(const QString&,int,const DbgAddr&)));
117 connect(driver, SIGNAL(processExited(KProcess*)), SLOT(gdbExited(KProcess*)));
118 connect(driver, SIGNAL(commandReceived(CmdQueueItem*,const char*)),
119 SLOT(parse(CmdQueueItem*,const char*)));
120 connect(driver, SIGNAL(wroteStdin(KProcess*)), SIGNAL(updateUI()));
121 connect(driver, SIGNAL(inferiorRunning()), SLOT(slotInferiorRunning()));
122 connect(driver, SIGNAL(enterIdleState()), SLOT(backgroundUpdate()));
123 connect(driver, SIGNAL(enterIdleState()), SIGNAL(updateUI()));
125 // create the program settings object
126 openProgramConfig(name);
128 // get debugger command from per-program settings
129 if (m_programConfig != 0) {
130 m_programConfig->setGroup(GeneralGroup);
131 m_debuggerCmd = readDebuggerCmd();
132 // get terminal emulation level
133 m_ttyLevel = TTYLevel(m_programConfig->readNumEntry(TTYLevelEntry, ttyFull));
135 // the rest is read in later in the handler of DCexecutable
137 m_d = driver;
139 if (!startDriver()) {
140 TRACE("startDriver failed");
141 m_d = 0;
142 return false;
145 TRACE("before file cmd");
146 m_d->executeCmd(DCexecutable, name);
147 m_executable = name;
149 // set remote target
150 if (!m_remoteDevice.isEmpty()) {
151 m_d->executeCmd(DCtargetremote, m_remoteDevice);
152 m_d->queueCmd(DCbt, DebuggerDriver::QMoverride);
153 m_d->queueCmd(DCframe, 0, DebuggerDriver::QMnormal);
154 m_programActive = true;
155 m_haveExecutable = true;
158 // create a type table
159 m_typeTable = new ProgramTypeTable;
160 m_sharedLibsListed = false;
162 emit updateUI();
164 return true;
167 void KDebugger::shutdown()
169 // shut down debugger driver
170 if (m_d != 0 && m_d->isRunning())
172 stopDriver();
176 void KDebugger::useCoreFile(QString corefile, bool batch)
178 m_corefile = corefile;
179 if (!batch) {
180 CmdQueueItem* cmd = loadCoreFile();
181 cmd->m_byUser = true;
185 void KDebugger::setAttachPid(const QString& pid)
187 m_attachedPid = pid;
190 void KDebugger::programRun()
192 if (!isReady())
193 return;
195 // when program is active, but not a core file, continue
196 // otherwise run the program
197 if (m_programActive && m_corefile.isEmpty()) {
198 // gdb command: continue
199 m_d->executeCmd(DCcont, true);
200 } else {
201 // gdb command: run
202 m_d->executeCmd(DCrun, true);
203 m_corefile = QString();
204 m_programActive = true;
206 m_programRunning = true;
209 void KDebugger::attachProgram(const QString& pid)
211 if (!isReady())
212 return;
214 m_attachedPid = pid;
215 TRACE("Attaching to " + m_attachedPid);
216 m_d->executeCmd(DCattach, m_attachedPid);
217 m_programActive = true;
218 m_programRunning = true;
221 void KDebugger::programRunAgain()
223 if (canSingleStep()) {
224 m_d->executeCmd(DCrun, true);
225 m_corefile = QString();
226 m_programRunning = true;
230 void KDebugger::programStep()
232 if (canSingleStep()) {
233 m_d->executeCmd(DCstep, true);
234 m_programRunning = true;
238 void KDebugger::programNext()
240 if (canSingleStep()) {
241 m_d->executeCmd(DCnext, true);
242 m_programRunning = true;
246 void KDebugger::programStepi()
248 if (canSingleStep()) {
249 m_d->executeCmd(DCstepi, true);
250 m_programRunning = true;
254 void KDebugger::programNexti()
256 if (canSingleStep()) {
257 m_d->executeCmd(DCnexti, true);
258 m_programRunning = true;
262 void KDebugger::programFinish()
264 if (canSingleStep()) {
265 m_d->executeCmd(DCfinish, true);
266 m_programRunning = true;
270 void KDebugger::programKill()
272 if (haveExecutable() && isProgramActive()) {
273 if (m_programRunning) {
274 m_d->interruptInferior();
276 // this is an emergency command; flush queues
277 m_d->flushCommands(true);
278 m_d->executeCmd(DCkill, true);
282 bool KDebugger::runUntil(const QString& fileName, int lineNo)
284 if (isReady() && m_programActive && !m_programRunning) {
285 // strip off directory part of file name
286 QString file = fileName;
287 int offset = file.findRev("/");
288 if (offset >= 0) {
289 file.remove(0, offset+1);
291 m_d->executeCmd(DCuntil, file, lineNo, true);
292 m_programRunning = true;
293 return true;
294 } else {
295 return false;
299 void KDebugger::programBreak()
301 if (m_haveExecutable && m_programRunning) {
302 m_d->interruptInferior();
306 void KDebugger::programArgs(QWidget* parent)
308 if (m_haveExecutable) {
309 QStringList allOptions = m_d->boolOptionList();
310 PgmArgs dlg(parent, m_executable, m_envVars, allOptions);
311 dlg.setArgs(m_programArgs);
312 dlg.setWd(m_programWD);
313 dlg.setOptions(m_boolOptions);
314 if (dlg.exec()) {
315 updateProgEnvironment(dlg.args(), dlg.wd(),
316 dlg.envVars(), dlg.options());
321 void KDebugger::programSettings(QWidget* parent)
323 if (!m_haveExecutable)
324 return;
326 ProgramSettings dlg(parent, m_executable);
328 dlg.m_chooseDriver.setDebuggerCmd(m_debuggerCmd);
329 dlg.m_output.setTTYLevel(m_ttyLevel);
331 if (dlg.exec() == QDialog::Accepted)
333 m_debuggerCmd = dlg.m_chooseDriver.debuggerCmd();
334 m_ttyLevel = TTYLevel(dlg.m_output.ttyLevel());
338 bool KDebugger::setBreakpoint(QString file, int lineNo,
339 const DbgAddr& address, bool temporary)
341 if (!isReady()) {
342 return false;
345 Breakpoint* bp = breakpointByFilePos(file, lineNo, address);
346 if (bp == 0)
349 * No such breakpoint, so set a new one. If we have an address, we
350 * set the breakpoint exactly there. Otherwise we use the file name
351 * plus line no.
353 Breakpoint* bp = new Breakpoint;
354 bp->temporary = temporary;
356 if (address.isEmpty())
358 bp->fileName = file;
359 bp->lineNo = lineNo;
361 else
363 bp->address = address;
365 setBreakpoint(bp, false);
367 else
370 * If the breakpoint is disabled, enable it; if it's enabled,
371 * delete that breakpoint.
373 if (bp->enabled) {
374 deleteBreakpoint(bp);
375 } else {
376 enableDisableBreakpoint(bp);
379 return true;
382 void KDebugger::setBreakpoint(Breakpoint* bp, bool queueOnly)
384 CmdQueueItem* cmd;
385 if (!bp->text.isEmpty())
388 * The breakpoint was set using the text box in the breakpoint
389 * list. This is the only way in which watchpoints are set.
391 if (bp->type == Breakpoint::watchpoint) {
392 cmd = m_d->executeCmd(DCwatchpoint, bp->text);
393 } else {
394 cmd = m_d->executeCmd(DCbreaktext, bp->text);
397 else if (bp->address.isEmpty())
399 // strip off directory part of file name
400 QString file = bp->fileName;
401 int offset = file.findRev("/");
402 if (offset >= 0) {
403 file.remove(0, offset+1);
405 if (queueOnly) {
406 cmd = m_d->queueCmd(bp->temporary ? DCtbreakline : DCbreakline,
407 file, bp->lineNo, DebuggerDriver::QMoverride);
408 } else {
409 cmd = m_d->executeCmd(bp->temporary ? DCtbreakline : DCbreakline,
410 file, bp->lineNo);
413 else
415 if (queueOnly) {
416 cmd = m_d->queueCmd(bp->temporary ? DCtbreakaddr : DCbreakaddr,
417 bp->address.asString(), DebuggerDriver::QMoverride);
418 } else {
419 cmd = m_d->executeCmd(bp->temporary ? DCtbreakaddr : DCbreakaddr,
420 bp->address.asString());
423 cmd->m_brkpt = bp; // used in newBreakpoint()
426 bool KDebugger::enableDisableBreakpoint(QString file, int lineNo,
427 const DbgAddr& address)
429 Breakpoint* bp = breakpointByFilePos(file, lineNo, address);
430 return bp == 0 || enableDisableBreakpoint(bp);
433 bool KDebugger::enableDisableBreakpoint(Breakpoint* bp)
436 * Toggle enabled/disabled state.
438 * The driver is not bothered if we are modifying an orphaned
439 * breakpoint.
441 if (!bp->isOrphaned()) {
442 if (!canChangeBreakpoints()) {
443 return false;
445 m_d->executeCmd(bp->enabled ? DCdisable : DCenable, bp->id);
446 } else {
447 bp->enabled = !bp->enabled;
448 emit breakpointsChanged();
450 return true;
453 bool KDebugger::conditionalBreakpoint(Breakpoint* bp,
454 const QString& condition,
455 int ignoreCount)
458 * Change the condition and ignore count.
460 * The driver is not bothered if we are removing an orphaned
461 * breakpoint.
464 if (!bp->isOrphaned()) {
465 if (!canChangeBreakpoints()) {
466 return false;
469 bool changed = false;
471 if (bp->condition != condition) {
472 // change condition
473 m_d->executeCmd(DCcondition, condition, bp->id);
474 changed = true;
476 if (bp->ignoreCount != ignoreCount) {
477 // change ignore count
478 m_d->executeCmd(DCignore, bp->id, ignoreCount);
479 changed = true;
481 if (changed) {
482 // get the changes
483 m_d->queueCmd(DCinfobreak, DebuggerDriver::QMoverride);
485 } else {
486 bp->condition = condition;
487 bp->ignoreCount = ignoreCount;
488 emit breakpointsChanged();
490 return true;
493 bool KDebugger::deleteBreakpoint(Breakpoint* bp)
496 * Remove the breakpoint.
498 * The driver is not bothered if we are removing an orphaned
499 * breakpoint.
501 if (!bp->isOrphaned()) {
502 if (!canChangeBreakpoints()) {
503 return false;
505 m_d->executeCmd(DCdelete, bp->id);
506 } else {
507 // move the last entry to bp's slot and shorten the list
508 int i = m_brkpts.findRef(bp);
509 m_brkpts.insert(i, m_brkpts.take(m_brkpts.size()-1));
510 m_brkpts.resize(m_brkpts.size()-1);
511 emit breakpointsChanged();
513 return false;
516 bool KDebugger::canSingleStep()
518 return isReady() && m_programActive && !m_programRunning;
521 bool KDebugger::canChangeBreakpoints()
523 return isReady() && !m_programRunning;
526 bool KDebugger::canStart()
528 return isReady() && !m_programActive;
531 bool KDebugger::isReady() const
533 return m_haveExecutable &&
534 m_d != 0 && m_d->canExecuteImmediately();
537 bool KDebugger::isIdle() const
539 return m_d == 0 || m_d->isIdle();
543 //////////////////////////////////////////////////////////
544 // debugger driver
546 bool KDebugger::startDriver()
548 emit debuggerStarting(); /* must set m_inferiorTerminal */
551 * If the per-program command string is empty, use the global setting
552 * (which might also be empty, in which case the driver uses its
553 * default).
555 m_explicitKill = false;
556 if (!m_d->startup(m_debuggerCmd)) {
557 return false;
561 * If we have an output terminal, we use it. Otherwise we will run the
562 * program with input and output redirected to /dev/null. Other
563 * redirections are also necessary depending on the tty emulation
564 * level.
566 int redirect = RDNstdin|RDNstdout|RDNstderr; /* redirect everything */
567 if (!m_inferiorTerminal.isEmpty()) {
568 switch (m_ttyLevel) {
569 default:
570 case ttyNone:
571 // redirect everything
572 break;
573 case ttySimpleOutputOnly:
574 redirect = RDNstdin;
575 break;
576 case ttyFull:
577 redirect = 0;
578 break;
581 m_d->executeCmd(DCtty, m_inferiorTerminal, redirect);
583 return true;
586 void KDebugger::stopDriver()
588 m_explicitKill = true;
590 if (m_attachedPid.isEmpty()) {
591 m_d->terminate();
592 } else {
593 m_d->detachAndTerminate();
597 * We MUST wait until the slot gdbExited() has been called. But to
598 * avoid a deadlock, we wait only for some certain maximum time. Should
599 * this timeout be reached, the only reasonable thing one could do then
600 * is exiting kdbg.
602 kapp->processEvents(1000); /* ideally, this will already shut it down */
603 int maxTime = 20; /* about 20 seconds */
604 while (m_haveExecutable && maxTime > 0) {
605 // give gdb time to die (and send a SIGCLD)
606 ::sleep(1);
607 --maxTime;
608 kapp->processEvents(1000);
612 void KDebugger::gdbExited(KProcess*)
615 * Save settings, but only if gdb has already processed "info line
616 * main", otherwise we would save an empty config file, because it
617 * isn't read in until then!
619 if (m_programConfig != 0) {
620 if (m_haveExecutable) {
621 saveProgramSettings();
622 m_programConfig->sync();
624 delete m_programConfig;
625 m_programConfig = 0;
628 // erase types
629 delete m_typeTable;
630 m_typeTable = 0;
632 if (m_explicitKill) {
633 TRACE(m_d->driverName() + " exited normally");
634 } else {
635 QString msg = i18n("%1 exited unexpectedly.\n"
636 "Restart the session (e.g. with File|Executable).");
637 KMessageBox::error(parentWidget(), msg.arg(m_d->driverName()));
640 // reset state
641 m_haveExecutable = false;
642 m_executable = "";
643 m_programActive = false;
644 m_programRunning = false;
645 m_explicitKill = false;
646 m_debuggerCmd = QString(); /* use global setting at next start! */
647 m_attachedPid = QString(); /* we are no longer attached to a process */
648 m_ttyLevel = ttyFull;
649 m_brkpts.clear();
651 // erase PC
652 emit updatePC(QString(), -1, DbgAddr(), 0);
655 QString KDebugger::getConfigForExe(const QString& name)
657 QFileInfo fi(name);
658 QString pgmConfigFile = fi.dirPath(true);
659 if (!pgmConfigFile.isEmpty()) {
660 pgmConfigFile += '/';
662 pgmConfigFile += ".kdbgrc." + fi.fileName();
663 TRACE("program config file = " + pgmConfigFile);
664 return pgmConfigFile;
667 void KDebugger::openProgramConfig(const QString& name)
669 ASSERT(m_programConfig == 0);
671 QString pgmConfigFile = getConfigForExe(name);
673 m_programConfig = new ProgramConfig(pgmConfigFile);
676 const char EnvironmentGroup[] = "Environment";
677 const char WatchGroup[] = "Watches";
678 const char FileVersion[] = "FileVersion";
679 const char ProgramArgs[] = "ProgramArgs";
680 const char WorkingDirectory[] = "WorkingDirectory";
681 const char OptionsSelected[] = "OptionsSelected";
682 const char Variable[] = "Var%d";
683 const char Value[] = "Value%d";
684 const char ExprFmt[] = "Expr%d";
686 void KDebugger::saveProgramSettings()
688 ASSERT(m_programConfig != 0);
689 m_programConfig->setGroup(GeneralGroup);
690 m_programConfig->writeEntry(FileVersion, 1);
691 m_programConfig->writeEntry(ProgramArgs, m_programArgs);
692 m_programConfig->writeEntry(WorkingDirectory, m_programWD);
693 m_programConfig->writeEntry(OptionsSelected, m_boolOptions);
694 m_programConfig->writeEntry(DebuggerCmdStr, m_debuggerCmd);
695 m_programConfig->writeEntry(TTYLevelEntry, int(m_ttyLevel));
696 QString driverName;
697 if (m_d != 0)
698 driverName = m_d->driverName();
699 m_programConfig->writeEntry(DriverNameEntry, driverName);
701 // write environment variables
702 m_programConfig->deleteGroup(EnvironmentGroup);
703 m_programConfig->setGroup(EnvironmentGroup);
704 QDictIterator<EnvVar> it = m_envVars;
705 EnvVar* var;
706 QString varName;
707 QString varValue;
708 for (int i = 0; (var = it) != 0; ++it, ++i) {
709 varName.sprintf(Variable, i);
710 varValue.sprintf(Value, i);
711 m_programConfig->writeEntry(varName, it.currentKey());
712 m_programConfig->writeEntry(varValue, var->value);
715 saveBreakpoints(m_programConfig);
717 // watch expressions
718 // first get rid of whatever was in this group
719 m_programConfig->deleteGroup(WatchGroup);
720 // then start a new group
721 m_programConfig->setGroup(WatchGroup);
722 KTreeViewItem* item = m_watchVariables.itemAt(0);
723 int watchNum = 0;
724 for (; item != 0; item = item->getSibling(), ++watchNum) {
725 varName.sprintf(ExprFmt, watchNum);
726 m_programConfig->writeEntry(varName, item->getText());
729 // give others a chance
730 emit saveProgramSpecific(m_programConfig);
733 void KDebugger::restoreProgramSettings()
735 ASSERT(m_programConfig != 0);
736 m_programConfig->setGroup(GeneralGroup);
738 * We ignore file version for now we will use it in the future to
739 * distinguish different versions of this configuration file.
741 // m_debuggerCmd has been read in already
742 // m_ttyLevel has been read in already
743 QString pgmArgs = m_programConfig->readEntry(ProgramArgs);
744 QString pgmWd = m_programConfig->readEntry(WorkingDirectory);
745 QStringList boolOptions = m_programConfig->readListEntry(OptionsSelected);
746 m_boolOptions = QStringList();
748 // read environment variables
749 m_programConfig->setGroup(EnvironmentGroup);
750 m_envVars.clear();
751 QDict<EnvVar> pgmVars;
752 EnvVar* var;
753 QString varName;
754 QString varValue;
755 for (int i = 0;; ++i) {
756 varName.sprintf(Variable, i);
757 varValue.sprintf(Value, i);
758 if (!m_programConfig->hasKey(varName)) {
759 /* entry not present, assume that we've hit them all */
760 break;
762 QString name = m_programConfig->readEntry(varName);
763 if (name.isEmpty()) {
764 // skip empty names
765 continue;
767 var = new EnvVar;
768 var->value = m_programConfig->readEntry(varValue);
769 var->status = EnvVar::EVnew;
770 pgmVars.insert(name, var);
773 updateProgEnvironment(pgmArgs, pgmWd, pgmVars, boolOptions);
775 restoreBreakpoints(m_programConfig);
777 // watch expressions
778 m_programConfig->setGroup(WatchGroup);
779 m_watchVariables.clear();
780 for (int i = 0;; ++i) {
781 varName.sprintf(ExprFmt, i);
782 if (!m_programConfig->hasKey(varName)) {
783 /* entry not present, assume that we've hit them all */
784 break;
786 QString expr = m_programConfig->readEntry(varName);
787 if (expr.isEmpty()) {
788 // skip empty expressions
789 continue;
791 addWatch(expr);
794 // give others a chance
795 emit restoreProgramSpecific(m_programConfig);
799 * Reads the debugger command line from the program settings. The config
800 * group must have been set by the caller.
802 QString KDebugger::readDebuggerCmd()
804 QString debuggerCmd = m_programConfig->readEntry(DebuggerCmdStr);
806 // always let the user confirm the debugger cmd if we are root
807 if (::geteuid() == 0)
809 if (!debuggerCmd.isEmpty()) {
810 QString msg = i18n(
811 "The settings for this program specify "
812 "the following debugger command:\n%1\n"
813 "Shall this command be used?");
814 if (KMessageBox::warningYesNo(parentWidget(), msg.arg(debuggerCmd))
815 != KMessageBox::Yes)
817 // don't use it
818 debuggerCmd = QString();
822 return debuggerCmd;
826 * Breakpoints are saved one per group.
828 const char BPGroup[] = "Breakpoint %d";
829 const char File[] = "File";
830 const char Line[] = "Line";
831 const char Text[] = "Text";
832 const char Address[] = "Address";
833 const char Temporary[] = "Temporary";
834 const char Enabled[] = "Enabled";
835 const char Condition[] = "Condition";
837 void KDebugger::saveBreakpoints(ProgramConfig* config)
839 QString groupName;
840 int i = 0;
841 for (uint j = 0; j < m_brkpts.size(); j++) {
842 Breakpoint* bp = m_brkpts[j];
843 if (bp->type == Breakpoint::watchpoint)
844 continue; /* don't save watchpoints */
845 groupName.sprintf(BPGroup, i++);
847 /* remove remmants */
848 config->deleteGroup(groupName);
850 config->setGroup(groupName);
851 if (!bp->text.isEmpty()) {
853 * The breakpoint was set using the text box in the breakpoint
854 * list. We do not save the location by filename+line number,
855 * but instead honor what the user typed (a function name, for
856 * example, which could move between sessions).
858 config->writeEntry(Text, bp->text);
859 } else if (!bp->fileName.isEmpty()) {
860 config->writeEntry(File, bp->fileName);
861 config->writeEntry(Line, bp->lineNo);
863 * Addresses are hardly correct across sessions, so we don't
864 * save it.
866 } else {
867 config->writeEntry(Address, bp->address.asString());
869 config->writeEntry(Temporary, bp->temporary);
870 config->writeEntry(Enabled, bp->enabled);
871 if (!bp->condition.isEmpty())
872 config->writeEntry(Condition, bp->condition);
873 // we do not save the ignore count
875 // delete remaining groups
876 // we recognize that a group is present if there is an Enabled entry
877 for (;; i++) {
878 groupName.sprintf(BPGroup, i);
879 config->setGroup(groupName);
880 if (!config->hasKey(Enabled)) {
881 /* group not present, assume that we've hit them all */
882 break;
884 config->deleteGroup(groupName);
888 void KDebugger::restoreBreakpoints(ProgramConfig* config)
890 QString groupName;
892 * We recognize the end of the list if there is no Enabled entry
893 * present.
895 for (int i = 0;; i++) {
896 groupName.sprintf(BPGroup, i);
897 config->setGroup(groupName);
898 if (!config->hasKey(Enabled)) {
899 /* group not present, assume that we've hit them all */
900 break;
902 Breakpoint* bp = new Breakpoint;
903 bp->fileName = config->readEntry(File);
904 bp->lineNo = config->readNumEntry(Line, -1);
905 bp->text = config->readEntry(Text);
906 bp->address = config->readEntry(Address);
907 // check consistency
908 if ((bp->fileName.isEmpty() || bp->lineNo < 0) &&
909 bp->text.isEmpty() &&
910 bp->address.isEmpty())
912 delete bp;
913 continue;
915 bp->enabled = config->readBoolEntry(Enabled, true);
916 bp->temporary = config->readBoolEntry(Temporary, false);
917 bp->condition = config->readEntry(Condition);
920 * Add the breakpoint.
922 setBreakpoint(bp, false);
923 // the new breakpoint is disabled or conditionalized later
924 // in newBreakpoint()
926 m_d->queueCmd(DCinfobreak, DebuggerDriver::QMoverride);
930 // parse output of command cmd
931 void KDebugger::parse(CmdQueueItem* cmd, const char* output)
933 ASSERT(cmd != 0); /* queue mustn't be empty */
935 TRACE(QString(__PRETTY_FUNCTION__) + " parsing " + output);
937 switch (cmd->m_cmd) {
938 case DCtargetremote:
939 // the output (if any) is uninteresting
940 case DCsetargs:
941 case DCtty:
942 // there is no output
943 case DCsetenv:
944 case DCunsetenv:
945 case DCsetoption:
946 /* if value is empty, we see output, but we don't care */
947 break;
948 case DCcd:
949 /* display gdb's message in the status bar */
950 m_d->parseChangeWD(output, m_statusMessage);
951 emit updateStatusMessage();
952 break;
953 case DCinitialize:
954 break;
955 case DCexecutable:
956 if (m_d->parseChangeExecutable(output, m_statusMessage))
958 // success; restore breakpoints etc.
959 if (m_programConfig != 0) {
960 restoreProgramSettings();
962 // load file containing main() or core file
963 if (!m_corefile.isEmpty())
965 // load core file
966 loadCoreFile();
968 else if (!m_attachedPid.isEmpty())
970 m_d->queueCmd(DCattach, m_attachedPid, DebuggerDriver::QMoverride);
971 m_programActive = true;
972 m_programRunning = true;
974 else if (!m_remoteDevice.isEmpty())
976 // handled elsewhere
978 else
980 m_d->queueCmd(DCinfolinemain, DebuggerDriver::QMnormal);
982 if (!m_statusMessage.isEmpty())
983 emit updateStatusMessage();
984 } else {
985 QString msg = m_d->driverName() + ": " + m_statusMessage;
986 KMessageBox::sorry(parentWidget(), msg);
987 m_executable = "";
988 m_corefile = ""; /* don't process core file */
989 m_haveExecutable = false;
991 break;
992 case DCcorefile:
993 // in any event we have an executable at this point
994 m_haveExecutable = true;
995 if (m_d->parseCoreFile(output)) {
996 // loading a core is like stopping at a breakpoint
997 m_programActive = true;
998 handleRunCommands(output);
999 // do not reset m_corefile
1000 } else {
1001 // report error
1002 QString msg = m_d->driverName() + ": " + QString(output);
1003 KMessageBox::sorry(parentWidget(), msg);
1005 // if core file was loaded from command line, revert to info line main
1006 if (!cmd->m_byUser) {
1007 m_d->queueCmd(DCinfolinemain, DebuggerDriver::QMnormal);
1009 m_corefile = QString(); /* core file not available any more */
1011 break;
1012 case DCinfolinemain:
1013 // ignore the output, marked file info follows
1014 m_haveExecutable = true;
1015 break;
1016 case DCinfolocals:
1017 // parse local variables
1018 if (output[0] != '\0') {
1019 handleLocals(output);
1021 break;
1022 case DCinforegisters:
1023 handleRegisters(output);
1024 break;
1025 case DCexamine:
1026 handleMemoryDump(output);
1027 break;
1028 case DCinfoline:
1029 handleInfoLine(cmd, output);
1030 break;
1031 case DCdisassemble:
1032 handleDisassemble(cmd, output);
1033 break;
1034 case DCframe:
1035 handleFrameChange(output);
1036 updateAllExprs();
1037 break;
1038 case DCbt:
1039 handleBacktrace(output);
1040 updateAllExprs();
1041 break;
1042 case DCprint:
1043 handlePrint(cmd, output);
1044 break;
1045 case DCprintDeref:
1046 handlePrintDeref(cmd, output);
1047 break;
1048 case DCprintWChar:
1049 handlePrintWChar(cmd, output);
1050 break;
1051 case DCattach:
1052 m_haveExecutable = true;
1053 // fall through
1054 case DCrun:
1055 case DCcont:
1056 case DCstep:
1057 case DCstepi:
1058 case DCnext:
1059 case DCnexti:
1060 case DCfinish:
1061 case DCuntil:
1062 case DCthread:
1063 handleRunCommands(output);
1064 break;
1065 case DCkill:
1066 m_programRunning = m_programActive = false;
1067 // erase PC
1068 emit updatePC(QString(), -1, DbgAddr(), 0);
1069 break;
1070 case DCbreaktext:
1071 case DCbreakline:
1072 case DCtbreakline:
1073 case DCbreakaddr:
1074 case DCtbreakaddr:
1075 case DCwatchpoint:
1076 newBreakpoint(cmd, output);
1077 // fall through
1078 case DCdelete:
1079 case DCenable:
1080 case DCdisable:
1081 // these commands need immediate response
1082 m_d->queueCmd(DCinfobreak, DebuggerDriver::QMoverrideMoreEqual);
1083 break;
1084 case DCinfobreak:
1085 // note: this handler must not enqueue a command, since
1086 // DCinfobreak is used at various different places.
1087 updateBreakList(output);
1088 break;
1089 case DCfindType:
1090 handleFindType(cmd, output);
1091 break;
1092 case DCprintStruct:
1093 case DCprintQStringStruct:
1094 handlePrintStruct(cmd, output);
1095 break;
1096 case DCinfosharedlib:
1097 handleSharedLibs(output);
1098 break;
1099 case DCcondition:
1100 case DCignore:
1101 // we are not interested in the output
1102 break;
1103 case DCinfothreads:
1104 handleThreadList(output);
1105 break;
1106 case DCsetpc:
1107 handleSetPC(output);
1108 break;
1109 case DCsetvariable:
1110 handleSetVariable(cmd, output);
1111 break;
1115 void KDebugger::backgroundUpdate()
1118 * If there are still expressions that need to be updated, then do so.
1120 if (m_programActive)
1121 evalExpressions();
1124 void KDebugger::handleRunCommands(const char* output)
1126 uint flags = m_d->parseProgramStopped(output, m_statusMessage);
1127 emit updateStatusMessage();
1129 m_programActive = flags & DebuggerDriver::SFprogramActive;
1131 // refresh files if necessary
1132 if (flags & DebuggerDriver::SFrefreshSource) {
1133 TRACE("re-reading files");
1134 emit executableUpdated();
1138 * Try to set any orphaned breakpoints now.
1140 for (int i = m_brkpts.size()-1; i >= 0; i--) {
1141 if (m_brkpts[i]->isOrphaned()) {
1142 TRACE("re-trying brkpt loc: "+m_brkpts[i]->location+
1143 " file: "+m_brkpts[i]->fileName+
1144 QString().sprintf(" line: %d", m_brkpts[i]->lineNo));
1145 setBreakpoint(m_brkpts[i], true);
1146 flags |= DebuggerDriver::SFrefreshBreak;
1151 * If we stopped at a breakpoint, we must update the breakpoint list
1152 * because the hit count changes. Also, if the breakpoint was temporary
1153 * it would go away now.
1155 if ((flags & (DebuggerDriver::SFrefreshBreak|DebuggerDriver::SFrefreshSource)) ||
1156 stopMayChangeBreakList())
1158 m_d->queueCmd(DCinfobreak, DebuggerDriver::QMoverride);
1162 * If we haven't listed the shared libraries yet, do so. We must do
1163 * this before we emit any commands that list variables, since the type
1164 * libraries depend on the shared libraries.
1166 if (!m_sharedLibsListed) {
1167 // must be a high-priority command!
1168 m_d->executeCmd(DCinfosharedlib);
1171 // get the backtrace if the program is running
1172 if (m_programActive) {
1173 m_d->queueCmd(DCbt, DebuggerDriver::QMoverride);
1174 } else {
1175 // program finished: erase PC
1176 emit updatePC(QString(), -1, DbgAddr(), 0);
1177 // dequeue any commands in the queues
1178 m_d->flushCommands();
1181 /* Update threads list */
1182 if (m_programActive && (flags & DebuggerDriver::SFrefreshThreads)) {
1183 m_d->queueCmd(DCinfothreads, DebuggerDriver::QMoverride);
1186 m_programRunning = false;
1187 emit programStopped();
1190 void KDebugger::slotInferiorRunning()
1192 m_programRunning = true;
1195 void KDebugger::updateAllExprs()
1197 if (!m_programActive)
1198 return;
1200 // retrieve local variables
1201 m_d->queueCmd(DCinfolocals, DebuggerDriver::QMoverride);
1203 // retrieve registers
1204 m_d->queueCmd(DCinforegisters, DebuggerDriver::QMoverride);
1206 // get new memory dump
1207 if (!m_memoryExpression.isEmpty()) {
1208 queueMemoryDump(false);
1211 // update watch expressions
1212 KTreeViewItem* item = m_watchVariables.itemAt(0);
1213 for (; item != 0; item = item->getSibling()) {
1214 m_watchEvalExpr.append(static_cast<VarTree*>(item));
1218 void KDebugger::updateProgEnvironment(const QString& args, const QString& wd,
1219 const QDict<EnvVar>& newVars,
1220 const QStringList& newOptions)
1222 m_programArgs = args;
1223 m_d->executeCmd(DCsetargs, m_programArgs);
1224 TRACE("new pgm args: " + m_programArgs + "\n");
1226 m_programWD = wd.stripWhiteSpace();
1227 if (!m_programWD.isEmpty()) {
1228 m_d->executeCmd(DCcd, m_programWD);
1229 TRACE("new wd: " + m_programWD + "\n");
1232 // update environment variables
1233 QDictIterator<EnvVar> it = newVars;
1234 EnvVar* val;
1235 for (; (val = it) != 0; ++it) {
1236 QString var = it.currentKey();
1237 switch (val->status) {
1238 case EnvVar::EVnew:
1239 m_envVars.insert(var, val);
1240 // fall thru
1241 case EnvVar::EVdirty:
1242 // the value must be in our list
1243 ASSERT(m_envVars[var] == val);
1244 // update value
1245 m_d->executeCmd(DCsetenv, var, val->value);
1246 break;
1247 case EnvVar::EVdeleted:
1248 // must be in our list
1249 ASSERT(m_envVars[var] == val);
1250 // delete value
1251 m_d->executeCmd(DCunsetenv, var);
1252 m_envVars.remove(var);
1253 break;
1254 default:
1255 ASSERT(false);
1256 case EnvVar::EVclean:
1257 // variable not changed
1258 break;
1262 // update options
1263 QStringList::ConstIterator oi;
1264 for (oi = newOptions.begin(); oi != newOptions.end(); ++oi)
1266 if (m_boolOptions.findIndex(*oi) < 0) {
1267 // the options is currently not set, so set it
1268 m_d->executeCmd(DCsetoption, *oi, 1);
1269 } else {
1270 // option is set, no action required, but move it to the end
1271 m_boolOptions.remove(*oi);
1273 m_boolOptions.append(*oi);
1276 * Now all options that should be set are at the end of m_boolOptions.
1277 * If some options need to be unset, they are at the front of the list.
1278 * Here we unset and remove them.
1280 while (m_boolOptions.count() > newOptions.count()) {
1281 m_d->executeCmd(DCsetoption, m_boolOptions.first(), 0);
1282 m_boolOptions.remove(m_boolOptions.begin());
1286 void KDebugger::handleLocals(const char* output)
1288 // retrieve old list of local variables
1289 QStrList oldVars;
1290 m_localVariables.exprList(oldVars);
1293 * Get local variables.
1295 QList<VarTree> newVars;
1296 parseLocals(output, newVars);
1299 * Clear any old VarTree item pointers, so that later we don't access
1300 * dangling pointers.
1302 m_localVariables.clearPendingUpdates();
1304 // reduce flicker
1305 bool autoU = m_localVariables.autoUpdate();
1306 m_localVariables.setAutoUpdate(false);
1307 bool repaintNeeded = false;
1310 * Match old variables against new ones.
1312 for (const char* n = oldVars.first(); n != 0; n = oldVars.next()) {
1313 // lookup this variable in the list of new variables
1314 VarTree* v = newVars.first();
1315 while (v != 0 && strcmp(v->getText(), n) != 0) {
1316 v = newVars.next();
1318 if (v == 0) {
1319 // old variable not in the new variables
1320 TRACE(QString("old var deleted: ") + n);
1321 v = m_localVariables.topLevelExprByName(n);
1322 removeExpr(&m_localVariables, v);
1323 if (v != 0) repaintNeeded = true;
1324 } else {
1325 // variable in both old and new lists: update
1326 TRACE(QString("update var: ") + n);
1327 m_localVariables.updateExpr(newVars.current());
1328 // remove the new variable from the list
1329 newVars.remove();
1330 delete v;
1331 repaintNeeded = true;
1334 // insert all remaining new variables
1335 for (VarTree* v = newVars.first(); v != 0; v = newVars.next()) {
1336 TRACE("new var: " + v->getText());
1337 m_localVariables.insertExpr(v);
1338 repaintNeeded = true;
1341 // repaint
1342 m_localVariables.setAutoUpdate(autoU);
1343 if (repaintNeeded && autoU && m_localVariables.isVisible())
1344 m_localVariables.repaint();
1347 void KDebugger::parseLocals(const char* output, QList<VarTree>& newVars)
1349 QList<VarTree> vars;
1350 m_d->parseLocals(output, vars);
1352 QString origName; /* used in renaming variables */
1353 while (vars.count() > 0)
1355 VarTree* variable = vars.take(0);
1356 // get some types
1357 variable->inferTypesOfChildren(*m_typeTable);
1359 * When gdb prints local variables, those from the innermost block
1360 * come first. We run through the list of already parsed variables
1361 * to find duplicates (ie. variables that hide local variables from
1362 * a surrounding block). We keep the name of the inner variable, but
1363 * rename those from the outer block so that, when the value is
1364 * updated in the window, the value of the variable that is
1365 * _visible_ changes the color!
1367 int block = 0;
1368 origName = variable->getText();
1369 for (VarTree* v = newVars.first(); v != 0; v = newVars.next()) {
1370 if (variable->getText() == v->getText()) {
1371 // we found a duplicate, change name
1372 block++;
1373 QString newName = origName + " (" + QString().setNum(block) + ")";
1374 variable->setText(newName);
1377 newVars.append(variable);
1381 bool KDebugger::handlePrint(CmdQueueItem* cmd, const char* output)
1383 ASSERT(cmd->m_expr != 0);
1385 VarTree* variable = parseExpr(output, true);
1386 if (variable == 0)
1387 return false;
1389 // set expression "name"
1390 variable->setText(cmd->m_expr->getText());
1393 TRACE("update expr: " + cmd->m_expr->getText());
1394 cmd->m_exprWnd->updateExpr(cmd->m_expr, variable);
1395 delete variable;
1398 evalExpressions(); /* enqueue dereferenced pointers */
1400 return true;
1403 bool KDebugger::handlePrintWChar(CmdQueueItem* cmd, const char* output)
1405 ASSERT(cmd->m_expr != 0);
1407 VarTree* variable = m_d->parseQCharArray(output, false, true);
1408 if (variable == 0) return false;
1410 variable->setText(cmd->m_expr->getText());
1411 variable->m_nameKind = VarTree::NKplain;
1412 variable->m_varKind = VarTree::VKsimple;
1413 // variable->m_value = partValue;
1415 QString val = cmd->m_expr->m_partialValue;
1416 int pos = val.find(") ");
1417 if (pos>0) val = val.mid(pos+2);
1418 variable->m_value = val+" L"+variable->m_value;
1420 m_localVariables.updateExpr(variable);
1421 delete variable;
1423 delete cmd->m_expr;
1424 cmd->m_expr = 0;
1426 evalExpressions(); /* enqueue dereferenced pointers */
1428 return true;
1431 bool KDebugger::handlePrintDeref(CmdQueueItem* cmd, const char* output)
1433 ASSERT(cmd->m_expr != 0);
1435 VarTree* variable = parseExpr(output, true);
1436 if (variable == 0)
1437 return false;
1439 // set expression "name"
1440 variable->setText(cmd->m_expr->getText());
1444 * We must insert a dummy parent, because otherwise variable's value
1445 * would overwrite cmd->m_expr's value.
1447 VarTree* dummyParent = new VarTree(variable->getText(), VarTree::NKplain);
1448 dummyParent->m_varKind = VarTree::VKdummy;
1449 // the name of the parsed variable is the address of the pointer
1450 QString addr = "*" + cmd->m_expr->m_value;
1451 variable->setText(addr);
1452 variable->m_nameKind = VarTree::NKaddress;
1454 dummyParent->appendChild(variable);
1455 dummyParent->setDeleteChildren(true);
1456 // expand the first level for convenience
1457 variable->setExpanded(true);
1458 TRACE("update ptr: " + cmd->m_expr->getText());
1459 cmd->m_exprWnd->updateExpr(cmd->m_expr, dummyParent);
1460 delete dummyParent;
1463 evalExpressions(); /* enqueue dereferenced pointers */
1465 return true;
1468 VarTree* KDebugger::parseExpr(const char* output, bool wantErrorValue)
1470 VarTree* variable;
1472 // check for error conditions
1473 bool goodValue = m_d->parsePrintExpr(output, wantErrorValue, variable);
1475 if (variable != 0 && goodValue)
1477 // get some types
1478 variable->inferTypesOfChildren(*m_typeTable);
1480 return variable;
1483 // parse the output of bt
1484 void KDebugger::handleBacktrace(const char* output)
1486 // reduce flicker
1487 m_btWindow.setAutoUpdate(false);
1489 m_btWindow.clear();
1491 QList<StackFrame> stack;
1492 m_d->parseBackTrace(output, stack);
1494 if (stack.count() > 0) {
1495 StackFrame* frm = stack.take(0);
1496 // first frame must set PC
1497 // note: frm->lineNo is zero-based
1498 emit updatePC(frm->fileName, frm->lineNo, frm->address, frm->frameNo);
1500 do {
1501 QString func;
1502 if (frm->var != 0)
1503 func = frm->var->getText();
1504 else
1505 func = frm->fileName + ":" + QString().setNum(frm->lineNo+1);
1506 m_btWindow.insertItem(func);
1507 TRACE("frame " + func + " (" + frm->fileName + ":" +
1508 QString().setNum(frm->lineNo+1) + ")");
1509 delete frm;
1511 while ((frm = stack.take()) != 0);
1514 m_btWindow.setAutoUpdate(true);
1515 m_btWindow.repaint();
1518 void KDebugger::gotoFrame(int frame)
1520 m_d->executeCmd(DCframe, frame);
1523 void KDebugger::handleFrameChange(const char* output)
1525 QString fileName;
1526 int frameNo;
1527 int lineNo;
1528 DbgAddr address;
1529 if (m_d->parseFrameChange(output, frameNo, fileName, lineNo, address)) {
1530 /* lineNo can be negative here if we can't find a file name */
1531 emit updatePC(fileName, lineNo, address, frameNo);
1532 } else {
1533 emit updatePC(fileName, -1, address, frameNo);
1537 void KDebugger::evalExpressions()
1539 // evaluate expressions in the following order:
1540 // watch expressions
1541 // pointers in local variables
1542 // pointers in watch expressions
1543 // types in local variables
1544 // types in watch expressions
1545 // pointers in 'this'
1546 // types in 'this'
1548 VarTree* exprItem = m_watchEvalExpr.first();
1549 if (exprItem != 0) {
1550 m_watchEvalExpr.remove();
1551 QString expr = exprItem->computeExpr();
1552 TRACE("watch expr: " + expr);
1553 CmdQueueItem* cmd = m_d->queueCmd(DCprint, expr, DebuggerDriver::QMoverride);
1554 // remember which expr this was
1555 cmd->m_expr = exprItem;
1556 cmd->m_exprWnd = &m_watchVariables;
1557 } else {
1558 ExprWnd* wnd;
1559 VarTree* exprItem;
1560 #define POINTER(widget) \
1561 wnd = &widget; \
1562 exprItem = widget.nextUpdatePtr(); \
1563 if (exprItem != 0) goto pointer
1564 #define STRUCT(widget) \
1565 wnd = &widget; \
1566 exprItem = widget.nextUpdateStruct(); \
1567 if (exprItem != 0) goto ustruct
1568 #define TYPE(widget) \
1569 wnd = &widget; \
1570 exprItem = widget.nextUpdateType(); \
1571 if (exprItem != 0) goto type
1572 repeat:
1573 POINTER(m_localVariables);
1574 POINTER(m_watchVariables);
1575 STRUCT(m_localVariables);
1576 STRUCT(m_watchVariables);
1577 TYPE(m_localVariables);
1578 TYPE(m_watchVariables);
1579 #undef POINTER
1580 #undef STRUCT
1581 #undef TYPE
1582 return;
1584 pointer:
1585 // we have an expression to send
1586 dereferencePointer(wnd, exprItem, false);
1587 return;
1589 ustruct:
1590 // paranoia
1591 if (exprItem->m_type == 0 || exprItem->m_type == TypeInfo::unknownType())
1592 goto repeat;
1593 evalInitialStructExpression(exprItem, wnd, false);
1594 return;
1596 type:
1598 * Sometimes a VarTree gets registered twice for a type update. So
1599 * it may happen that it has already been updated. Hence, we ignore
1600 * it here and go on to the next task.
1602 if (exprItem->m_type != 0)
1603 goto repeat;
1604 determineType(wnd, exprItem);
1608 void KDebugger::dereferencePointer(ExprWnd* wnd, VarTree* exprItem,
1609 bool immediate)
1611 ASSERT(exprItem->m_varKind == VarTree::VKpointer);
1612 DbgCommand dbgCmd = DCprintDeref;
1614 QString expr = exprItem->computeExpr();
1616 if (strncmp(exprItem->m_value, "(const wchar_t *)", 17)==0 ||
1617 strncmp(exprItem->m_value, "(wchar_t *)", 11)==0)
1619 expr = "*"+expr+"@wcslen("+expr+")";
1620 dbgCmd = DCprintWChar;
1623 TRACE("dereferencing pointer: " + expr);
1624 CmdQueueItem* cmd;
1625 if (immediate) {
1626 cmd = m_d->queueCmd(dbgCmd, expr, DebuggerDriver::QMoverrideMoreEqual);
1627 } else {
1628 cmd = m_d->queueCmd(dbgCmd, expr, DebuggerDriver::QMoverride);
1630 // remember which expr this was
1631 cmd->m_expr = exprItem;
1632 cmd->m_exprWnd = wnd;
1635 void KDebugger::determineType(ExprWnd* wnd, VarTree* exprItem)
1637 ASSERT(exprItem->m_varKind == VarTree::VKstruct);
1639 QString expr = exprItem->computeExpr();
1640 TRACE("get type of: " + expr);
1641 CmdQueueItem* cmd;
1642 cmd = m_d->queueCmd(DCfindType, expr, DebuggerDriver::QMoverride);
1644 // remember which expr this was
1645 cmd->m_expr = exprItem;
1646 cmd->m_exprWnd = wnd;
1649 void KDebugger::handleFindType(CmdQueueItem* cmd, const char* output)
1651 QString type;
1652 if (m_d->parseFindType(output, type))
1654 ASSERT(cmd != 0 && cmd->m_expr != 0);
1656 TypeInfo* info = m_typeTable->lookup(type);
1658 if (info == 0) {
1660 * We've asked gdb for the type of the expression in
1661 * cmd->m_expr, but it returned a name we don't know. The base
1662 * class (and member) types have been checked already (at the
1663 * time when we parsed that particular expression). Now it's
1664 * time to derive the type from the base classes as a last
1665 * resort.
1667 info = cmd->m_expr->inferTypeFromBaseClass();
1668 // if we found a type through this method, register an alias
1669 if (info != 0) {
1670 TRACE("infered alias: " + type);
1671 m_typeTable->registerAlias(type, info);
1674 if (info == 0) {
1675 TRACE("unknown type "+type);
1676 cmd->m_expr->m_type = TypeInfo::unknownType();
1677 } else {
1678 cmd->m_expr->m_type = info;
1679 /* since this node has a new type, we get its value immediately */
1680 evalInitialStructExpression(cmd->m_expr, cmd->m_exprWnd, false);
1681 return;
1685 evalExpressions(); /* queue more of them */
1688 void KDebugger::handlePrintStruct(CmdQueueItem* cmd, const char* output)
1690 VarTree* var = cmd->m_expr;
1691 ASSERT(var != 0);
1692 ASSERT(var->m_varKind == VarTree::VKstruct);
1694 VarTree* partExpr;
1695 if (cmd->m_cmd != DCprintQStringStruct) {
1696 partExpr = parseExpr(output, false);
1697 } else {
1698 partExpr = m_d->parseQCharArray(output, false, m_typeTable->qCharIsShort());
1700 bool errorValue =
1701 partExpr == 0 ||
1702 /* we only allow simple values at the moment */
1703 partExpr->childCount() != 0;
1705 QString partValue;
1706 if (errorValue)
1708 partValue = "?""?""?"; // 2 question marks in a row would be a trigraph
1709 } else {
1710 partValue = partExpr->m_value;
1712 delete partExpr;
1713 partExpr = 0;
1716 * Updating a struct value works like this: var->m_partialValue holds
1717 * the value that we have gathered so far (it's been initialized with
1718 * var->m_type->m_displayString[0] earlier). Each time we arrive here,
1719 * we append the printed result followed by the next
1720 * var->m_type->m_displayString to var->m_partialValue.
1722 * If the expression we just evaluated was a guard expression, and it
1723 * resulted in an error, we must not evaluate the real expression, but
1724 * go on to the next index. (We must still add the question marks to
1725 * the value).
1727 * Next, if this was the length expression, we still have not seen the
1728 * real expression, but the length of a QString.
1730 ASSERT(var->m_exprIndex >= 0 && var->m_exprIndex <= typeInfoMaxExpr);
1732 if (errorValue || !var->m_exprIndexUseGuard)
1734 // add current partValue (which might be the question marks)
1735 var->m_partialValue += partValue;
1736 var->m_exprIndex++; /* next part */
1737 var->m_exprIndexUseGuard = true;
1738 var->m_partialValue += var->m_type->m_displayString[var->m_exprIndex];
1740 else
1742 // this was a guard expression that succeeded
1743 // go for the real expression
1744 var->m_exprIndexUseGuard = false;
1747 /* go for more sub-expressions if needed */
1748 if (var->m_exprIndex < var->m_type->m_numExprs) {
1749 /* queue a new print command with quite high priority */
1750 evalStructExpression(var, cmd->m_exprWnd, true);
1751 return;
1754 cmd->m_exprWnd->updateStructValue(var);
1756 evalExpressions(); /* enqueue dereferenced pointers */
1759 /* queues the first printStruct command for a struct */
1760 void KDebugger::evalInitialStructExpression(VarTree* var, ExprWnd* wnd, bool immediate)
1762 var->m_exprIndex = 0;
1763 var->m_exprIndexUseGuard = true;
1764 var->m_partialValue = var->m_type->m_displayString[0];
1765 evalStructExpression(var, wnd, immediate);
1768 /* queues a printStruct command; var must have been initialized correctly */
1769 void KDebugger::evalStructExpression(VarTree* var, ExprWnd* wnd, bool immediate)
1771 QString base = var->computeExpr();
1772 QString exprFmt;
1773 if (var->m_exprIndexUseGuard) {
1774 exprFmt = var->m_type->m_guardStrings[var->m_exprIndex];
1775 if (exprFmt.isEmpty()) {
1776 // no guard, omit it and go to expression
1777 var->m_exprIndexUseGuard = false;
1780 if (!var->m_exprIndexUseGuard) {
1781 exprFmt = var->m_type->m_exprStrings[var->m_exprIndex];
1784 QString expr;
1785 expr.sprintf(exprFmt, base.data());
1787 DbgCommand dbgCmd = DCprintStruct;
1788 // check if this is a QString::Data
1789 if (strncmp(expr, "/QString::Data ", 15) == 0)
1791 if (m_typeTable->parseQt2QStrings())
1793 expr = expr.mid(15, expr.length()); /* strip off /QString::Data */
1794 dbgCmd = DCprintQStringStruct;
1795 } else {
1797 * This should not happen: the type libraries should be set up
1798 * in a way that this can't happen. If this happens
1799 * nevertheless it means that, eg., kdecore was loaded but qt2
1800 * was not (only qt2 enables the QString feature).
1802 // TODO: remove this "print"; queue the next printStruct instead
1803 expr = "*0";
1805 } else {
1806 expr = expr;
1808 TRACE("evalStruct: " + expr + (var->m_exprIndexUseGuard ? " // guard" : " // real"));
1809 CmdQueueItem* cmd = m_d->queueCmd(dbgCmd, expr,
1810 immediate ? DebuggerDriver::QMoverrideMoreEqual
1811 : DebuggerDriver::QMnormal);
1813 // remember which expression this was
1814 cmd->m_expr = var;
1815 cmd->m_exprWnd = wnd;
1818 /* removes expression from window */
1819 void KDebugger::removeExpr(ExprWnd* wnd, VarTree* var)
1821 if (var == 0)
1822 return;
1824 // must remove any references to var from command queues
1825 m_d->dequeueCmdByVar(var);
1827 wnd->removeExpr(var);
1830 void KDebugger::handleSharedLibs(const char* output)
1832 // delete all known libraries
1833 m_sharedLibs.clear();
1835 // parse the table of shared libraries
1836 m_d->parseSharedLibs(output, m_sharedLibs);
1837 m_sharedLibsListed = true;
1839 // get type libraries
1840 m_typeTable->loadLibTypes(m_sharedLibs);
1842 // hand over the QString data cmd
1843 m_d->setPrintQStringDataCmd(m_typeTable->printQStringDataCmd());
1846 CmdQueueItem* KDebugger::loadCoreFile()
1848 return m_d->queueCmd(DCcorefile, m_corefile, DebuggerDriver::QMoverride);
1851 void KDebugger::slotLocalsExpanding(KTreeViewItem* item, bool& allow)
1853 exprExpandingHelper(&m_localVariables, item, allow);
1856 void KDebugger::slotWatchExpanding(KTreeViewItem* item, bool& allow)
1858 exprExpandingHelper(&m_watchVariables, item, allow);
1861 void KDebugger::exprExpandingHelper(ExprWnd* wnd, KTreeViewItem* item, bool&)
1863 VarTree* exprItem = static_cast<VarTree*>(item);
1864 if (exprItem->m_varKind != VarTree::VKpointer) {
1865 return;
1867 dereferencePointer(wnd, exprItem, true);
1870 // add the expression in the edit field to the watch expressions
1871 void KDebugger::addWatch(const QString& t)
1873 QString expr = t.stripWhiteSpace();
1874 if (expr.isEmpty())
1875 return;
1876 VarTree* exprItem = new VarTree(expr, VarTree::NKplain);
1877 m_watchVariables.insertExpr(exprItem);
1879 // if we are boring ourselves, send down the command
1880 if (m_programActive) {
1881 m_watchEvalExpr.append(exprItem);
1882 if (m_d->isIdle()) {
1883 evalExpressions();
1888 // delete a toplevel watch expression
1889 void KDebugger::slotDeleteWatch()
1891 // delete only allowed while debugger is idle; or else we might delete
1892 // the very expression the debugger is currently working on...
1893 if (!m_d->isIdle())
1894 return;
1896 int index = m_watchVariables.currentItem();
1897 if (index < 0)
1898 return;
1900 VarTree* item = static_cast<VarTree*>(m_watchVariables.itemAt(index));
1901 if (!item->isToplevelExpr())
1902 return;
1904 // remove the variable from the list to evaluate
1905 if (m_watchEvalExpr.findRef(item) >= 0) {
1906 m_watchEvalExpr.remove();
1908 removeExpr(&m_watchVariables, item);
1909 // item is invalid at this point!
1912 void KDebugger::handleRegisters(const char* output)
1914 QList<RegisterInfo> regs;
1915 m_d->parseRegisters(output, regs);
1917 emit registersChanged(regs);
1919 // delete them all
1920 regs.setAutoDelete(true);
1924 * The output of the DCbreak* commands has more accurate information about
1925 * the file and the line number.
1927 * All newly set breakpoints are inserted in the m_brkpts, even those that
1928 * were not set sucessfully. The unsuccessful breakpoints ("orphaned
1929 * breakpoints") are assigned negative ids, and they are tried to set later
1930 * when the program stops again at a breakpoint.
1932 void KDebugger::newBreakpoint(CmdQueueItem* cmd, const char* output)
1934 Breakpoint* bp = cmd->m_brkpt;
1935 assert(bp != 0);
1936 if (bp == 0)
1937 return;
1939 // if this is a new breakpoint, put it in the list
1940 bool isNew = !m_brkpts.contains(bp);
1941 if (isNew) {
1942 assert(bp->id == 0);
1943 int n = m_brkpts.size();
1944 m_brkpts.resize(n+1);
1945 m_brkpts.insert(n, bp);
1948 // parse the output to determine success or failure
1949 int id;
1950 QString file;
1951 int lineNo;
1952 QString address;
1953 if (!m_d->parseBreakpoint(output, id, file, lineNo, address))
1956 * Failure, the breakpoint could not be set. If this is a new
1957 * breakpoint, assign it a negative id. We look for the minimal id
1958 * of all breakpoints (that are already in the list) to get the new
1959 * id.
1961 if (isNew)
1963 assert(bp->id == 0);
1964 for (int i = m_brkpts.size()-2; i >= 0; i--) {
1965 if (m_brkpts[i]->id < bp->id) {
1966 bp->id = m_brkpts[i]->id;
1967 break;
1970 --bp->id;
1972 return;
1975 // The breakpoint was successfully set.
1976 if (bp->id <= 0)
1978 // this is a new or orphaned breakpoint:
1979 // set the remaining properties
1980 if (!cmd->m_brkpt->enabled) {
1981 m_d->executeCmd(DCdisable, id);
1983 if (!cmd->m_brkpt->condition.isEmpty()) {
1984 m_d->executeCmd(DCcondition, cmd->m_brkpt->condition, id);
1988 bp->id = id;
1989 bp->fileName = file;
1990 bp->lineNo = lineNo;
1991 if (!address.isEmpty())
1992 bp->address = address;
1995 void KDebugger::updateBreakList(const char* output)
1997 // get the new list
1998 QList<Breakpoint> brks;
1999 brks.setAutoDelete(false);
2000 m_d->parseBreakList(output, brks);
2002 // merge new information into existing breakpoints
2004 for (int i = m_brkpts.size()-1; i >= 0; i--) // decrement!
2006 // skip orphaned breakpoints
2007 if (m_brkpts[i]->id < 0)
2008 continue;
2010 for (Breakpoint* bp = brks.first(); bp != 0; bp = brks.next())
2012 if (bp->id == m_brkpts[i]->id) {
2013 // keep accurate location
2014 // except that xsldbg doesn't have a location in
2015 // the old breakpoint if it's just been set
2016 bp->text = m_brkpts[i]->text;
2017 if (!m_brkpts[i]->fileName.isEmpty()) {
2018 bp->fileName = m_brkpts[i]->fileName;
2019 bp->lineNo = m_brkpts[i]->lineNo;
2021 m_brkpts.insert(i, bp); // old object is deleted
2022 goto stillAlive;
2026 * If we get here, this breakpoint is no longer present.
2028 * To delete the breakpoint at i, we place the last breakpoint in
2029 * the list into the slot i. This will delete the old object at i.
2030 * Then we shorten the list by one.
2032 m_brkpts.insert(i, m_brkpts.take(m_brkpts.size()-1));
2033 m_brkpts.resize(m_brkpts.size()-1);
2034 TRACE(QString().sprintf("deleted brkpt %d, have now %d brkpts", i, m_brkpts.size()));
2036 stillAlive:;
2039 // brks may contain new breakpoints not already in m_brkpts
2040 for (const Breakpoint* bp = brks.first(); bp != 0; bp = brks.next())
2042 bool found = false;
2043 for (uint i = 0; i < m_brkpts.size(); i++) {
2044 if (bp->id == m_brkpts[i]->id) {
2045 found = true;
2046 break;
2049 if (!found){
2050 int n = m_brkpts.size();
2051 m_brkpts.resize(n+1);
2052 m_brkpts.insert(n, bp);
2056 emit breakpointsChanged();
2059 // look if there is at least one temporary breakpoint
2060 // or a watchpoint
2061 bool KDebugger::stopMayChangeBreakList() const
2063 for (int i = m_brkpts.size()-1; i >= 0; i--) {
2064 Breakpoint* bp = m_brkpts[i];
2065 if (bp->temporary || bp->type == Breakpoint::watchpoint)
2066 return true;
2068 return false;
2071 Breakpoint* KDebugger::breakpointByFilePos(QString file, int lineNo,
2072 const DbgAddr& address)
2074 // look for exact file name match
2075 int i;
2076 for (i = m_brkpts.size()-1; i >= 0; i--) {
2077 if (m_brkpts[i]->lineNo == lineNo &&
2078 m_brkpts[i]->fileName == file &&
2079 (address.isEmpty() || m_brkpts[i]->address == address))
2081 return m_brkpts[i];
2084 // not found, so try basename
2085 // strip off directory part of file name
2086 int offset = file.findRev("/");
2087 file.remove(0, offset+1);
2089 for (i = m_brkpts.size()-1; i >= 0; i--) {
2090 // get base name of breakpoint's file
2091 QString basename = m_brkpts[i]->fileName;
2092 int offset = basename.findRev("/");
2093 if (offset >= 0) {
2094 basename.remove(0, offset+1);
2097 if (m_brkpts[i]->lineNo == lineNo &&
2098 basename == file &&
2099 (address.isEmpty() || m_brkpts[i]->address == address))
2101 return m_brkpts[i];
2105 // not found
2106 return 0;
2109 Breakpoint* KDebugger::breakpointById(int id)
2111 for (int i = m_brkpts.size()-1; i >= 0; i--)
2113 if (m_brkpts[i]->id == id) {
2114 return m_brkpts[i];
2117 // not found
2118 return 0;
2121 void KDebugger::slotValuePopup(const QString& expr)
2123 // search the local variables for a match
2124 VarTree* v = m_localVariables.topLevelExprByName(expr);
2125 if (v == 0) {
2126 // not found, check watch expressions
2127 v = m_watchVariables.topLevelExprByName(expr);
2128 if (v == 0) {
2129 // nothing found; do nothing
2130 return;
2134 // construct the tip
2135 QString tip = v->getText() + " = ";
2136 if (!v->m_value.isEmpty())
2138 tip += v->m_value;
2140 else
2142 // no value: we use some hint
2143 switch (v->m_varKind) {
2144 case VarTree::VKstruct:
2145 tip += "{...}";
2146 break;
2147 case VarTree::VKarray:
2148 tip += "[...]";
2149 break;
2150 default:
2151 tip += "?""?""?"; // 2 question marks in a row would be a trigraph
2152 break;
2155 emit valuePopup(tip);
2158 void KDebugger::slotDisassemble(const QString& fileName, int lineNo)
2160 CmdQueueItem* cmd = m_d->queueCmd(DCinfoline, fileName, lineNo,
2161 DebuggerDriver::QMoverrideMoreEqual);
2162 cmd->m_fileName = fileName;
2163 cmd->m_lineNo = lineNo;
2166 void KDebugger::handleInfoLine(CmdQueueItem* cmd, const char* output)
2168 QString addrFrom, addrTo;
2169 if (cmd->m_lineNo >= 0) {
2170 // disassemble
2171 if (m_d->parseInfoLine(output, addrFrom, addrTo)) {
2172 // got the address range, now get the real code
2173 CmdQueueItem* c = m_d->queueCmd(DCdisassemble, addrFrom, addrTo,
2174 DebuggerDriver::QMoverrideMoreEqual);
2175 c->m_fileName = cmd->m_fileName;
2176 c->m_lineNo = cmd->m_lineNo;
2177 } else {
2178 // no code
2179 QList<DisassembledCode> empty;
2180 emit disassembled(cmd->m_fileName, cmd->m_lineNo, empty);
2182 } else {
2183 // set program counter
2184 if (m_d->parseInfoLine(output, addrFrom, addrTo)) {
2185 // move the program counter to the start address
2186 m_d->executeCmd(DCsetpc, addrFrom);
2191 void KDebugger::handleDisassemble(CmdQueueItem* cmd, const char* output)
2193 QList<DisassembledCode> code;
2194 code.setAutoDelete(true);
2195 m_d->parseDisassemble(output, code);
2196 emit disassembled(cmd->m_fileName, cmd->m_lineNo, code);
2199 void KDebugger::handleThreadList(const char* output)
2201 QList<ThreadInfo> threads;
2202 threads.setAutoDelete(true);
2203 m_d->parseThreadList(output, threads);
2204 emit threadsChanged(threads);
2207 void KDebugger::setThread(int id)
2209 m_d->queueCmd(DCthread, id, DebuggerDriver::QMoverrideMoreEqual);
2212 void KDebugger::setMemoryExpression(const QString& memexpr)
2214 m_memoryExpression = memexpr;
2216 // queue the new expression
2217 if (!m_memoryExpression.isEmpty() &&
2218 isProgramActive() &&
2219 !isProgramRunning())
2221 queueMemoryDump(true);
2225 void KDebugger::queueMemoryDump(bool immediate)
2227 m_d->queueCmd(DCexamine, m_memoryExpression, m_memoryFormat,
2228 immediate ? DebuggerDriver::QMoverrideMoreEqual :
2229 DebuggerDriver::QMoverride);
2232 void KDebugger::handleMemoryDump(const char* output)
2234 QList<MemoryDump> memdump;
2235 memdump.setAutoDelete(true);
2236 QString msg = m_d->parseMemoryDump(output, memdump);
2237 emit memoryDumpChanged(msg, memdump);
2240 void KDebugger::setProgramCounter(const QString& file, int line, const DbgAddr& addr)
2242 if (addr.isEmpty()) {
2243 // find address of the specified line
2244 CmdQueueItem* cmd = m_d->executeCmd(DCinfoline, file, line);
2245 cmd->m_lineNo = -1; /* indicates "Set PC" UI command */
2246 } else {
2247 // move the program counter to that address
2248 m_d->executeCmd(DCsetpc, addr.asString());
2252 void KDebugger::handleSetPC(const char* /*output*/)
2254 // TODO: handle errors
2256 // now go to the top-most frame
2257 // this also modifies the program counter indicator in the UI
2258 gotoFrame(0);
2261 void KDebugger::slotValueEdited(int row, const QString& text)
2263 if (text.simplifyWhiteSpace().isEmpty())
2264 return; /* no text entered: ignore request */
2266 ASSERT(sender()->inherits("ExprWnd"));
2267 ExprWnd* wnd = const_cast<ExprWnd*>(static_cast<const ExprWnd*>(sender()));
2268 TRACE(QString().sprintf("Changing %s at row %d to ",
2269 wnd->name(), row) + text);
2271 // determine the lvalue to edit
2272 VarTree* expr = static_cast<VarTree*>(wnd->itemAt(row));
2273 QString lvalue = expr->computeExpr();
2274 CmdQueueItem* cmd = m_d->executeCmd(DCsetvariable, lvalue, text);
2275 cmd->m_expr = expr;
2276 cmd->m_exprWnd = wnd;
2279 void KDebugger::handleSetVariable(CmdQueueItem* cmd, const char* output)
2281 QString msg = m_d->parseSetVariable(output);
2282 if (!msg.isEmpty())
2284 // there was an error; display it in the status bar
2285 m_statusMessage = msg;
2286 emit updateStatusMessage();
2287 return;
2290 // get the new value
2291 QString expr = cmd->m_expr->computeExpr();
2292 CmdQueueItem* printCmd =
2293 m_d->queueCmd(DCprint, expr, DebuggerDriver::QMoverrideMoreEqual);
2294 printCmd->m_expr = cmd->m_expr;
2295 printCmd->m_exprWnd = cmd->m_exprWnd;
2299 #include "debugger.moc"