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.
10 #include "typetable.h"
12 #include "pgmsettings.h"
14 #include <qfileinfo.h>
15 #include <q3listbox.h>
16 #include <qstringlist.h>
17 #include <kapplication.h>
19 #include <klocale.h> /* i18n */
20 #include <kmessagebox.h>
23 #include <stdlib.h> /* strtol, atoi */
24 #include <unistd.h> /* sleep(3) */
28 KDebugger::KDebugger(QWidget
* parent
,
31 Q3ListBox
* backtrace
) :
32 QObject(parent
, "debugger"),
34 m_memoryFormat(MDTword
| MDThex
),
35 m_haveExecutable(false),
36 m_programActive(false),
37 m_programRunning(false),
38 m_sharedLibsListed(false),
42 m_localVariables(*localVars
),
43 m_watchVariables(*watchVars
),
44 m_btWindow(*backtrace
)
46 m_envVars
.setAutoDelete(true);
48 connect(&m_localVariables
, SIGNAL(expanded(Q3ListViewItem
*)),
49 SLOT(slotExpanding(Q3ListViewItem
*)));
50 connect(&m_watchVariables
, SIGNAL(expanded(Q3ListViewItem
*)),
51 SLOT(slotExpanding(Q3ListViewItem
*)));
52 connect(&m_localVariables
, SIGNAL(editValueCommitted(VarTree
*, const QString
&)),
53 SLOT(slotValueEdited(VarTree
*, const QString
&)));
54 connect(&m_watchVariables
, SIGNAL(editValueCommitted(VarTree
*, const QString
&)),
55 SLOT(slotValueEdited(VarTree
*, const QString
&)));
57 connect(&m_btWindow
, SIGNAL(highlighted(int)), SLOT(gotoFrame(int)));
62 KDebugger::~KDebugger()
64 if (m_programConfig
!= 0) {
65 saveProgramSettings();
66 m_programConfig
->sync();
67 delete m_programConfig
;
74 void KDebugger::saveSettings(KConfig
* /*config*/)
78 void KDebugger::restoreSettings(KConfig
* /*config*/)
83 //////////////////////////////////////////////////////////////////////
86 const char GeneralGroup
[] = "General";
87 const char DebuggerCmdStr
[] = "DebuggerCmdStr";
88 const char TTYLevelEntry
[] = "TTYLevel";
89 const char KDebugger::DriverNameEntry
[] = "DriverName";
91 bool KDebugger::debugProgram(const QString
& name
,
92 DebuggerDriver
* driver
)
94 if (m_d
!= 0 && m_d
->isRunning())
96 QApplication::setOverrideCursor(Qt::waitCursor
);
100 QApplication::restoreOverrideCursor();
102 if (m_d
->isRunning() || m_haveExecutable
) {
103 /* timed out! We can't really do anything useful now */
104 TRACE("timed out while waiting for gdb to die!");
111 // wire up the driver
112 connect(driver
, SIGNAL(activateFileLine(const QString
&,int,const DbgAddr
&)),
113 this, SIGNAL(activateFileLine(const QString
&,int,const DbgAddr
&)));
114 connect(driver
, SIGNAL(processExited(KProcess
*)), SLOT(gdbExited(KProcess
*)));
115 connect(driver
, SIGNAL(commandReceived(CmdQueueItem
*,const char*)),
116 SLOT(parse(CmdQueueItem
*,const char*)));
117 connect(driver
, SIGNAL(wroteStdin(KProcess
*)), SIGNAL(updateUI()));
118 connect(driver
, SIGNAL(inferiorRunning()), SLOT(slotInferiorRunning()));
119 connect(driver
, SIGNAL(enterIdleState()), SLOT(backgroundUpdate()));
120 connect(driver
, SIGNAL(enterIdleState()), SIGNAL(updateUI()));
121 connect(&m_localVariables
, SIGNAL(removingItem(VarTree
*)),
122 driver
, SLOT(dequeueCmdByVar(VarTree
*)));
123 connect(&m_watchVariables
, SIGNAL(removingItem(VarTree
*)),
124 driver
, SLOT(dequeueCmdByVar(VarTree
*)));
126 // create the program settings object
127 openProgramConfig(name
);
129 // get debugger command from per-program settings
130 if (m_programConfig
!= 0) {
131 m_programConfig
->setGroup(GeneralGroup
);
132 m_debuggerCmd
= readDebuggerCmd();
133 // get terminal emulation level
134 m_ttyLevel
= TTYLevel(m_programConfig
->readNumEntry(TTYLevelEntry
, ttyFull
));
136 // the rest is read in later in the handler of DCexecutable
140 if (!startDriver()) {
141 TRACE("startDriver failed");
146 TRACE("before file cmd");
147 m_d
->executeCmd(DCexecutable
, name
);
151 if (!m_remoteDevice
.isEmpty()) {
152 m_d
->executeCmd(DCtargetremote
, m_remoteDevice
);
153 m_d
->queueCmd(DCbt
, DebuggerDriver::QMoverride
);
154 m_d
->queueCmd(DCframe
, 0, DebuggerDriver::QMnormal
);
155 m_programActive
= true;
156 m_haveExecutable
= true;
159 // create a type table
160 m_typeTable
= new ProgramTypeTable
;
161 m_sharedLibsListed
= false;
168 void KDebugger::shutdown()
170 // shut down debugger driver
171 if (m_d
!= 0 && m_d
->isRunning())
177 void KDebugger::useCoreFile(QString corefile
, bool batch
)
179 m_corefile
= corefile
;
181 CmdQueueItem
* cmd
= loadCoreFile();
182 cmd
->m_byUser
= true;
186 void KDebugger::setAttachPid(const QString
& pid
)
191 void KDebugger::programRun()
196 // when program is active, but not a core file, continue
197 // otherwise run the program
198 if (m_programActive
&& m_corefile
.isEmpty()) {
199 // gdb command: continue
200 m_d
->executeCmd(DCcont
, true);
203 m_d
->executeCmd(DCrun
, true);
204 m_corefile
= QString();
205 m_programActive
= true;
207 m_programRunning
= true;
210 void KDebugger::attachProgram(const QString
& pid
)
216 TRACE("Attaching to " + m_attachedPid
);
217 m_d
->executeCmd(DCattach
, m_attachedPid
);
218 m_programActive
= true;
219 m_programRunning
= true;
222 void KDebugger::programRunAgain()
224 if (canSingleStep()) {
225 m_d
->executeCmd(DCrun
, true);
226 m_corefile
= QString();
227 m_programRunning
= true;
231 void KDebugger::programStep()
233 if (canSingleStep()) {
234 m_d
->executeCmd(DCstep
, true);
235 m_programRunning
= true;
239 void KDebugger::programNext()
241 if (canSingleStep()) {
242 m_d
->executeCmd(DCnext
, true);
243 m_programRunning
= true;
247 void KDebugger::programStepi()
249 if (canSingleStep()) {
250 m_d
->executeCmd(DCstepi
, true);
251 m_programRunning
= true;
255 void KDebugger::programNexti()
257 if (canSingleStep()) {
258 m_d
->executeCmd(DCnexti
, true);
259 m_programRunning
= true;
263 void KDebugger::programFinish()
265 if (canSingleStep()) {
266 m_d
->executeCmd(DCfinish
, true);
267 m_programRunning
= true;
271 void KDebugger::programKill()
273 if (haveExecutable() && isProgramActive()) {
274 if (m_programRunning
) {
275 m_d
->interruptInferior();
277 // this is an emergency command; flush queues
278 m_d
->flushCommands(true);
279 m_d
->executeCmd(DCkill
, true);
283 bool KDebugger::runUntil(const QString
& fileName
, int lineNo
)
285 if (isReady() && m_programActive
&& !m_programRunning
) {
286 // strip off directory part of file name
287 QString file
= fileName
;
288 int offset
= file
.findRev("/");
290 file
.remove(0, offset
+1);
292 m_d
->executeCmd(DCuntil
, file
, lineNo
, true);
293 m_programRunning
= true;
300 void KDebugger::programBreak()
302 if (m_haveExecutable
&& m_programRunning
) {
303 m_d
->interruptInferior();
307 void KDebugger::programArgs(QWidget
* parent
)
309 if (m_haveExecutable
) {
310 QStringList allOptions
= m_d
->boolOptionList();
311 PgmArgs
dlg(parent
, m_executable
, m_envVars
, allOptions
);
312 dlg
.setArgs(m_programArgs
);
313 dlg
.setWd(m_programWD
);
314 dlg
.setOptions(m_boolOptions
);
316 updateProgEnvironment(dlg
.args(), dlg
.wd(),
317 dlg
.envVars(), dlg
.options());
322 void KDebugger::programSettings(QWidget
* parent
)
324 if (!m_haveExecutable
)
327 ProgramSettings
dlg(parent
, m_executable
);
329 dlg
.m_chooseDriver
.setDebuggerCmd(m_debuggerCmd
);
330 dlg
.m_output
.setTTYLevel(m_ttyLevel
);
332 if (dlg
.exec() == QDialog::Accepted
)
334 m_debuggerCmd
= dlg
.m_chooseDriver
.debuggerCmd();
335 m_ttyLevel
= TTYLevel(dlg
.m_output
.ttyLevel());
339 bool KDebugger::setBreakpoint(QString file
, int lineNo
,
340 const DbgAddr
& address
, bool temporary
)
346 BrkptIterator bp
= breakpointByFilePos(file
, lineNo
, address
);
347 if (bp
== m_brkpts
.end())
350 * No such breakpoint, so set a new one. If we have an address, we
351 * set the breakpoint exactly there. Otherwise we use the file name
354 Breakpoint
* bp
= new Breakpoint
;
355 bp
->temporary
= temporary
;
357 if (address
.isEmpty())
364 bp
->address
= address
;
366 setBreakpoint(bp
, false);
371 * If the breakpoint is disabled, enable it; if it's enabled,
372 * delete that breakpoint.
375 deleteBreakpoint(bp
);
377 enableDisableBreakpoint(bp
);
383 void KDebugger::setBreakpoint(Breakpoint
* bp
, bool queueOnly
)
385 CmdQueueItem
* cmd
= executeBreakpoint(bp
, queueOnly
);
386 cmd
->m_brkpt
= bp
; // used in newBreakpoint()
389 CmdQueueItem
* KDebugger::executeBreakpoint(const Breakpoint
* bp
, bool queueOnly
)
392 if (!bp
->text
.isEmpty())
395 * The breakpoint was set using the text box in the breakpoint
396 * list. This is the only way in which watchpoints are set.
398 if (bp
->type
== Breakpoint::watchpoint
) {
399 cmd
= m_d
->executeCmd(DCwatchpoint
, bp
->text
);
401 cmd
= m_d
->executeCmd(DCbreaktext
, bp
->text
);
404 else if (bp
->address
.isEmpty())
406 // strip off directory part of file name
407 QString file
= bp
->fileName
;
408 int offset
= file
.findRev("/");
410 file
.remove(0, offset
+1);
413 cmd
= m_d
->queueCmd(bp
->temporary
? DCtbreakline
: DCbreakline
,
414 file
, bp
->lineNo
, DebuggerDriver::QMoverride
);
416 cmd
= m_d
->executeCmd(bp
->temporary
? DCtbreakline
: DCbreakline
,
423 cmd
= m_d
->queueCmd(bp
->temporary
? DCtbreakaddr
: DCbreakaddr
,
424 bp
->address
.asString(), DebuggerDriver::QMoverride
);
426 cmd
= m_d
->executeCmd(bp
->temporary
? DCtbreakaddr
: DCbreakaddr
,
427 bp
->address
.asString());
433 bool KDebugger::infoLine(QString file
, int lineNo
, const DbgAddr
& addr
)
435 if (isReady() && !m_programRunning
) {
436 CmdQueueItem
* cmd
= m_d
->executeCmd(DCinfoline
, file
, lineNo
);
444 bool KDebugger::enableDisableBreakpoint(QString file
, int lineNo
,
445 const DbgAddr
& address
)
447 BrkptIterator bp
= breakpointByFilePos(file
, lineNo
, address
);
448 return enableDisableBreakpoint(bp
);
451 bool KDebugger::enableDisableBreakpoint(BrkptIterator bp
)
453 if (bp
== m_brkpts
.end())
457 * Toggle enabled/disabled state.
459 * The driver is not bothered if we are modifying an orphaned
462 if (!bp
->isOrphaned()) {
463 if (!canChangeBreakpoints()) {
466 m_d
->executeCmd(bp
->enabled
? DCdisable
: DCenable
, bp
->id
);
468 bp
->enabled
= !bp
->enabled
;
469 emit
breakpointsChanged();
474 bool KDebugger::conditionalBreakpoint(BrkptIterator bp
,
475 const QString
& condition
,
478 if (bp
== m_brkpts
.end())
482 * Change the condition and ignore count.
484 * The driver is not bothered if we are removing an orphaned
488 if (!bp
->isOrphaned()) {
489 if (!canChangeBreakpoints()) {
493 bool changed
= false;
495 if (bp
->condition
!= condition
) {
497 m_d
->executeCmd(DCcondition
, condition
, bp
->id
);
500 if (bp
->ignoreCount
!= ignoreCount
) {
501 // change ignore count
502 m_d
->executeCmd(DCignore
, bp
->id
, ignoreCount
);
507 m_d
->queueCmd(DCinfobreak
, DebuggerDriver::QMoverride
);
510 bp
->condition
= condition
;
511 bp
->ignoreCount
= ignoreCount
;
512 emit
breakpointsChanged();
517 bool KDebugger::deleteBreakpoint(BrkptIterator bp
)
519 if (bp
== m_brkpts
.end())
523 * Remove the breakpoint.
525 * The driver is not bothered if we are removing an orphaned
528 if (!bp
->isOrphaned()) {
529 if (!canChangeBreakpoints()) {
532 m_d
->executeCmd(DCdelete
, bp
->id
);
535 emit
breakpointsChanged();
540 bool KDebugger::canSingleStep()
542 return isReady() && m_programActive
&& !m_programRunning
;
545 bool KDebugger::canChangeBreakpoints()
547 return isReady() && !m_programRunning
;
550 bool KDebugger::canStart()
552 return isReady() && !m_programActive
;
555 bool KDebugger::isReady() const
557 return m_haveExecutable
&&
558 m_d
!= 0 && m_d
->canExecuteImmediately();
561 bool KDebugger::isIdle() const
563 return m_d
== 0 || m_d
->isIdle();
567 //////////////////////////////////////////////////////////
570 bool KDebugger::startDriver()
572 emit
debuggerStarting(); /* must set m_inferiorTerminal */
575 * If the per-program command string is empty, use the global setting
576 * (which might also be empty, in which case the driver uses its
579 m_explicitKill
= false;
580 if (!m_d
->startup(m_debuggerCmd
)) {
585 * If we have an output terminal, we use it. Otherwise we will run the
586 * program with input and output redirected to /dev/null. Other
587 * redirections are also necessary depending on the tty emulation
590 int redirect
= RDNstdin
|RDNstdout
|RDNstderr
; /* redirect everything */
591 if (!m_inferiorTerminal
.isEmpty()) {
592 switch (m_ttyLevel
) {
595 // redirect everything
597 case ttySimpleOutputOnly
:
605 m_d
->executeCmd(DCtty
, m_inferiorTerminal
, redirect
);
610 void KDebugger::stopDriver()
612 m_explicitKill
= true;
614 if (m_attachedPid
.isEmpty()) {
617 m_d
->detachAndTerminate();
621 * We MUST wait until the slot gdbExited() has been called. But to
622 * avoid a deadlock, we wait only for some certain maximum time. Should
623 * this timeout be reached, the only reasonable thing one could do then
626 kapp
->processEvents(1000); /* ideally, this will already shut it down */
627 int maxTime
= 20; /* about 20 seconds */
628 while (m_haveExecutable
&& maxTime
> 0) {
629 // give gdb time to die (and send a SIGCLD)
632 kapp
->processEvents(1000);
636 void KDebugger::gdbExited(KProcess
*)
639 * Save settings, but only if gdb has already processed "info line
640 * main", otherwise we would save an empty config file, because it
641 * isn't read in until then!
643 if (m_programConfig
!= 0) {
644 if (m_haveExecutable
) {
645 saveProgramSettings();
646 m_programConfig
->sync();
648 delete m_programConfig
;
656 if (m_explicitKill
) {
657 TRACE(m_d
->driverName() + " exited normally");
659 QString msg
= i18n("%1 exited unexpectedly.\n"
660 "Restart the session (e.g. with File|Executable).");
661 KMessageBox::error(parentWidget(), msg
.arg(m_d
->driverName()));
665 m_haveExecutable
= false;
667 m_programActive
= false;
668 m_programRunning
= false;
669 m_explicitKill
= false;
670 m_debuggerCmd
= QString(); /* use global setting at next start! */
671 m_attachedPid
= QString(); /* we are no longer attached to a process */
672 m_ttyLevel
= ttyFull
;
676 emit
updatePC(QString(), -1, DbgAddr(), 0);
679 QString
KDebugger::getConfigForExe(const QString
& name
)
682 QString pgmConfigFile
= fi
.dirPath(true);
683 if (!pgmConfigFile
.isEmpty()) {
684 pgmConfigFile
+= '/';
686 pgmConfigFile
+= ".kdbgrc." + fi
.fileName();
687 TRACE("program config file = " + pgmConfigFile
);
688 return pgmConfigFile
;
691 void KDebugger::openProgramConfig(const QString
& name
)
693 ASSERT(m_programConfig
== 0);
695 QString pgmConfigFile
= getConfigForExe(name
);
697 m_programConfig
= new KConfig(pgmConfigFile
);
700 const char EnvironmentGroup
[] = "Environment";
701 const char WatchGroup
[] = "Watches";
702 const char FileVersion
[] = "FileVersion";
703 const char ProgramArgs
[] = "ProgramArgs";
704 const char WorkingDirectory
[] = "WorkingDirectory";
705 const char OptionsSelected
[] = "OptionsSelected";
706 const char Variable
[] = "Var%d";
707 const char Value
[] = "Value%d";
708 const char ExprFmt
[] = "Expr%d";
710 void KDebugger::saveProgramSettings()
712 ASSERT(m_programConfig
!= 0);
713 m_programConfig
->setGroup(GeneralGroup
);
714 m_programConfig
->writeEntry(FileVersion
, 1);
715 m_programConfig
->writeEntry(ProgramArgs
, m_programArgs
);
716 m_programConfig
->writeEntry(WorkingDirectory
, m_programWD
);
717 m_programConfig
->writeEntry(OptionsSelected
, m_boolOptions
);
718 m_programConfig
->writeEntry(DebuggerCmdStr
, m_debuggerCmd
);
719 m_programConfig
->writeEntry(TTYLevelEntry
, int(m_ttyLevel
));
722 driverName
= m_d
->driverName();
723 m_programConfig
->writeEntry(DriverNameEntry
, driverName
);
725 // write environment variables
726 m_programConfig
->deleteGroup(EnvironmentGroup
);
727 m_programConfig
->setGroup(EnvironmentGroup
);
728 Q3DictIterator
<EnvVar
> it
= m_envVars
;
732 for (int i
= 0; (var
= it
) != 0; ++it
, ++i
) {
733 varName
.sprintf(Variable
, i
);
734 varValue
.sprintf(Value
, i
);
735 m_programConfig
->writeEntry(varName
, it
.currentKey());
736 m_programConfig
->writeEntry(varValue
, var
->value
);
739 saveBreakpoints(m_programConfig
);
742 // first get rid of whatever was in this group
743 m_programConfig
->deleteGroup(WatchGroup
);
744 // then start a new group
745 m_programConfig
->setGroup(WatchGroup
);
746 VarTree
* item
= m_watchVariables
.firstChild();
748 for (; item
!= 0; item
= item
->nextSibling(), ++watchNum
) {
749 varName
.sprintf(ExprFmt
, watchNum
);
750 m_programConfig
->writeEntry(varName
, item
->getText());
753 // give others a chance
754 emit
saveProgramSpecific(m_programConfig
);
757 void KDebugger::overrideProgramArguments(const QString
& args
)
759 ASSERT(m_programConfig
!= 0);
760 m_programConfig
->setGroup(GeneralGroup
);
761 m_programConfig
->writeEntry(ProgramArgs
, args
);
764 void KDebugger::restoreProgramSettings()
766 ASSERT(m_programConfig
!= 0);
767 m_programConfig
->setGroup(GeneralGroup
);
769 * We ignore file version for now we will use it in the future to
770 * distinguish different versions of this configuration file.
772 // m_debuggerCmd has been read in already
773 // m_ttyLevel has been read in already
774 QString pgmArgs
= m_programConfig
->readEntry(ProgramArgs
);
775 QString pgmWd
= m_programConfig
->readEntry(WorkingDirectory
);
776 QStringList boolOptions
= m_programConfig
->readListEntry(OptionsSelected
);
777 m_boolOptions
= QStringList();
779 // read environment variables
780 m_programConfig
->setGroup(EnvironmentGroup
);
782 Q3Dict
<EnvVar
> pgmVars
;
786 for (int i
= 0;; ++i
) {
787 varName
.sprintf(Variable
, i
);
788 varValue
.sprintf(Value
, i
);
789 if (!m_programConfig
->hasKey(varName
)) {
790 /* entry not present, assume that we've hit them all */
793 QString name
= m_programConfig
->readEntry(varName
);
794 if (name
.isEmpty()) {
799 var
->value
= m_programConfig
->readEntry(varValue
);
800 var
->status
= EnvVar::EVnew
;
801 pgmVars
.insert(name
, var
);
804 updateProgEnvironment(pgmArgs
, pgmWd
, pgmVars
, boolOptions
);
806 restoreBreakpoints(m_programConfig
);
809 m_programConfig
->setGroup(WatchGroup
);
810 m_watchVariables
.clear();
811 for (int i
= 0;; ++i
) {
812 varName
.sprintf(ExprFmt
, i
);
813 if (!m_programConfig
->hasKey(varName
)) {
814 /* entry not present, assume that we've hit them all */
817 QString expr
= m_programConfig
->readEntry(varName
);
818 if (expr
.isEmpty()) {
819 // skip empty expressions
825 // give others a chance
826 emit
restoreProgramSpecific(m_programConfig
);
830 * Reads the debugger command line from the program settings. The config
831 * group must have been set by the caller.
833 QString
KDebugger::readDebuggerCmd()
835 QString debuggerCmd
= m_programConfig
->readEntry(DebuggerCmdStr
);
837 // always let the user confirm the debugger cmd if we are root
838 if (::geteuid() == 0)
840 if (!debuggerCmd
.isEmpty()) {
842 "The settings for this program specify "
843 "the following debugger command:\n%1\n"
844 "Shall this command be used?");
845 if (KMessageBox::warningYesNo(parentWidget(), msg
.arg(debuggerCmd
))
849 debuggerCmd
= QString();
857 * Breakpoints are saved one per group.
859 const char BPGroup
[] = "Breakpoint %d";
860 const char File
[] = "File";
861 const char Line
[] = "Line";
862 const char Text
[] = "Text";
863 const char Address
[] = "Address";
864 const char Temporary
[] = "Temporary";
865 const char Enabled
[] = "Enabled";
866 const char Condition
[] = "Condition";
868 void KDebugger::saveBreakpoints(KConfig
* config
)
872 for (BrkptIterator bp
= m_brkpts
.begin(); bp
!= m_brkpts
.end(); ++bp
)
874 if (bp
->type
== Breakpoint::watchpoint
)
875 continue; /* don't save watchpoints */
876 groupName
.sprintf(BPGroup
, i
++);
878 /* remove remmants */
879 config
->deleteGroup(groupName
);
881 config
->setGroup(groupName
);
882 if (!bp
->text
.isEmpty()) {
884 * The breakpoint was set using the text box in the breakpoint
885 * list. We do not save the location by filename+line number,
886 * but instead honor what the user typed (a function name, for
887 * example, which could move between sessions).
889 config
->writeEntry(Text
, bp
->text
);
890 } else if (!bp
->fileName
.isEmpty()) {
891 config
->writeEntry(File
, bp
->fileName
);
892 config
->writeEntry(Line
, bp
->lineNo
);
894 * Addresses are hardly correct across sessions, so we don't
898 config
->writeEntry(Address
, bp
->address
.asString());
900 config
->writeEntry(Temporary
, bp
->temporary
);
901 config
->writeEntry(Enabled
, bp
->enabled
);
902 if (!bp
->condition
.isEmpty())
903 config
->writeEntry(Condition
, bp
->condition
);
904 // we do not save the ignore count
906 // delete remaining groups
907 // we recognize that a group is present if there is an Enabled entry
909 groupName
.sprintf(BPGroup
, i
);
910 config
->setGroup(groupName
);
911 if (!config
->hasKey(Enabled
)) {
912 /* group not present, assume that we've hit them all */
915 config
->deleteGroup(groupName
);
919 void KDebugger::restoreBreakpoints(KConfig
* config
)
923 * We recognize the end of the list if there is no Enabled entry
926 for (int i
= 0;; i
++) {
927 groupName
.sprintf(BPGroup
, i
);
928 config
->setGroup(groupName
);
929 if (!config
->hasKey(Enabled
)) {
930 /* group not present, assume that we've hit them all */
933 Breakpoint
* bp
= new Breakpoint
;
934 bp
->fileName
= config
->readEntry(File
);
935 bp
->lineNo
= config
->readNumEntry(Line
, -1);
936 bp
->text
= config
->readEntry(Text
);
937 bp
->address
= config
->readEntry(Address
);
939 if ((bp
->fileName
.isEmpty() || bp
->lineNo
< 0) &&
940 bp
->text
.isEmpty() &&
941 bp
->address
.isEmpty())
946 bp
->enabled
= config
->readBoolEntry(Enabled
, true);
947 bp
->temporary
= config
->readBoolEntry(Temporary
, false);
948 bp
->condition
= config
->readEntry(Condition
);
951 * Add the breakpoint.
953 setBreakpoint(bp
, false);
954 // the new breakpoint is disabled or conditionalized later
955 // in newBreakpoint()
957 m_d
->queueCmd(DCinfobreak
, DebuggerDriver::QMoverride
);
961 // parse output of command cmd
962 void KDebugger::parse(CmdQueueItem
* cmd
, const char* output
)
964 ASSERT(cmd
!= 0); /* queue mustn't be empty */
966 TRACE(QString(__PRETTY_FUNCTION__
) + " parsing " + output
);
968 switch (cmd
->m_cmd
) {
970 // the output (if any) is uninteresting
973 // there is no output
977 /* if value is empty, we see output, but we don't care */
980 /* display gdb's message in the status bar */
981 m_d
->parseChangeWD(output
, m_statusMessage
);
982 emit
updateStatusMessage();
987 if (m_d
->parseChangeExecutable(output
, m_statusMessage
))
989 // success; restore breakpoints etc.
990 if (m_programConfig
!= 0) {
991 restoreProgramSettings();
993 // load file containing main() or core file
994 if (!m_corefile
.isEmpty())
999 else if (!m_attachedPid
.isEmpty())
1001 m_d
->queueCmd(DCattach
, m_attachedPid
, DebuggerDriver::QMoverride
);
1002 m_programActive
= true;
1003 m_programRunning
= true;
1005 else if (!m_remoteDevice
.isEmpty())
1007 // handled elsewhere
1011 m_d
->queueCmd(DCinfolinemain
, DebuggerDriver::QMnormal
);
1013 if (!m_statusMessage
.isEmpty())
1014 emit
updateStatusMessage();
1016 QString msg
= m_d
->driverName() + ": " + m_statusMessage
;
1017 KMessageBox::sorry(parentWidget(), msg
);
1019 m_corefile
= ""; /* don't process core file */
1020 m_haveExecutable
= false;
1024 // in any event we have an executable at this point
1025 m_haveExecutable
= true;
1026 if (m_d
->parseCoreFile(output
)) {
1027 // loading a core is like stopping at a breakpoint
1028 m_programActive
= true;
1029 handleRunCommands(output
);
1030 // do not reset m_corefile
1033 QString msg
= m_d
->driverName() + ": " + QString(output
);
1034 KMessageBox::sorry(parentWidget(), msg
);
1036 // if core file was loaded from command line, revert to info line main
1037 if (!cmd
->m_byUser
) {
1038 m_d
->queueCmd(DCinfolinemain
, DebuggerDriver::QMnormal
);
1040 m_corefile
= QString(); /* core file not available any more */
1043 case DCinfolinemain
:
1044 // ignore the output, marked file info follows
1045 m_haveExecutable
= true;
1048 // parse local variables
1049 if (output
[0] != '\0') {
1050 handleLocals(output
);
1053 case DCinforegisters
:
1054 handleRegisters(output
);
1057 handleMemoryDump(output
);
1060 handleInfoLine(cmd
, output
);
1063 handleDisassemble(cmd
, output
);
1066 handleFrameChange(output
);
1070 handleBacktrace(output
);
1074 handlePrint(cmd
, output
);
1077 handlePrintDeref(cmd
, output
);
1080 m_haveExecutable
= true;
1091 handleRunCommands(output
);
1094 m_programRunning
= m_programActive
= false;
1096 emit
updatePC(QString(), -1, DbgAddr(), 0);
1104 newBreakpoint(cmd
, output
);
1109 // these commands need immediate response
1110 m_d
->queueCmd(DCinfobreak
, DebuggerDriver::QMoverrideMoreEqual
);
1113 // note: this handler must not enqueue a command, since
1114 // DCinfobreak is used at various different places.
1115 updateBreakList(output
);
1118 handleFindType(cmd
, output
);
1121 case DCprintQStringStruct
:
1123 handlePrintStruct(cmd
, output
);
1125 case DCinfosharedlib
:
1126 handleSharedLibs(output
);
1130 // we are not interested in the output
1133 handleThreadList(output
);
1136 handleSetPC(output
);
1139 handleSetVariable(cmd
, output
);
1144 void KDebugger::backgroundUpdate()
1147 * If there are still expressions that need to be updated, then do so.
1149 if (m_programActive
)
1153 void KDebugger::handleRunCommands(const char* output
)
1155 uint flags
= m_d
->parseProgramStopped(output
, m_statusMessage
);
1156 emit
updateStatusMessage();
1158 m_programActive
= flags
& DebuggerDriver::SFprogramActive
;
1160 // refresh files if necessary
1161 if (flags
& DebuggerDriver::SFrefreshSource
) {
1162 TRACE("re-reading files");
1163 emit
executableUpdated();
1167 * Try to set any orphaned breakpoints now.
1169 for (BrkptIterator bp
= m_brkpts
.begin(); bp
!= m_brkpts
.end(); ++bp
)
1171 if (bp
->isOrphaned()) {
1172 TRACE(QString("re-trying brkpt loc: %2 file: %3 line: %1")
1173 .arg(bp
->lineNo
).arg(bp
->location
, bp
->fileName
));
1174 CmdQueueItem
* cmd
= executeBreakpoint(&*bp
, true);
1175 cmd
->m_existingBrkpt
= bp
->id
; // used in newBreakpoint()
1176 flags
|= DebuggerDriver::SFrefreshBreak
;
1181 * If we stopped at a breakpoint, we must update the breakpoint list
1182 * because the hit count changes. Also, if the breakpoint was temporary
1183 * it would go away now.
1185 if ((flags
& (DebuggerDriver::SFrefreshBreak
|DebuggerDriver::SFrefreshSource
)) ||
1186 stopMayChangeBreakList())
1188 m_d
->queueCmd(DCinfobreak
, DebuggerDriver::QMoverride
);
1192 * If we haven't listed the shared libraries yet, do so. We must do
1193 * this before we emit any commands that list variables, since the type
1194 * libraries depend on the shared libraries.
1196 if (!m_sharedLibsListed
) {
1197 // must be a high-priority command!
1198 m_d
->executeCmd(DCinfosharedlib
);
1201 // get the backtrace if the program is running
1202 if (m_programActive
) {
1203 m_d
->queueCmd(DCbt
, DebuggerDriver::QMoverride
);
1205 // program finished: erase PC
1206 emit
updatePC(QString(), -1, DbgAddr(), 0);
1207 // dequeue any commands in the queues
1208 m_d
->flushCommands();
1211 /* Update threads list */
1212 if (m_programActive
&& (flags
& DebuggerDriver::SFrefreshThreads
)) {
1213 m_d
->queueCmd(DCinfothreads
, DebuggerDriver::QMoverride
);
1216 m_programRunning
= false;
1217 emit
programStopped();
1220 void KDebugger::slotInferiorRunning()
1222 m_programRunning
= true;
1225 void KDebugger::updateAllExprs()
1227 if (!m_programActive
)
1230 // retrieve local variables
1231 m_d
->queueCmd(DCinfolocals
, DebuggerDriver::QMoverride
);
1233 // retrieve registers
1234 m_d
->queueCmd(DCinforegisters
, DebuggerDriver::QMoverride
);
1236 // get new memory dump
1237 if (!m_memoryExpression
.isEmpty()) {
1238 queueMemoryDump(false);
1241 // update watch expressions
1242 VarTree
* item
= m_watchVariables
.firstChild();
1243 for (; item
!= 0; item
= item
->nextSibling()) {
1244 m_watchEvalExpr
.push_back(item
->getText());
1248 void KDebugger::updateProgEnvironment(const QString
& args
, const QString
& wd
,
1249 const Q3Dict
<EnvVar
>& newVars
,
1250 const QStringList
& newOptions
)
1252 m_programArgs
= args
;
1253 m_d
->executeCmd(DCsetargs
, m_programArgs
);
1254 TRACE("new pgm args: " + m_programArgs
+ "\n");
1256 m_programWD
= wd
.stripWhiteSpace();
1257 if (!m_programWD
.isEmpty()) {
1258 m_d
->executeCmd(DCcd
, m_programWD
);
1259 TRACE("new wd: " + m_programWD
+ "\n");
1262 // update environment variables
1263 Q3DictIterator
<EnvVar
> it
= newVars
;
1265 for (; (val
= it
) != 0; ++it
) {
1266 QString var
= it
.currentKey();
1267 switch (val
->status
) {
1269 m_envVars
.insert(var
, val
);
1271 case EnvVar::EVdirty
:
1272 // the value must be in our list
1273 ASSERT(m_envVars
[var
] == val
);
1275 m_d
->executeCmd(DCsetenv
, var
, val
->value
);
1277 case EnvVar::EVdeleted
:
1278 // must be in our list
1279 ASSERT(m_envVars
[var
] == val
);
1281 m_d
->executeCmd(DCunsetenv
, var
);
1282 m_envVars
.remove(var
);
1286 case EnvVar::EVclean
:
1287 // variable not changed
1293 QStringList::ConstIterator oi
;
1294 for (oi
= newOptions
.begin(); oi
!= newOptions
.end(); ++oi
)
1296 if (m_boolOptions
.findIndex(*oi
) < 0) {
1297 // the options is currently not set, so set it
1298 m_d
->executeCmd(DCsetoption
, *oi
, 1);
1300 // option is set, no action required, but move it to the end
1301 m_boolOptions
.remove(*oi
);
1303 m_boolOptions
.append(*oi
);
1306 * Now all options that should be set are at the end of m_boolOptions.
1307 * If some options need to be unset, they are at the front of the list.
1308 * Here we unset and remove them.
1310 while (m_boolOptions
.count() > newOptions
.count()) {
1311 m_d
->executeCmd(DCsetoption
, m_boolOptions
.first(), 0);
1312 m_boolOptions
.remove(m_boolOptions
.begin());
1316 void KDebugger::handleLocals(const char* output
)
1318 // retrieve old list of local variables
1319 QStringList oldVars
= m_localVariables
.exprList();
1322 * Get local variables.
1324 std::list
<ExprValue
*> newVars
;
1325 parseLocals(output
, newVars
);
1328 * Clear any old VarTree item pointers, so that later we don't access
1329 * dangling pointers.
1331 m_localVariables
.clearPendingUpdates();
1334 * Match old variables against new ones.
1336 for (QStringList::ConstIterator n
= oldVars
.begin(); n
!= oldVars
.end(); ++n
) {
1337 // lookup this variable in the list of new variables
1338 std::list
<ExprValue
*>::iterator v
= newVars
.begin();
1339 while (v
!= newVars
.end() && (*v
)->m_name
!= *n
)
1341 if (v
== newVars
.end()) {
1342 // old variable not in the new variables
1343 TRACE("old var deleted: " + *n
);
1344 VarTree
* v
= m_localVariables
.topLevelExprByName(*n
);
1346 m_localVariables
.removeExpr(v
);
1349 // variable in both old and new lists: update
1350 TRACE("update var: " + *n
);
1351 m_localVariables
.updateExpr(*v
, *m_typeTable
);
1352 // remove the new variable from the list
1357 // insert all remaining new variables
1358 while (!newVars
.empty())
1360 ExprValue
* v
= newVars
.front();
1361 TRACE("new var: " + v
->m_name
);
1362 m_localVariables
.insertExpr(v
, *m_typeTable
);
1364 newVars
.pop_front();
1368 void KDebugger::parseLocals(const char* output
, std::list
<ExprValue
*>& newVars
)
1370 std::list
<ExprValue
*> vars
;
1371 m_d
->parseLocals(output
, vars
);
1373 QString origName
; /* used in renaming variables */
1374 while (!vars
.empty())
1376 ExprValue
* variable
= vars
.front();
1379 * When gdb prints local variables, those from the innermost block
1380 * come first. We run through the list of already parsed variables
1381 * to find duplicates (ie. variables that hide local variables from
1382 * a surrounding block). We keep the name of the inner variable, but
1383 * rename those from the outer block so that, when the value is
1384 * updated in the window, the value of the variable that is
1385 * _visible_ changes the color!
1388 origName
= variable
->m_name
;
1389 for (std::list
<ExprValue
*>::iterator v
= newVars
.begin(); v
!= newVars
.end(); ++v
) {
1390 if (variable
->m_name
== (*v
)->m_name
) {
1391 // we found a duplicate, change name
1393 QString newName
= origName
+ " (" + QString().setNum(block
) + ")";
1394 variable
->m_name
= newName
;
1397 newVars
.push_back(variable
);
1401 bool KDebugger::handlePrint(CmdQueueItem
* cmd
, const char* output
)
1403 ASSERT(cmd
->m_expr
!= 0);
1405 ExprValue
* variable
= m_d
->parsePrintExpr(output
, true);
1409 // set expression "name"
1410 variable
->m_name
= cmd
->m_expr
->getText();
1413 TRACE("update expr: " + cmd
->m_expr
->getText());
1414 cmd
->m_exprWnd
->updateExpr(cmd
->m_expr
, variable
, *m_typeTable
);
1418 evalExpressions(); /* enqueue dereferenced pointers */
1423 bool KDebugger::handlePrintDeref(CmdQueueItem
* cmd
, const char* output
)
1425 ASSERT(cmd
->m_expr
!= 0);
1427 ExprValue
* variable
= m_d
->parsePrintExpr(output
, true);
1431 // set expression "name"
1432 variable
->m_name
= cmd
->m_expr
->getText();
1436 * We must insert a dummy parent, because otherwise variable's value
1437 * would overwrite cmd->m_expr's value.
1439 ExprValue
* dummyParent
= new ExprValue(variable
->m_name
, VarTree::NKplain
);
1440 dummyParent
->m_varKind
= VarTree::VKdummy
;
1441 // the name of the parsed variable is the address of the pointer
1442 QString addr
= "*" + cmd
->m_expr
->value();
1443 variable
->m_name
= addr
;
1444 variable
->m_nameKind
= VarTree::NKaddress
;
1446 dummyParent
->m_child
= variable
;
1447 // expand the first level for convenience
1448 variable
->m_initiallyExpanded
= true;
1449 TRACE("update ptr: " + cmd
->m_expr
->getText());
1450 cmd
->m_exprWnd
->updateExpr(cmd
->m_expr
, dummyParent
, *m_typeTable
);
1454 evalExpressions(); /* enqueue dereferenced pointers */
1459 // parse the output of bt
1460 void KDebugger::handleBacktrace(const char* output
)
1463 m_btWindow
.setAutoUpdate(false);
1467 std::list
<StackFrame
> stack
;
1468 m_d
->parseBackTrace(output
, stack
);
1470 if (!stack
.empty()) {
1471 std::list
<StackFrame
>::iterator frm
= stack
.begin();
1472 // first frame must set PC
1473 // note: frm->lineNo is zero-based
1474 emit
updatePC(frm
->fileName
, frm
->lineNo
, frm
->address
, frm
->frameNo
);
1476 for (; frm
!= stack
.end(); ++frm
) {
1479 func
= frm
->var
->m_name
;
1481 func
= frm
->fileName
+ ":" + QString().setNum(frm
->lineNo
+1);
1482 m_btWindow
.insertItem(func
);
1483 TRACE("frame " + func
+ " (" + frm
->fileName
+ ":" +
1484 QString().setNum(frm
->lineNo
+1) + ")");
1488 m_btWindow
.setAutoUpdate(true);
1489 m_btWindow
.repaint();
1492 void KDebugger::gotoFrame(int frame
)
1494 m_d
->executeCmd(DCframe
, frame
);
1497 void KDebugger::handleFrameChange(const char* output
)
1503 if (m_d
->parseFrameChange(output
, frameNo
, fileName
, lineNo
, address
)) {
1504 /* lineNo can be negative here if we can't find a file name */
1505 emit
updatePC(fileName
, lineNo
, address
, frameNo
);
1507 emit
updatePC(fileName
, -1, address
, frameNo
);
1511 void KDebugger::evalExpressions()
1513 // evaluate expressions in the following order:
1514 // watch expressions
1515 // pointers in local variables
1516 // pointers in watch expressions
1517 // types in local variables
1518 // types in watch expressions
1519 // struct members in local variables
1520 // struct members in watch expressions
1521 VarTree
* exprItem
= 0;
1522 if (!m_watchEvalExpr
.empty())
1524 QString expr
= m_watchEvalExpr
.front();
1525 m_watchEvalExpr
.pop_front();
1526 exprItem
= m_watchVariables
.topLevelExprByName(expr
);
1528 if (exprItem
!= 0) {
1529 CmdQueueItem
* cmd
= m_d
->queueCmd(DCprint
, exprItem
->getText(), DebuggerDriver::QMoverride
);
1530 // remember which expr this was
1531 cmd
->m_expr
= exprItem
;
1532 cmd
->m_exprWnd
= &m_watchVariables
;
1535 #define POINTER(widget) \
1537 exprItem = widget.nextUpdatePtr(); \
1538 if (exprItem != 0) goto pointer
1539 #define STRUCT(widget) \
1541 exprItem = widget.nextUpdateStruct(); \
1542 if (exprItem != 0) goto ustruct
1543 #define TYPE(widget) \
1545 exprItem = widget.nextUpdateType(); \
1546 if (exprItem != 0) goto type
1548 POINTER(m_localVariables
);
1549 POINTER(m_watchVariables
);
1550 STRUCT(m_localVariables
);
1551 STRUCT(m_watchVariables
);
1552 TYPE(m_localVariables
);
1553 TYPE(m_watchVariables
);
1560 // we have an expression to send
1561 dereferencePointer(wnd
, exprItem
, false);
1566 if (exprItem
->m_type
== 0 || exprItem
->m_type
== TypeInfo::unknownType())
1568 evalInitialStructExpression(exprItem
, wnd
, false);
1573 * Sometimes a VarTree gets registered twice for a type update. So
1574 * it may happen that it has already been updated. Hence, we ignore
1575 * it here and go on to the next task.
1577 if (exprItem
->m_type
!= 0)
1579 determineType(wnd
, exprItem
);
1583 void KDebugger::dereferencePointer(ExprWnd
* wnd
, VarTree
* exprItem
,
1586 ASSERT(exprItem
->m_varKind
== VarTree::VKpointer
);
1588 QString expr
= exprItem
->computeExpr();
1589 TRACE("dereferencing pointer: " + expr
);
1592 cmd
= m_d
->queueCmd(DCprintDeref
, expr
, DebuggerDriver::QMoverrideMoreEqual
);
1594 cmd
= m_d
->queueCmd(DCprintDeref
, expr
, DebuggerDriver::QMoverride
);
1596 // remember which expr this was
1597 cmd
->m_expr
= exprItem
;
1598 cmd
->m_exprWnd
= wnd
;
1601 void KDebugger::determineType(ExprWnd
* wnd
, VarTree
* exprItem
)
1603 ASSERT(exprItem
->m_varKind
== VarTree::VKstruct
);
1605 QString expr
= exprItem
->computeExpr();
1606 TRACE("get type of: " + expr
);
1608 cmd
= m_d
->queueCmd(DCfindType
, expr
, DebuggerDriver::QMoverride
);
1610 // remember which expr this was
1611 cmd
->m_expr
= exprItem
;
1612 cmd
->m_exprWnd
= wnd
;
1615 void KDebugger::handleFindType(CmdQueueItem
* cmd
, const char* output
)
1618 if (m_d
->parseFindType(output
, type
))
1620 ASSERT(cmd
!= 0 && cmd
->m_expr
!= 0);
1622 TypeInfo
* info
= m_typeTable
->lookup(type
);
1626 * We've asked gdb for the type of the expression in
1627 * cmd->m_expr, but it returned a name we don't know. The base
1628 * class (and member) types have been checked already (at the
1629 * time when we parsed that particular expression). Now it's
1630 * time to derive the type from the base classes as a last
1633 info
= cmd
->m_expr
->inferTypeFromBaseClass();
1634 // if we found a type through this method, register an alias
1636 TRACE("infered alias: " + type
);
1637 m_typeTable
->registerAlias(type
, info
);
1641 TRACE("unknown type "+type
);
1642 cmd
->m_expr
->m_type
= TypeInfo::unknownType();
1644 cmd
->m_expr
->m_type
= info
;
1645 /* since this node has a new type, we get its value immediately */
1646 evalInitialStructExpression(cmd
->m_expr
, cmd
->m_exprWnd
, false);
1651 evalExpressions(); /* queue more of them */
1654 void KDebugger::handlePrintStruct(CmdQueueItem
* cmd
, const char* output
)
1656 VarTree
* var
= cmd
->m_expr
;
1658 ASSERT(var
->m_varKind
== VarTree::VKstruct
);
1660 ExprValue
* partExpr
;
1661 if (cmd
->m_cmd
== DCprintQStringStruct
) {
1662 partExpr
= m_d
->parseQCharArray(output
, false, m_typeTable
->qCharIsShort());
1663 } else if (cmd
->m_cmd
== DCprintWChar
) {
1664 partExpr
= m_d
->parseQCharArray(output
, false, true);
1666 partExpr
= m_d
->parsePrintExpr(output
, false);
1670 /* we only allow simple values at the moment */
1671 partExpr
->m_child
!= 0;
1676 partValue
= "?""?""?"; // 2 question marks in a row would be a trigraph
1678 partValue
= partExpr
->m_value
;
1684 * Updating a struct value works like this: var->m_partialValue holds
1685 * the value that we have gathered so far (it's been initialized with
1686 * var->m_type->m_displayString[0] earlier). Each time we arrive here,
1687 * we append the printed result followed by the next
1688 * var->m_type->m_displayString to var->m_partialValue.
1690 * If the expression we just evaluated was a guard expression, and it
1691 * resulted in an error, we must not evaluate the real expression, but
1692 * go on to the next index. (We must still add the question marks to
1695 * Next, if this was the length expression, we still have not seen the
1696 * real expression, but the length of a QString.
1698 ASSERT(var
->m_exprIndex
>= 0 && var
->m_exprIndex
<= typeInfoMaxExpr
);
1700 if (errorValue
|| !var
->m_exprIndexUseGuard
)
1702 // add current partValue (which might be the question marks)
1703 var
->m_partialValue
+= partValue
;
1704 var
->m_exprIndex
++; /* next part */
1705 var
->m_exprIndexUseGuard
= true;
1706 var
->m_partialValue
+= var
->m_type
->m_displayString
[var
->m_exprIndex
];
1710 // this was a guard expression that succeeded
1711 // go for the real expression
1712 var
->m_exprIndexUseGuard
= false;
1715 /* go for more sub-expressions if needed */
1716 if (var
->m_exprIndex
< var
->m_type
->m_numExprs
) {
1717 /* queue a new print command with quite high priority */
1718 evalStructExpression(var
, cmd
->m_exprWnd
, true);
1722 cmd
->m_exprWnd
->updateStructValue(var
);
1724 evalExpressions(); /* enqueue dereferenced pointers */
1727 /* queues the first printStruct command for a struct */
1728 void KDebugger::evalInitialStructExpression(VarTree
* var
, ExprWnd
* wnd
, bool immediate
)
1730 var
->m_exprIndex
= 0;
1731 if (var
->m_type
!= TypeInfo::wchartType())
1733 var
->m_exprIndexUseGuard
= true;
1734 var
->m_partialValue
= var
->m_type
->m_displayString
[0];
1735 evalStructExpression(var
, wnd
, immediate
);
1739 var
->m_exprIndexUseGuard
= false;
1740 QString expr
= var
->computeExpr();
1741 CmdQueueItem
* cmd
= m_d
->queueCmd(DCprintWChar
, expr
,
1742 immediate
? DebuggerDriver::QMoverrideMoreEqual
1743 : DebuggerDriver::QMoverride
);
1744 // remember which expression this was
1746 cmd
->m_exprWnd
= wnd
;
1750 /** queues a printStruct command; var must have been initialized correctly */
1751 void KDebugger::evalStructExpression(VarTree
* var
, ExprWnd
* wnd
, bool immediate
)
1753 QString base
= var
->computeExpr();
1755 if (var
->m_exprIndexUseGuard
) {
1756 expr
= var
->m_type
->m_guardStrings
[var
->m_exprIndex
];
1757 if (expr
.isEmpty()) {
1758 // no guard, omit it and go to expression
1759 var
->m_exprIndexUseGuard
= false;
1762 if (!var
->m_exprIndexUseGuard
) {
1763 expr
= var
->m_type
->m_exprStrings
[var
->m_exprIndex
];
1766 expr
.replace("%s", base
);
1768 DbgCommand dbgCmd
= DCprintStruct
;
1769 // check if this is a QString::Data
1770 if (expr
.left(15) == "/QString::Data ")
1772 if (m_typeTable
->parseQt2QStrings())
1774 expr
= expr
.mid(15, expr
.length()); /* strip off /QString::Data */
1775 dbgCmd
= DCprintQStringStruct
;
1778 * This should not happen: the type libraries should be set up
1779 * in a way that this can't happen. If this happens
1780 * nevertheless it means that, eg., kdecore was loaded but qt2
1781 * was not (only qt2 enables the QString feature).
1783 // TODO: remove this "print"; queue the next printStruct instead
1787 TRACE("evalStruct: " + expr
+ (var
->m_exprIndexUseGuard
? " // guard" : " // real"));
1788 CmdQueueItem
* cmd
= m_d
->queueCmd(dbgCmd
, expr
,
1789 immediate
? DebuggerDriver::QMoverrideMoreEqual
1790 : DebuggerDriver::QMnormal
);
1792 // remember which expression this was
1794 cmd
->m_exprWnd
= wnd
;
1797 void KDebugger::handleSharedLibs(const char* output
)
1799 // parse the table of shared libraries
1800 m_sharedLibs
= m_d
->parseSharedLibs(output
);
1801 m_sharedLibsListed
= true;
1803 // get type libraries
1804 m_typeTable
->loadLibTypes(m_sharedLibs
);
1806 // hand over the QString data cmd
1807 m_d
->setPrintQStringDataCmd(m_typeTable
->printQStringDataCmd());
1810 CmdQueueItem
* KDebugger::loadCoreFile()
1812 return m_d
->queueCmd(DCcorefile
, m_corefile
, DebuggerDriver::QMoverride
);
1815 void KDebugger::slotExpanding(Q3ListViewItem
* item
)
1817 VarTree
* exprItem
= static_cast<VarTree
*>(item
);
1818 if (exprItem
->m_varKind
!= VarTree::VKpointer
) {
1821 ExprWnd
* wnd
= static_cast<ExprWnd
*>(item
->listView());
1822 dereferencePointer(wnd
, exprItem
, true);
1825 // add the expression in the edit field to the watch expressions
1826 void KDebugger::addWatch(const QString
& t
)
1828 QString expr
= t
.stripWhiteSpace();
1829 // don't add a watched expression again
1830 if (expr
.isEmpty() || m_watchVariables
.topLevelExprByName(expr
) != 0)
1832 ExprValue
e(expr
, VarTree::NKplain
);
1833 m_watchVariables
.insertExpr(&e
, *m_typeTable
);
1835 // if we are boring ourselves, send down the command
1836 if (m_programActive
) {
1837 m_watchEvalExpr
.push_back(expr
);
1838 if (m_d
->isIdle()) {
1844 // delete a toplevel watch expression
1845 void KDebugger::slotDeleteWatch()
1847 // delete only allowed while debugger is idle; or else we might delete
1848 // the very expression the debugger is currently working on...
1849 if (m_d
== 0 || !m_d
->isIdle())
1852 VarTree
* item
= m_watchVariables
.currentItem();
1853 if (item
== 0 || !item
->isToplevelExpr())
1856 // remove the variable from the list to evaluate
1857 QStringList::iterator i
= m_watchEvalExpr
.find(item
->getText());
1858 if (i
!= m_watchEvalExpr
.end()) {
1859 m_watchEvalExpr
.erase(i
);
1861 m_watchVariables
.removeExpr(item
);
1862 // item is invalid at this point!
1865 void KDebugger::handleRegisters(const char* output
)
1867 emit
registersChanged(m_d
->parseRegisters(output
));
1871 * The output of the DCbreak* commands has more accurate information about
1872 * the file and the line number.
1874 * All newly set breakpoints are inserted in the m_brkpts, even those that
1875 * were not set sucessfully. The unsuccessful breakpoints ("orphaned
1876 * breakpoints") are assigned negative ids, and they are tried to set later
1877 * when the program stops again at a breakpoint.
1879 void KDebugger::newBreakpoint(CmdQueueItem
* cmd
, const char* output
)
1882 if (cmd
->m_brkpt
!= 0) {
1883 // a new breakpoint, put it in the list
1884 assert(cmd
->m_brkpt
->id
== 0);
1885 m_brkpts
.push_back(*cmd
->m_brkpt
);
1886 delete cmd
->m_brkpt
;
1887 bp
= m_brkpts
.end();
1890 // an existing breakpoint was retried
1891 assert(cmd
->m_existingBrkpt
!= 0);
1892 bp
= breakpointById(cmd
->m_existingBrkpt
);
1893 if (bp
== m_brkpts
.end())
1897 // parse the output to determine success or failure
1902 if (!m_d
->parseBreakpoint(output
, id
, file
, lineNo
, address
))
1905 * Failure, the breakpoint could not be set. If this is a new
1906 * breakpoint, assign it a negative id. We look for the minimal id
1907 * of all breakpoints (that are already in the list) to get the new
1913 for (BrkptIterator i
= m_brkpts
.begin(); i
!= m_brkpts
.end(); ++i
) {
1922 // The breakpoint was successfully set.
1925 // this is a new or orphaned breakpoint:
1926 // set the remaining properties
1928 m_d
->executeCmd(DCdisable
, id
);
1930 if (!bp
->condition
.isEmpty()) {
1931 m_d
->executeCmd(DCcondition
, bp
->condition
, id
);
1936 bp
->fileName
= file
;
1937 bp
->lineNo
= lineNo
;
1938 if (!address
.isEmpty())
1939 bp
->address
= address
;
1942 void KDebugger::updateBreakList(const char* output
)
1945 std::list
<Breakpoint
> brks
;
1946 m_d
->parseBreakList(output
, brks
);
1948 // merge existing information into the new list
1949 // then swap the old and new lists
1951 for (BrkptIterator bp
= brks
.begin(); bp
!= brks
.end(); ++bp
)
1953 BrkptIterator i
= breakpointById(bp
->id
);
1954 if (i
!= m_brkpts
.end())
1956 // preserve accurate location information
1957 // note that xsldbg doesn't have a location in
1958 // the listed breakpoint if it has just been set
1959 // therefore, we copy it as well if necessary
1961 if (!i
->fileName
.isEmpty()) {
1962 bp
->fileName
= i
->fileName
;
1963 bp
->lineNo
= i
->lineNo
;
1968 // orphaned breakpoints must be copied
1969 for (BrkptIterator bp
= m_brkpts
.begin(); bp
!= m_brkpts
.end(); ++bp
)
1971 if (bp
->isOrphaned())
1972 brks
.push_back(*bp
);
1975 m_brkpts
.swap(brks
);
1976 emit
breakpointsChanged();
1979 // look if there is at least one temporary breakpoint
1981 bool KDebugger::stopMayChangeBreakList() const
1983 for (BrkptROIterator bp
= m_brkpts
.begin(); bp
!= m_brkpts
.end(); ++bp
)
1985 if (bp
->temporary
|| bp
->type
== Breakpoint::watchpoint
)
1991 KDebugger::BrkptIterator
KDebugger::breakpointByFilePos(QString file
, int lineNo
,
1992 const DbgAddr
& address
)
1994 // look for exact file name match
1995 for (BrkptIterator bp
= m_brkpts
.begin(); bp
!= m_brkpts
.end(); ++bp
)
1997 if (bp
->lineNo
== lineNo
&&
1998 bp
->fileName
== file
&&
1999 (address
.isEmpty() || bp
->address
== address
))
2004 // not found, so try basename
2005 // strip off directory part of file name
2006 int offset
= file
.findRev("/");
2007 file
.remove(0, offset
+1);
2009 for (BrkptIterator bp
= m_brkpts
.begin(); bp
!= m_brkpts
.end(); ++bp
)
2011 // get base name of breakpoint's file
2012 QString basename
= bp
->fileName
;
2013 int offset
= basename
.findRev("/");
2015 basename
.remove(0, offset
+1);
2018 if (bp
->lineNo
== lineNo
&&
2020 (address
.isEmpty() || bp
->address
== address
))
2027 return m_brkpts
.end();
2030 KDebugger::BrkptIterator
KDebugger::breakpointById(int id
)
2032 for (BrkptIterator bp
= m_brkpts
.begin(); bp
!= m_brkpts
.end(); ++bp
)
2039 return m_brkpts
.end();
2042 void KDebugger::slotValuePopup(const QString
& expr
)
2044 // search the local variables for a match
2045 VarTree
* v
= m_localVariables
.topLevelExprByName(expr
);
2047 // not found, check watch expressions
2048 v
= m_watchVariables
.topLevelExprByName(expr
);
2050 // try a member of 'this'
2051 v
= m_localVariables
.topLevelExprByName("this");
2053 v
= ExprWnd::ptrMemberByName(v
, expr
);
2055 // nothing found; do nothing
2061 // construct the tip
2062 QString tip
= v
->getText() + " = ";
2063 if (!v
->value().isEmpty())
2069 // no value: we use some hint
2070 switch (v
->m_varKind
) {
2071 case VarTree::VKstruct
:
2074 case VarTree::VKarray
:
2078 tip
+= "?""?""?"; // 2 question marks in a row would be a trigraph
2082 emit
valuePopup(tip
);
2085 void KDebugger::slotDisassemble(const QString
& fileName
, int lineNo
)
2087 if (m_haveExecutable
) {
2088 CmdQueueItem
* cmd
= m_d
->queueCmd(DCinfoline
, fileName
, lineNo
,
2089 DebuggerDriver::QMoverrideMoreEqual
);
2090 cmd
->m_fileName
= fileName
;
2091 cmd
->m_lineNo
= lineNo
;
2095 void KDebugger::handleInfoLine(CmdQueueItem
* cmd
, const char* output
)
2097 QString addrFrom
, addrTo
;
2098 if (cmd
->m_lineNo
>= 0) {
2100 if (m_d
->parseInfoLine(output
, addrFrom
, addrTo
)) {
2101 // got the address range, now get the real code
2102 CmdQueueItem
* c
= m_d
->queueCmd(DCdisassemble
, addrFrom
, addrTo
,
2103 DebuggerDriver::QMoverrideMoreEqual
);
2104 c
->m_fileName
= cmd
->m_fileName
;
2105 c
->m_lineNo
= cmd
->m_lineNo
;
2108 emit
disassembled(cmd
->m_fileName
, cmd
->m_lineNo
, std::list
<DisassembledCode
>());
2111 // set program counter
2112 if (m_d
->parseInfoLine(output
, addrFrom
, addrTo
)) {
2113 // move the program counter to the start address
2114 m_d
->executeCmd(DCsetpc
, addrFrom
);
2119 void KDebugger::handleDisassemble(CmdQueueItem
* cmd
, const char* output
)
2121 emit
disassembled(cmd
->m_fileName
, cmd
->m_lineNo
,
2122 m_d
->parseDisassemble(output
));
2125 void KDebugger::handleThreadList(const char* output
)
2127 emit
threadsChanged(m_d
->parseThreadList(output
));
2130 void KDebugger::setThread(int id
)
2132 m_d
->queueCmd(DCthread
, id
, DebuggerDriver::QMoverrideMoreEqual
);
2135 void KDebugger::setMemoryExpression(const QString
& memexpr
)
2137 m_memoryExpression
= memexpr
;
2139 // queue the new expression
2140 if (!m_memoryExpression
.isEmpty() &&
2141 isProgramActive() &&
2142 !isProgramRunning())
2144 queueMemoryDump(true);
2148 void KDebugger::queueMemoryDump(bool immediate
)
2150 m_d
->queueCmd(DCexamine
, m_memoryExpression
, m_memoryFormat
,
2151 immediate
? DebuggerDriver::QMoverrideMoreEqual
:
2152 DebuggerDriver::QMoverride
);
2155 void KDebugger::handleMemoryDump(const char* output
)
2157 std::list
<MemoryDump
> memdump
;
2158 QString msg
= m_d
->parseMemoryDump(output
, memdump
);
2159 emit
memoryDumpChanged(msg
, memdump
);
2162 void KDebugger::setProgramCounter(const QString
& file
, int line
, const DbgAddr
& addr
)
2164 if (addr
.isEmpty()) {
2165 // find address of the specified line
2166 CmdQueueItem
* cmd
= m_d
->executeCmd(DCinfoline
, file
, line
);
2167 cmd
->m_lineNo
= -1; /* indicates "Set PC" UI command */
2169 // move the program counter to that address
2170 m_d
->executeCmd(DCsetpc
, addr
.asString());
2174 void KDebugger::handleSetPC(const char* /*output*/)
2176 // TODO: handle errors
2178 // now go to the top-most frame
2179 // this also modifies the program counter indicator in the UI
2183 void KDebugger::slotValueEdited(VarTree
* expr
, const QString
& text
)
2185 if (text
.simplifyWhiteSpace().isEmpty())
2186 return; /* no text entered: ignore request */
2188 ExprWnd
* wnd
= static_cast<ExprWnd
*>(expr
->listView());
2189 TRACE(QString().sprintf("Changing %s to ",
2190 wnd
->name()) + text
);
2192 // determine the lvalue to edit
2193 QString lvalue
= expr
->computeExpr();
2194 CmdQueueItem
* cmd
= m_d
->executeCmd(DCsetvariable
, lvalue
, text
);
2196 cmd
->m_exprWnd
= wnd
;
2199 void KDebugger::handleSetVariable(CmdQueueItem
* cmd
, const char* output
)
2201 QString msg
= m_d
->parseSetVariable(output
);
2204 // there was an error; display it in the status bar
2205 m_statusMessage
= msg
;
2206 emit
updateStatusMessage();
2210 // get the new value
2211 QString expr
= cmd
->m_expr
->computeExpr();
2212 CmdQueueItem
* printCmd
=
2213 m_d
->queueCmd(DCprint
, expr
, DebuggerDriver::QMoverrideMoreEqual
);
2214 printCmd
->m_expr
= cmd
->m_expr
;
2215 printCmd
->m_exprWnd
= cmd
->m_exprWnd
;
2219 #include "debugger.moc"