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 <QListWidget>
15 #include <QApplication>
16 #include <kcodecs.h> // KMD5
18 #include <klocale.h> /* i18n */
19 #include <kmessagebox.h>
20 #include <kstandarddirs.h>
22 #include <stdlib.h> /* strtol, atoi */
23 #include <unistd.h> /* sleep(3) */
28 KDebugger::KDebugger(QWidget
* parent
,
31 QListWidget
* backtrace
) :
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 connect(&m_localVariables
, SIGNAL(itemExpanded(QTreeWidgetItem
*)),
47 SLOT(slotExpanding(QTreeWidgetItem
*)));
48 connect(&m_watchVariables
, SIGNAL(itemExpanded(QTreeWidgetItem
*)),
49 SLOT(slotExpanding(QTreeWidgetItem
*)));
50 connect(&m_localVariables
, SIGNAL(editValueCommitted(VarTree
*, const QString
&)),
51 SLOT(slotValueEdited(VarTree
*, const QString
&)));
52 connect(&m_watchVariables
, SIGNAL(editValueCommitted(VarTree
*, const QString
&)),
53 SLOT(slotValueEdited(VarTree
*, const QString
&)));
55 connect(&m_btWindow
, SIGNAL(currentRowChanged(int)), this, SLOT(gotoFrame(int)));
60 KDebugger::~KDebugger()
62 if (m_programConfig
!= 0) {
63 saveProgramSettings();
64 m_programConfig
->sync();
65 delete m_programConfig
;
72 void KDebugger::saveSettings(KConfig
* /*config*/)
76 void KDebugger::restoreSettings(KConfig
* /*config*/)
81 //////////////////////////////////////////////////////////////////////
84 const char GeneralGroup
[] = "General";
85 const char DebuggerCmdStr
[] = "DebuggerCmdStr";
86 const char TTYLevelEntry
[] = "TTYLevel";
87 const char KDebugger::DriverNameEntry
[] = "DriverName";
89 bool KDebugger::debugProgram(const QString
& name
,
90 DebuggerDriver
* driver
)
92 if (m_d
!= 0 && m_d
->isRunning())
94 QApplication::setOverrideCursor(Qt::WaitCursor
);
98 QApplication::restoreOverrideCursor();
100 if (m_d
->isRunning() || m_haveExecutable
) {
101 /* timed out! We can't really do anything useful now */
102 TRACE("timed out while waiting for gdb to die!");
109 // wire up the driver
110 connect(driver
, SIGNAL(activateFileLine(const QString
&,int,const DbgAddr
&)),
111 this, SIGNAL(activateFileLine(const QString
&,int,const DbgAddr
&)));
112 connect(driver
, SIGNAL(finished(int, QProcess::ExitStatus
)),
114 connect(driver
, SIGNAL(commandReceived(CmdQueueItem
*,const char*)),
115 SLOT(parse(CmdQueueItem
*,const char*)));
116 connect(driver
, SIGNAL(bytesWritten(qint64
)), SIGNAL(updateUI()));
117 connect(driver
, SIGNAL(inferiorRunning()), SLOT(slotInferiorRunning()));
118 connect(driver
, SIGNAL(enterIdleState()), SLOT(backgroundUpdate()));
119 connect(driver
, SIGNAL(enterIdleState()), SIGNAL(updateUI()));
120 connect(&m_localVariables
, SIGNAL(removingItem(VarTree
*)),
121 driver
, SLOT(dequeueCmdByVar(VarTree
*)));
122 connect(&m_watchVariables
, SIGNAL(removingItem(VarTree
*)),
123 driver
, SLOT(dequeueCmdByVar(VarTree
*)));
125 // create the program settings object
126 openProgramConfig(name
);
128 // get debugger command from per-program settings
129 if (m_programConfig
!= 0) {
130 KConfigGroup g
= m_programConfig
->group(GeneralGroup
);
131 m_debuggerCmd
= readDebuggerCmd(g
);
132 // get terminal emulation level
133 m_ttyLevel
= TTYLevel(g
.readEntry(TTYLevelEntry
, int(ttyFull
)));
135 // the rest is read in later in the handler of DCexecutable
139 if (!startDriver()) {
140 TRACE("startDriver failed");
145 TRACE("before file cmd");
146 m_d
->executeCmd(DCexecutable
, name
);
150 if (!m_remoteDevice
.isEmpty()) {
151 m_d
->executeCmd(DCtargetremote
, m_remoteDevice
);
152 m_d
->queueCmd(DCbt
, DebuggerDriver::QMoverride
);
153 m_d
->queueCmd(DCinfothreads
, 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 QFileInfo
fi(fileName
);
288 m_d
->executeCmd(DCuntil
, fi
.fileName(), lineNo
, true);
289 m_programRunning
= true;
296 void KDebugger::programBreak()
298 if (m_haveExecutable
&& m_programRunning
) {
299 m_d
->interruptInferior();
303 void KDebugger::programArgs(QWidget
* parent
)
305 if (m_haveExecutable
) {
306 QStringList allOptions
= m_d
->boolOptionList();
307 PgmArgs
dlg(parent
, m_executable
, m_envVars
, allOptions
);
308 dlg
.setArgs(m_programArgs
);
309 dlg
.setWd(m_programWD
);
310 dlg
.setOptions(m_boolOptions
);
312 updateProgEnvironment(dlg
.args(), dlg
.wd(),
313 dlg
.envVars(), dlg
.options());
318 void KDebugger::programSettings(QWidget
* parent
)
320 if (!m_haveExecutable
)
323 ProgramSettings
dlg(parent
, m_executable
);
325 dlg
.m_chooseDriver
.setDebuggerCmd(m_debuggerCmd
);
326 dlg
.m_output
.setTTYLevel(m_ttyLevel
);
328 if (dlg
.exec() == QDialog::Accepted
)
330 m_debuggerCmd
= dlg
.m_chooseDriver
.debuggerCmd();
331 m_ttyLevel
= TTYLevel(dlg
.m_output
.ttyLevel());
335 bool KDebugger::setBreakpoint(QString file
, int lineNo
,
336 const DbgAddr
& address
, bool temporary
)
342 BrkptIterator bp
= breakpointByFilePos(file
, lineNo
, address
);
343 if (bp
== m_brkpts
.end())
346 * No such breakpoint, so set a new one. If we have an address, we
347 * set the breakpoint exactly there. Otherwise we use the file name
350 Breakpoint
* bp
= new Breakpoint
;
351 bp
->temporary
= temporary
;
353 if (address
.isEmpty())
360 bp
->address
= address
;
362 setBreakpoint(bp
, false);
367 * If the breakpoint is disabled, enable it; if it's enabled,
368 * delete that breakpoint.
371 deleteBreakpoint(bp
);
373 enableDisableBreakpoint(bp
);
379 void KDebugger::setBreakpoint(Breakpoint
* bp
, bool queueOnly
)
381 CmdQueueItem
* cmd
= executeBreakpoint(bp
, queueOnly
);
382 cmd
->m_brkpt
= bp
; // used in newBreakpoint()
385 CmdQueueItem
* KDebugger::executeBreakpoint(const Breakpoint
* bp
, bool queueOnly
)
388 if (!bp
->text
.isEmpty())
391 * The breakpoint was set using the text box in the breakpoint
392 * list. This is the only way in which watchpoints are set.
394 if (bp
->type
== Breakpoint::watchpoint
) {
395 cmd
= m_d
->executeCmd(DCwatchpoint
, bp
->text
);
397 cmd
= m_d
->executeCmd(DCbreaktext
, bp
->text
);
400 else if (bp
->address
.isEmpty())
402 // strip off directory part of file name
403 QString file
= QFileInfo(bp
->fileName
).fileName();
405 cmd
= m_d
->queueCmd(bp
->temporary
? DCtbreakline
: DCbreakline
,
406 file
, bp
->lineNo
, DebuggerDriver::QMoverride
);
408 cmd
= m_d
->executeCmd(bp
->temporary
? DCtbreakline
: DCbreakline
,
415 cmd
= m_d
->queueCmd(bp
->temporary
? DCtbreakaddr
: DCbreakaddr
,
416 bp
->address
.asString(), DebuggerDriver::QMoverride
);
418 cmd
= m_d
->executeCmd(bp
->temporary
? DCtbreakaddr
: DCbreakaddr
,
419 bp
->address
.asString());
425 bool KDebugger::infoLine(QString file
, int lineNo
, const DbgAddr
& addr
)
427 if (isReady() && !m_programRunning
) {
428 CmdQueueItem
* cmd
= m_d
->executeCmd(DCinfoline
, file
, lineNo
);
436 bool KDebugger::enableDisableBreakpoint(QString file
, int lineNo
,
437 const DbgAddr
& address
)
439 BrkptIterator bp
= breakpointByFilePos(file
, lineNo
, address
);
440 return enableDisableBreakpoint(bp
);
443 bool KDebugger::enableDisableBreakpoint(BrkptIterator bp
)
445 if (bp
== m_brkpts
.end())
449 * Toggle enabled/disabled state.
451 * The driver is not bothered if we are modifying an orphaned
454 if (!bp
->isOrphaned()) {
455 if (!canChangeBreakpoints()) {
458 m_d
->executeCmd(bp
->enabled
? DCdisable
: DCenable
, bp
->id
);
460 bp
->enabled
= !bp
->enabled
;
461 emit
breakpointsChanged();
466 bool KDebugger::conditionalBreakpoint(BrkptIterator bp
,
467 const QString
& condition
,
470 if (bp
== m_brkpts
.end())
474 * Change the condition and ignore count.
476 * The driver is not bothered if we are removing an orphaned
480 if (!bp
->isOrphaned()) {
481 if (!canChangeBreakpoints()) {
485 bool changed
= false;
487 if (bp
->condition
!= condition
) {
489 m_d
->executeCmd(DCcondition
, condition
, bp
->id
);
492 if (bp
->ignoreCount
!= ignoreCount
) {
493 // change ignore count
494 m_d
->executeCmd(DCignore
, bp
->id
, ignoreCount
);
499 m_d
->queueCmd(DCinfobreak
, DebuggerDriver::QMoverride
);
502 bp
->condition
= condition
;
503 bp
->ignoreCount
= ignoreCount
;
504 emit
breakpointsChanged();
509 bool KDebugger::deleteBreakpoint(BrkptIterator bp
)
511 if (bp
== m_brkpts
.end())
515 * Remove the breakpoint.
517 * The driver is not bothered if we are removing an orphaned
520 if (!bp
->isOrphaned()) {
521 if (!canChangeBreakpoints()) {
524 m_d
->executeCmd(DCdelete
, bp
->id
);
527 emit
breakpointsChanged();
532 bool KDebugger::canSingleStep()
534 return isReady() && m_programActive
&& !m_programRunning
;
537 bool KDebugger::canChangeBreakpoints()
539 return isReady() && !m_programRunning
;
542 bool KDebugger::canStart()
544 return isReady() && !m_programActive
;
547 bool KDebugger::isReady() const
549 return m_haveExecutable
&&
550 m_d
!= 0 && m_d
->canExecuteImmediately();
553 bool KDebugger::isIdle() const
555 return m_d
== 0 || m_d
->isIdle();
559 //////////////////////////////////////////////////////////
562 bool KDebugger::startDriver()
564 emit
debuggerStarting(); /* must set m_inferiorTerminal */
567 * If the per-program command string is empty, use the global setting
568 * (which might also be empty, in which case the driver uses its
571 m_explicitKill
= false;
572 if (!m_d
->startup(m_debuggerCmd
)) {
577 * If we have an output terminal, we use it. Otherwise we will run the
578 * program with input and output redirected to /dev/null. Other
579 * redirections are also necessary depending on the tty emulation
582 int redirect
= RDNstdin
|RDNstdout
|RDNstderr
; /* redirect everything */
583 if (!m_inferiorTerminal
.isEmpty()) {
584 switch (m_ttyLevel
) {
587 // redirect everything
589 case ttySimpleOutputOnly
:
597 m_d
->executeCmd(DCtty
, m_inferiorTerminal
, redirect
);
602 void KDebugger::stopDriver()
604 m_explicitKill
= true;
606 if (m_attachedPid
.isEmpty()) {
609 m_d
->detachAndTerminate();
613 * We MUST wait until the slot gdbExited() has been called. But to
614 * avoid a deadlock, we wait only for some certain maximum time. Should
615 * this timeout be reached, the only reasonable thing one could do then
618 QApplication::processEvents(QEventLoop::AllEvents
, 1000);
619 int maxTime
= 20; /* about 20 seconds */
620 while (m_haveExecutable
&& maxTime
> 0) {
621 // give gdb time to die (and send a SIGCLD)
624 QApplication::processEvents(QEventLoop::AllEvents
, 1000);
628 void KDebugger::gdbExited()
631 * Save settings, but only if gdb has already processed "info line
632 * main", otherwise we would save an empty config file, because it
633 * isn't read in until then!
635 if (m_programConfig
!= 0) {
636 if (m_haveExecutable
) {
637 saveProgramSettings();
638 m_programConfig
->sync();
640 delete m_programConfig
;
648 if (m_explicitKill
) {
649 TRACE(m_d
->driverName() + " exited normally");
651 QString msg
= i18n("%1 exited unexpectedly.\n"
652 "Restart the session (e.g. with File|Executable).");
653 KMessageBox::error(parentWidget(), msg
.arg(m_d
->driverName()));
657 m_haveExecutable
= false;
659 m_programActive
= false;
660 m_programRunning
= false;
661 m_explicitKill
= false;
662 m_debuggerCmd
= QString(); /* use global setting at next start! */
663 m_attachedPid
= QString(); /* we are no longer attached to a process */
664 m_ttyLevel
= ttyFull
;
668 emit
updatePC(QString(), -1, DbgAddr(), 0);
671 QString
KDebugger::getConfigForExe(const QString
& name
)
674 QString dir
= fi
.absolutePath();
676 // The session file for the given executable consists of
677 // a hash of the directory, followed by the program name.
678 // Assume that the first 15 positions of the hash are unique;
679 // this keeps the file names short.
680 QString hash
= KMD5(dir
.toUtf8()).base64Digest();
681 hash
.replace('/', QString()); // avoid directory separators
682 QString pgmConfigFile
= hash
.left(15) + "-" + fi
.fileName();
683 pgmConfigFile
= KStandardDirs::locateLocal("sessions", pgmConfigFile
);
684 TRACE("program config file = " + pgmConfigFile
);
685 return pgmConfigFile
;
688 void KDebugger::openProgramConfig(const QString
& name
)
690 ASSERT(m_programConfig
== 0);
692 QString pgmConfigFile
= getConfigForExe(name
);
694 m_programConfig
= new KConfig(pgmConfigFile
);
696 // this leaves a clue behind in the config file which
697 // executable it applies to; it is mostly intended for
698 // users peeking into the file
699 KConfigGroup g
= m_programConfig
->group(GeneralGroup
);
700 g
.writeEntry("ExecutableFile", name
);
703 const char EnvironmentGroup
[] = "Environment";
704 const char WatchGroup
[] = "Watches";
705 const char FileVersion
[] = "FileVersion";
706 const char ProgramArgs
[] = "ProgramArgs";
707 const char WorkingDirectory
[] = "WorkingDirectory";
708 const char OptionsSelected
[] = "OptionsSelected";
709 const char Variable
[] = "Var%d";
710 const char Value
[] = "Value%d";
711 const char ExprFmt
[] = "Expr%d";
713 void KDebugger::saveProgramSettings()
715 ASSERT(m_programConfig
!= 0);
716 KConfigGroup gg
= m_programConfig
->group(GeneralGroup
);
717 gg
.writeEntry(FileVersion
, 1);
718 gg
.writeEntry(ProgramArgs
, m_programArgs
);
719 gg
.writeEntry(WorkingDirectory
, m_programWD
);
720 gg
.writeEntry(OptionsSelected
, m_boolOptions
.toList());
721 gg
.writeEntry(DebuggerCmdStr
, m_debuggerCmd
);
722 gg
.writeEntry(TTYLevelEntry
, int(m_ttyLevel
));
725 driverName
= m_d
->driverName();
726 gg
.writeEntry(DriverNameEntry
, driverName
);
728 // write environment variables
729 m_programConfig
->deleteGroup(EnvironmentGroup
);
730 KConfigGroup eg
= m_programConfig
->group(EnvironmentGroup
);
734 for (std::map
<QString
,QString
>::iterator it
= m_envVars
.begin(); it
!= m_envVars
.end(); ++it
, ++i
)
736 varName
.sprintf(Variable
, i
);
737 varValue
.sprintf(Value
, i
);
738 eg
.writeEntry(varName
, it
->first
);
739 eg
.writeEntry(varValue
, it
->second
);
742 saveBreakpoints(m_programConfig
);
745 // first get rid of whatever was in this group
746 m_programConfig
->deleteGroup(WatchGroup
);
747 // then start a new group
748 KConfigGroup wg
= m_programConfig
->group(WatchGroup
);
750 foreach (QString expr
, m_watchVariables
.exprList()) {
751 varName
.sprintf(ExprFmt
, watchNum
++);
752 wg
.writeEntry(varName
, expr
);
755 // give others a chance
756 emit
saveProgramSpecific(m_programConfig
);
759 void KDebugger::overrideProgramArguments(const QString
& args
)
761 ASSERT(m_programConfig
!= 0);
762 KConfigGroup g
= m_programConfig
->group(GeneralGroup
);
763 g
.writeEntry(ProgramArgs
, args
);
766 void KDebugger::restoreProgramSettings()
768 ASSERT(m_programConfig
!= 0);
769 KConfigGroup gg
= m_programConfig
->group(GeneralGroup
);
771 * We ignore file version for now we will use it in the future to
772 * distinguish different versions of this configuration file.
774 // m_debuggerCmd has been read in already
775 // m_ttyLevel has been read in already
776 QString pgmArgs
= gg
.readEntry(ProgramArgs
);
777 QString pgmWd
= gg
.readEntry(WorkingDirectory
);
778 QSet
<QString
> boolOptions
= QSet
<QString
>::fromList(gg
.readEntry(OptionsSelected
, QStringList()));
779 m_boolOptions
.clear();
781 // read environment variables
782 KConfigGroup eg
= m_programConfig
->group(EnvironmentGroup
);
784 std::map
<QString
,EnvVar
> pgmVars
;
787 for (int i
= 0;; ++i
) {
788 varName
.sprintf(Variable
, i
);
789 varValue
.sprintf(Value
, i
);
790 if (!eg
.hasKey(varName
)) {
791 /* entry not present, assume that we've hit them all */
794 QString name
= eg
.readEntry(varName
, QString());
795 if (name
.isEmpty()) {
799 EnvVar
* var
= &pgmVars
[name
];
800 var
->value
= eg
.readEntry(varValue
, QString());
801 var
->status
= EnvVar::EVnew
;
804 updateProgEnvironment(pgmArgs
, pgmWd
, pgmVars
, boolOptions
);
806 restoreBreakpoints(m_programConfig
);
809 KConfigGroup wg
= m_programConfig
->group(WatchGroup
);
810 m_watchVariables
.clear();
811 for (int i
= 0;; ++i
) {
812 varName
.sprintf(ExprFmt
, i
);
813 if (!wg
.hasKey(varName
)) {
814 /* entry not present, assume that we've hit them all */
817 QString expr
= wg
.readEntry(varName
, QString());
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(const KConfigGroup
& g
)
835 QString debuggerCmd
= g
.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 KConfigGroup g
= config
->group(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 g
.writeEntry(Text
, bp
->text
);
890 } else if (!bp
->fileName
.isEmpty()) {
891 g
.writeEntry(File
, bp
->fileName
);
892 g
.writeEntry(Line
, bp
->lineNo
);
894 * Addresses are hardly correct across sessions, so we don't
898 g
.writeEntry(Address
, bp
->address
.asString());
900 g
.writeEntry(Temporary
, bp
->temporary
);
901 g
.writeEntry(Enabled
, bp
->enabled
);
902 if (!bp
->condition
.isEmpty())
903 g
.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 if (!config
->group(groupName
).hasKey(Enabled
)) {
911 /* group not present, assume that we've hit them all */
914 config
->deleteGroup(groupName
);
918 void KDebugger::restoreBreakpoints(KConfig
* config
)
922 * We recognize the end of the list if there is no Enabled entry
925 for (int i
= 0;; i
++) {
926 groupName
.sprintf(BPGroup
, i
);
927 KConfigGroup g
= config
->group(groupName
);
928 if (!g
.hasKey(Enabled
)) {
929 /* group not present, assume that we've hit them all */
932 Breakpoint
* bp
= new Breakpoint
;
933 bp
->fileName
= g
.readEntry(File
);
934 bp
->lineNo
= g
.readEntry(Line
, -1);
935 bp
->text
= g
.readEntry(Text
);
936 bp
->address
= g
.readEntry(Address
);
938 if ((bp
->fileName
.isEmpty() || bp
->lineNo
< 0) &&
939 bp
->text
.isEmpty() &&
940 bp
->address
.isEmpty())
945 bp
->enabled
= g
.readEntry(Enabled
, true);
946 bp
->temporary
= g
.readEntry(Temporary
, false);
947 bp
->condition
= g
.readEntry(Condition
);
950 * Add the breakpoint.
952 setBreakpoint(bp
, false);
953 // the new breakpoint is disabled or conditionalized later
954 // in newBreakpoint()
956 m_d
->queueCmd(DCinfobreak
, DebuggerDriver::QMoverride
);
960 // parse output of command cmd
961 void KDebugger::parse(CmdQueueItem
* cmd
, const char* output
)
963 ASSERT(cmd
!= 0); /* queue mustn't be empty */
965 TRACE(QString(__PRETTY_FUNCTION__
) + " parsing " + output
);
967 switch (cmd
->m_cmd
) {
969 // the output (if any) is uninteresting
972 // there is no output
976 /* if value is empty, we see output, but we don't care */
979 /* display gdb's message in the status bar */
980 m_d
->parseChangeWD(output
, m_statusMessage
);
981 emit
updateStatusMessage();
986 if (m_d
->parseChangeExecutable(output
, m_statusMessage
))
988 // success; restore breakpoints etc.
989 if (m_programConfig
!= 0) {
990 restoreProgramSettings();
992 // load file containing main() or core file
993 if (!m_corefile
.isEmpty())
998 else if (!m_attachedPid
.isEmpty())
1000 m_d
->queueCmd(DCattach
, m_attachedPid
, DebuggerDriver::QMoverride
);
1001 m_programActive
= true;
1002 m_programRunning
= true;
1004 else if (!m_remoteDevice
.isEmpty())
1006 // handled elsewhere
1010 m_d
->queueCmd(DCinfolinemain
, DebuggerDriver::QMnormal
);
1012 if (!m_statusMessage
.isEmpty())
1013 emit
updateStatusMessage();
1015 QString msg
= m_d
->driverName() + ": " + m_statusMessage
;
1016 KMessageBox::sorry(parentWidget(), msg
);
1018 m_corefile
= ""; /* don't process core file */
1019 m_haveExecutable
= false;
1023 // in any event we have an executable at this point
1024 m_haveExecutable
= true;
1025 if (m_d
->parseCoreFile(output
)) {
1026 // loading a core is like stopping at a breakpoint
1027 m_programActive
= true;
1028 handleRunCommands(output
);
1029 // do not reset m_corefile
1032 QString msg
= m_d
->driverName() + ": " + QString(output
);
1033 KMessageBox::sorry(parentWidget(), msg
);
1035 // if core file was loaded from command line, revert to info line main
1036 if (!cmd
->m_byUser
) {
1037 m_d
->queueCmd(DCinfolinemain
, DebuggerDriver::QMnormal
);
1039 m_corefile
= QString(); /* core file not available any more */
1042 case DCinfolinemain
:
1043 // ignore the output, marked file info follows
1044 m_haveExecutable
= true;
1047 // parse local variables
1048 if (output
[0] != '\0') {
1049 handleLocals(output
);
1052 case DCinforegisters
:
1053 handleRegisters(output
);
1056 handleMemoryDump(output
);
1059 handleInfoLine(cmd
, output
);
1062 handleDisassemble(cmd
, output
);
1065 handleFrameChange(output
);
1069 handleBacktrace(output
);
1073 handlePrint(cmd
, output
);
1076 handlePrintDeref(cmd
, output
);
1079 m_haveExecutable
= true;
1090 handleRunCommands(output
);
1093 m_programRunning
= m_programActive
= false;
1095 emit
updatePC(QString(), -1, DbgAddr(), 0);
1103 newBreakpoint(cmd
, output
);
1108 // these commands need immediate response
1109 m_d
->queueCmd(DCinfobreak
, DebuggerDriver::QMoverrideMoreEqual
);
1112 // note: this handler must not enqueue a command, since
1113 // DCinfobreak is used at various different places.
1114 updateBreakList(output
);
1117 handleFindType(cmd
, output
);
1120 case DCprintQStringStruct
:
1122 handlePrintStruct(cmd
, output
);
1124 case DCinfosharedlib
:
1125 handleSharedLibs(output
);
1129 // we are not interested in the output
1132 handleThreadList(output
);
1135 handleSetPC(output
);
1138 handleSetVariable(cmd
, output
);
1143 void KDebugger::backgroundUpdate()
1146 * If there are still expressions that need to be updated, then do so.
1148 if (m_programActive
)
1152 void KDebugger::handleRunCommands(const char* output
)
1154 uint flags
= m_d
->parseProgramStopped(output
, m_statusMessage
);
1155 emit
updateStatusMessage();
1157 m_programActive
= flags
& DebuggerDriver::SFprogramActive
;
1159 // refresh files if necessary
1160 if (flags
& DebuggerDriver::SFrefreshSource
) {
1161 TRACE("re-reading files");
1162 emit
executableUpdated();
1166 * Try to set any orphaned breakpoints now.
1168 for (BrkptIterator bp
= m_brkpts
.begin(); bp
!= m_brkpts
.end(); ++bp
)
1170 if (bp
->isOrphaned()) {
1171 TRACE(QString("re-trying brkpt loc: %2 file: %3 line: %1")
1172 .arg(bp
->lineNo
).arg(bp
->location
, bp
->fileName
));
1173 CmdQueueItem
* cmd
= executeBreakpoint(&*bp
, true);
1174 cmd
->m_existingBrkpt
= bp
->id
; // used in newBreakpoint()
1175 flags
|= DebuggerDriver::SFrefreshBreak
;
1180 * If we stopped at a breakpoint, we must update the breakpoint list
1181 * because the hit count changes. Also, if the breakpoint was temporary
1182 * it would go away now.
1184 if ((flags
& (DebuggerDriver::SFrefreshBreak
|DebuggerDriver::SFrefreshSource
)) ||
1185 stopMayChangeBreakList())
1187 m_d
->queueCmd(DCinfobreak
, DebuggerDriver::QMoverride
);
1191 * If we haven't listed the shared libraries yet, do so. We must do
1192 * this before we emit any commands that list variables, since the type
1193 * libraries depend on the shared libraries.
1195 if (!m_sharedLibsListed
) {
1196 // must be a high-priority command!
1197 m_d
->executeCmd(DCinfosharedlib
);
1200 // get the backtrace if the program is running
1201 if (m_programActive
) {
1202 m_d
->queueCmd(DCbt
, DebuggerDriver::QMoverride
);
1204 // program finished: erase PC
1205 emit
updatePC(QString(), -1, DbgAddr(), 0);
1206 // dequeue any commands in the queues
1207 m_d
->flushCommands();
1210 /* Update threads list */
1211 if (m_programActive
&& (flags
& DebuggerDriver::SFrefreshThreads
)) {
1212 m_d
->queueCmd(DCinfothreads
, DebuggerDriver::QMoverride
);
1215 m_programRunning
= false;
1216 emit
programStopped();
1219 void KDebugger::slotInferiorRunning()
1221 m_programRunning
= true;
1224 void KDebugger::updateAllExprs()
1226 if (!m_programActive
)
1229 // retrieve local variables
1230 m_d
->queueCmd(DCinfolocals
, DebuggerDriver::QMoverride
);
1232 // retrieve registers
1233 m_d
->queueCmd(DCinforegisters
, DebuggerDriver::QMoverride
);
1235 // get new memory dump
1236 if (!m_memoryExpression
.isEmpty()) {
1237 queueMemoryDump(false);
1240 // update watch expressions
1241 foreach (QString expr
, m_watchVariables
.exprList()) {
1242 m_watchEvalExpr
.push_back(expr
);
1246 void KDebugger::updateProgEnvironment(const QString
& args
, const QString
& wd
,
1247 const std::map
<QString
,EnvVar
>& newVars
,
1248 const QSet
<QString
>& newOptions
)
1250 m_programArgs
= args
;
1251 m_d
->executeCmd(DCsetargs
, m_programArgs
);
1252 TRACE("new pgm args: " + m_programArgs
+ "\n");
1254 m_programWD
= wd
.trimmed();
1255 if (!m_programWD
.isEmpty()) {
1256 m_d
->executeCmd(DCcd
, m_programWD
);
1257 TRACE("new wd: " + m_programWD
+ "\n");
1260 // update environment variables
1261 for (std::map
<QString
,EnvVar
>::const_iterator i
= newVars
.begin(); i
!= newVars
.end(); ++i
)
1263 QString var
= i
->first
;
1264 const EnvVar
* val
= &i
->second
;
1265 switch (val
->status
) {
1267 case EnvVar::EVdirty
:
1268 m_envVars
[var
] = val
->value
;
1270 m_d
->executeCmd(DCsetenv
, var
, val
->value
);
1272 case EnvVar::EVdeleted
:
1274 m_d
->executeCmd(DCunsetenv
, var
);
1275 m_envVars
.erase(var
);
1279 case EnvVar::EVclean
:
1280 // variable not changed
1286 foreach (QString opt
, newOptions
- m_boolOptions
)
1288 // option is not set, set it
1289 m_d
->executeCmd(DCsetoption
, opt
, 1);
1291 foreach (QString opt
, m_boolOptions
- newOptions
)
1293 // option is set, unset it
1294 m_d
->executeCmd(DCsetoption
, opt
, 0);
1296 m_boolOptions
= newOptions
;
1299 void KDebugger::handleLocals(const char* output
)
1301 // retrieve old list of local variables
1302 QStringList oldVars
= m_localVariables
.exprList();
1305 * Get local variables.
1307 std::list
<ExprValue
*> newVars
;
1308 parseLocals(output
, newVars
);
1311 * Clear any old VarTree item pointers, so that later we don't access
1312 * dangling pointers.
1314 m_localVariables
.clearPendingUpdates();
1317 * Match old variables against new ones.
1319 for (QStringList::ConstIterator n
= oldVars
.begin(); n
!= oldVars
.end(); ++n
) {
1320 // lookup this variable in the list of new variables
1321 std::list
<ExprValue
*>::iterator v
= newVars
.begin();
1322 while (v
!= newVars
.end() && (*v
)->m_name
!= *n
)
1324 if (v
== newVars
.end()) {
1325 // old variable not in the new variables
1326 TRACE("old var deleted: " + *n
);
1327 VarTree
* v
= m_localVariables
.topLevelExprByName(*n
);
1329 m_localVariables
.removeExpr(v
);
1332 // variable in both old and new lists: update
1333 TRACE("update var: " + *n
);
1334 m_localVariables
.updateExpr(*v
, *m_typeTable
);
1335 // remove the new variable from the list
1340 // insert all remaining new variables
1341 while (!newVars
.empty())
1343 ExprValue
* v
= newVars
.front();
1344 TRACE("new var: " + v
->m_name
);
1345 m_localVariables
.insertExpr(v
, *m_typeTable
);
1347 newVars
.pop_front();
1351 void KDebugger::parseLocals(const char* output
, std::list
<ExprValue
*>& newVars
)
1353 std::list
<ExprValue
*> vars
;
1354 m_d
->parseLocals(output
, vars
);
1356 QString origName
; /* used in renaming variables */
1357 while (!vars
.empty())
1359 ExprValue
* variable
= vars
.front();
1362 * When gdb prints local variables, those from the innermost block
1363 * come first. We run through the list of already parsed variables
1364 * to find duplicates (ie. variables that hide local variables from
1365 * a surrounding block). We keep the name of the inner variable, but
1366 * rename those from the outer block so that, when the value is
1367 * updated in the window, the value of the variable that is
1368 * _visible_ changes the color!
1371 origName
= variable
->m_name
;
1372 for (std::list
<ExprValue
*>::iterator v
= newVars
.begin(); v
!= newVars
.end(); ++v
) {
1373 if (variable
->m_name
== (*v
)->m_name
) {
1374 // we found a duplicate, change name
1376 QString newName
= origName
+ " (" + QString().setNum(block
) + ")";
1377 variable
->m_name
= newName
;
1380 newVars
.push_back(variable
);
1384 bool KDebugger::handlePrint(CmdQueueItem
* cmd
, const char* output
)
1386 ASSERT(cmd
->m_expr
!= 0);
1388 ExprValue
* variable
= m_d
->parsePrintExpr(output
, true);
1392 // set expression "name"
1393 variable
->m_name
= cmd
->m_expr
->getText();
1396 TRACE("update expr: " + cmd
->m_expr
->getText());
1397 cmd
->m_exprWnd
->updateExpr(cmd
->m_expr
, variable
, *m_typeTable
);
1401 evalExpressions(); /* enqueue dereferenced pointers */
1406 bool KDebugger::handlePrintDeref(CmdQueueItem
* cmd
, const char* output
)
1408 ASSERT(cmd
->m_expr
!= 0);
1410 ExprValue
* variable
= m_d
->parsePrintExpr(output
, true);
1414 // set expression "name"
1415 variable
->m_name
= cmd
->m_expr
->getText();
1419 * We must insert a dummy parent, because otherwise variable's value
1420 * would overwrite cmd->m_expr's value.
1422 ExprValue
* dummyParent
= new ExprValue(variable
->m_name
, VarTree::NKplain
);
1423 dummyParent
->m_varKind
= VarTree::VKdummy
;
1424 // the name of the parsed variable is the address of the pointer
1425 QString addr
= "*" + cmd
->m_expr
->value();
1426 variable
->m_name
= addr
;
1427 variable
->m_nameKind
= VarTree::NKaddress
;
1429 dummyParent
->m_child
= variable
;
1430 // expand the first level for convenience
1431 variable
->m_initiallyExpanded
= true;
1432 TRACE("update ptr: " + cmd
->m_expr
->getText());
1433 cmd
->m_exprWnd
->updateExpr(cmd
->m_expr
, dummyParent
, *m_typeTable
);
1437 evalExpressions(); /* enqueue dereferenced pointers */
1442 // parse the output of bt
1443 void KDebugger::handleBacktrace(const char* output
)
1447 std::list
<StackFrame
> stack
;
1448 m_d
->parseBackTrace(output
, stack
);
1450 if (!stack
.empty()) {
1451 std::list
<StackFrame
>::iterator frm
= stack
.begin();
1452 // first frame must set PC
1453 // note: frm->lineNo is zero-based
1454 emit
updatePC(frm
->fileName
, frm
->lineNo
, frm
->address
, frm
->frameNo
);
1456 for (; frm
!= stack
.end(); ++frm
) {
1459 func
= frm
->var
->m_name
;
1461 func
= frm
->fileName
+ ":" + QString().setNum(frm
->lineNo
+1);
1463 m_btWindow
.addItem(func
);
1464 TRACE("frame " + func
+ " (" + frm
->fileName
+ ":" +
1465 QString().setNum(frm
->lineNo
+1) + ")");
1471 void KDebugger::gotoFrame(int frame
)
1473 m_d
->executeCmd(DCframe
, frame
);
1476 void KDebugger::handleFrameChange(const char* output
)
1482 if (m_d
->parseFrameChange(output
, frameNo
, fileName
, lineNo
, address
)) {
1483 /* lineNo can be negative here if we can't find a file name */
1484 emit
updatePC(fileName
, lineNo
, address
, frameNo
);
1486 emit
updatePC(fileName
, -1, address
, frameNo
);
1490 void KDebugger::evalExpressions()
1492 // evaluate expressions in the following order:
1493 // watch expressions
1494 // pointers in local variables
1495 // pointers in watch expressions
1496 // types in local variables
1497 // types in watch expressions
1498 // struct members in local variables
1499 // struct members in watch expressions
1500 VarTree
* exprItem
= 0;
1501 if (!m_watchEvalExpr
.empty())
1503 QString expr
= m_watchEvalExpr
.front();
1504 m_watchEvalExpr
.pop_front();
1505 exprItem
= m_watchVariables
.topLevelExprByName(expr
);
1507 if (exprItem
!= 0) {
1508 CmdQueueItem
* cmd
= m_d
->queueCmd(DCprint
, exprItem
->getText(), DebuggerDriver::QMoverride
);
1509 // remember which expr this was
1510 cmd
->m_expr
= exprItem
;
1511 cmd
->m_exprWnd
= &m_watchVariables
;
1514 #define POINTER(widget) \
1516 exprItem = widget.nextUpdatePtr(); \
1517 if (exprItem != 0) goto pointer
1518 #define STRUCT(widget) \
1520 exprItem = widget.nextUpdateStruct(); \
1521 if (exprItem != 0) goto ustruct
1522 #define TYPE(widget) \
1524 exprItem = widget.nextUpdateType(); \
1525 if (exprItem != 0) goto type
1527 POINTER(m_localVariables
);
1528 POINTER(m_watchVariables
);
1529 STRUCT(m_localVariables
);
1530 STRUCT(m_watchVariables
);
1531 TYPE(m_localVariables
);
1532 TYPE(m_watchVariables
);
1539 // we have an expression to send
1540 dereferencePointer(wnd
, exprItem
, false);
1545 if (exprItem
->m_type
== 0 || exprItem
->m_type
== TypeInfo::unknownType())
1547 evalInitialStructExpression(exprItem
, wnd
, false);
1552 * Sometimes a VarTree gets registered twice for a type update. So
1553 * it may happen that it has already been updated. Hence, we ignore
1554 * it here and go on to the next task.
1556 if (exprItem
->m_type
!= 0)
1558 determineType(wnd
, exprItem
);
1562 void KDebugger::dereferencePointer(ExprWnd
* wnd
, VarTree
* exprItem
,
1565 ASSERT(exprItem
->m_varKind
== VarTree::VKpointer
);
1567 QString expr
= exprItem
->computeExpr();
1568 TRACE("dereferencing pointer: " + expr
);
1571 cmd
= m_d
->queueCmd(DCprintDeref
, expr
, DebuggerDriver::QMoverrideMoreEqual
);
1573 cmd
= m_d
->queueCmd(DCprintDeref
, expr
, DebuggerDriver::QMoverride
);
1575 // remember which expr this was
1576 cmd
->m_expr
= exprItem
;
1577 cmd
->m_exprWnd
= wnd
;
1580 void KDebugger::determineType(ExprWnd
* wnd
, VarTree
* exprItem
)
1582 ASSERT(exprItem
->m_varKind
== VarTree::VKstruct
);
1584 QString expr
= exprItem
->computeExpr();
1585 TRACE("get type of: " + expr
);
1587 cmd
= m_d
->queueCmd(DCfindType
, expr
, DebuggerDriver::QMoverride
);
1589 // remember which expr this was
1590 cmd
->m_expr
= exprItem
;
1591 cmd
->m_exprWnd
= wnd
;
1594 void KDebugger::handleFindType(CmdQueueItem
* cmd
, const char* output
)
1597 if (m_d
->parseFindType(output
, type
))
1599 ASSERT(cmd
!= 0 && cmd
->m_expr
!= 0);
1601 const TypeInfo
* info
= m_typeTable
->lookup(type
);
1605 * We've asked gdb for the type of the expression in
1606 * cmd->m_expr, but it returned a name we don't know. The base
1607 * class (and member) types have been checked already (at the
1608 * time when we parsed that particular expression). Now it's
1609 * time to derive the type from the base classes as a last
1612 info
= cmd
->m_expr
->inferTypeFromBaseClass();
1613 // if we found a type through this method, register an alias
1615 TRACE("infered alias: " + type
);
1616 m_typeTable
->registerAlias(type
, info
);
1620 TRACE("unknown type "+type
);
1621 cmd
->m_expr
->m_type
= TypeInfo::unknownType();
1623 cmd
->m_expr
->m_type
= info
;
1624 /* since this node has a new type, we get its value immediately */
1625 evalInitialStructExpression(cmd
->m_expr
, cmd
->m_exprWnd
, false);
1630 evalExpressions(); /* queue more of them */
1633 void KDebugger::handlePrintStruct(CmdQueueItem
* cmd
, const char* output
)
1635 VarTree
* var
= cmd
->m_expr
;
1637 ASSERT(var
->m_varKind
== VarTree::VKstruct
);
1639 ExprValue
* partExpr
;
1640 if (cmd
->m_cmd
== DCprintQStringStruct
) {
1641 partExpr
= m_d
->parseQCharArray(output
, false, m_typeTable
->qCharIsShort());
1642 } else if (cmd
->m_cmd
== DCprintWChar
) {
1643 partExpr
= m_d
->parseQCharArray(output
, false, true);
1645 partExpr
= m_d
->parsePrintExpr(output
, false);
1649 /* we only allow simple values at the moment */
1650 partExpr
->m_child
!= 0;
1655 partValue
= "?""?""?"; // 2 question marks in a row would be a trigraph
1657 partValue
= partExpr
->m_value
;
1663 * Updating a struct value works like this: var->m_partialValue holds
1664 * the value that we have gathered so far (it's been initialized with
1665 * var->m_type->m_displayString[0] earlier). Each time we arrive here,
1666 * we append the printed result followed by the next
1667 * var->m_type->m_displayString to var->m_partialValue.
1669 * If the expression we just evaluated was a guard expression, and it
1670 * resulted in an error, we must not evaluate the real expression, but
1671 * go on to the next index. (We must still add the question marks to
1674 * Next, if this was the length expression, we still have not seen the
1675 * real expression, but the length of a QString.
1677 ASSERT(var
->m_exprIndex
>= 0 && var
->m_exprIndex
<= typeInfoMaxExpr
);
1679 if (errorValue
|| !var
->m_exprIndexUseGuard
)
1681 // add current partValue (which might be the question marks)
1682 var
->m_partialValue
+= partValue
;
1683 var
->m_exprIndex
++; /* next part */
1684 var
->m_exprIndexUseGuard
= true;
1685 var
->m_partialValue
+= var
->m_type
->m_displayString
[var
->m_exprIndex
];
1689 // this was a guard expression that succeeded
1690 // go for the real expression
1691 var
->m_exprIndexUseGuard
= false;
1694 /* go for more sub-expressions if needed */
1695 if (var
->m_exprIndex
< var
->m_type
->m_numExprs
) {
1696 /* queue a new print command with quite high priority */
1697 evalStructExpression(var
, cmd
->m_exprWnd
, true);
1701 cmd
->m_exprWnd
->updateStructValue(var
);
1703 evalExpressions(); /* enqueue dereferenced pointers */
1706 /* queues the first printStruct command for a struct */
1707 void KDebugger::evalInitialStructExpression(VarTree
* var
, ExprWnd
* wnd
, bool immediate
)
1709 var
->m_exprIndex
= 0;
1710 if (var
->m_type
!= TypeInfo::wchartType())
1712 var
->m_exprIndexUseGuard
= true;
1713 var
->m_partialValue
= var
->m_type
->m_displayString
[0];
1714 evalStructExpression(var
, wnd
, immediate
);
1718 var
->m_exprIndexUseGuard
= false;
1719 QString expr
= var
->computeExpr();
1720 CmdQueueItem
* cmd
= m_d
->queueCmd(DCprintWChar
, expr
,
1721 immediate
? DebuggerDriver::QMoverrideMoreEqual
1722 : DebuggerDriver::QMoverride
);
1723 // remember which expression this was
1725 cmd
->m_exprWnd
= wnd
;
1729 /** queues a printStruct command; var must have been initialized correctly */
1730 void KDebugger::evalStructExpression(VarTree
* var
, ExprWnd
* wnd
, bool immediate
)
1732 QString base
= var
->computeExpr();
1734 if (var
->m_exprIndexUseGuard
) {
1735 expr
= var
->m_type
->m_guardStrings
[var
->m_exprIndex
];
1736 if (expr
.isEmpty()) {
1737 // no guard, omit it and go to expression
1738 var
->m_exprIndexUseGuard
= false;
1741 if (!var
->m_exprIndexUseGuard
) {
1742 expr
= var
->m_type
->m_exprStrings
[var
->m_exprIndex
];
1745 expr
.replace("%s", base
);
1747 DbgCommand dbgCmd
= DCprintStruct
;
1748 // check if this is a QString::Data
1749 if (expr
.left(15) == "/QString::Data ")
1751 if (m_typeTable
->parseQt2QStrings())
1753 expr
= expr
.mid(15, expr
.length()); /* strip off /QString::Data */
1754 dbgCmd
= DCprintQStringStruct
;
1757 * This should not happen: the type libraries should be set up
1758 * in a way that this can't happen. If this happens
1759 * nevertheless it means that, eg., kdecore was loaded but qt2
1760 * was not (only qt2 enables the QString feature).
1762 // TODO: remove this "print"; queue the next printStruct instead
1766 TRACE("evalStruct: " + expr
+ (var
->m_exprIndexUseGuard
? " // guard" : " // real"));
1767 CmdQueueItem
* cmd
= m_d
->queueCmd(dbgCmd
, expr
,
1768 immediate
? DebuggerDriver::QMoverrideMoreEqual
1769 : DebuggerDriver::QMnormal
);
1771 // remember which expression this was
1773 cmd
->m_exprWnd
= wnd
;
1776 void KDebugger::handleSharedLibs(const char* output
)
1778 // parse the table of shared libraries
1779 m_sharedLibs
= m_d
->parseSharedLibs(output
);
1780 m_sharedLibsListed
= true;
1782 // get type libraries
1783 m_typeTable
->loadLibTypes(m_sharedLibs
);
1785 // hand over the QString data cmd
1786 m_d
->setPrintQStringDataCmd(m_typeTable
->printQStringDataCmd());
1789 CmdQueueItem
* KDebugger::loadCoreFile()
1791 return m_d
->queueCmd(DCcorefile
, m_corefile
, DebuggerDriver::QMoverride
);
1794 void KDebugger::slotExpanding(QTreeWidgetItem
* item
)
1796 VarTree
* exprItem
= static_cast<VarTree
*>(item
);
1797 if (exprItem
->m_varKind
!= VarTree::VKpointer
) {
1800 ExprWnd
* wnd
= static_cast<ExprWnd
*>(item
->treeWidget());
1801 dereferencePointer(wnd
, exprItem
, true);
1804 // add the expression in the edit field to the watch expressions
1805 void KDebugger::addWatch(const QString
& t
)
1807 QString expr
= t
.trimmed();
1808 // don't add a watched expression again
1809 if (expr
.isEmpty() || m_watchVariables
.topLevelExprByName(expr
) != 0)
1811 ExprValue
e(expr
, VarTree::NKplain
);
1812 m_watchVariables
.insertExpr(&e
, *m_typeTable
);
1814 // if we are boring ourselves, send down the command
1815 if (m_programActive
) {
1816 m_watchEvalExpr
.push_back(expr
);
1817 if (m_d
->isIdle()) {
1823 // delete a toplevel watch expression
1824 void KDebugger::slotDeleteWatch()
1826 // delete only allowed while debugger is idle; or else we might delete
1827 // the very expression the debugger is currently working on...
1828 if (m_d
== 0 || !m_d
->isIdle())
1831 VarTree
* item
= m_watchVariables
.selectedItem();
1832 if (item
== 0 || !item
->isToplevelExpr())
1835 // remove the variable from the list to evaluate
1836 std::list
<QString
>::iterator i
=
1837 std::find(m_watchEvalExpr
.begin(), m_watchEvalExpr
.end(), item
->getText());
1838 if (i
!= m_watchEvalExpr
.end()) {
1839 m_watchEvalExpr
.erase(i
);
1841 m_watchVariables
.removeExpr(item
);
1842 // item is invalid at this point!
1845 void KDebugger::handleRegisters(const char* output
)
1847 emit
registersChanged(m_d
->parseRegisters(output
));
1851 * The output of the DCbreak* commands has more accurate information about
1852 * the file and the line number.
1854 * All newly set breakpoints are inserted in the m_brkpts, even those that
1855 * were not set sucessfully. The unsuccessful breakpoints ("orphaned
1856 * breakpoints") are assigned negative ids, and they are tried to set later
1857 * when the program stops again at a breakpoint.
1859 void KDebugger::newBreakpoint(CmdQueueItem
* cmd
, const char* output
)
1862 if (cmd
->m_brkpt
!= 0) {
1863 // a new breakpoint, put it in the list
1864 assert(cmd
->m_brkpt
->id
== 0);
1865 m_brkpts
.push_back(*cmd
->m_brkpt
);
1866 delete cmd
->m_brkpt
;
1867 bp
= m_brkpts
.end();
1870 // an existing breakpoint was retried
1871 assert(cmd
->m_existingBrkpt
!= 0);
1872 bp
= breakpointById(cmd
->m_existingBrkpt
);
1873 if (bp
== m_brkpts
.end())
1877 // parse the output to determine success or failure
1882 if (!m_d
->parseBreakpoint(output
, id
, file
, lineNo
, address
))
1885 * Failure, the breakpoint could not be set. If this is a new
1886 * breakpoint, assign it a negative id. We look for the minimal id
1887 * of all breakpoints (that are already in the list) to get the new
1893 for (BrkptIterator i
= m_brkpts
.begin(); i
!= m_brkpts
.end(); ++i
) {
1902 // The breakpoint was successfully set.
1905 // this is a new or orphaned breakpoint:
1906 // set the remaining properties
1908 m_d
->executeCmd(DCdisable
, id
);
1910 if (!bp
->condition
.isEmpty()) {
1911 m_d
->executeCmd(DCcondition
, bp
->condition
, id
);
1916 bp
->fileName
= file
;
1917 bp
->lineNo
= lineNo
;
1918 if (!address
.isEmpty())
1919 bp
->address
= address
;
1922 void KDebugger::updateBreakList(const char* output
)
1925 std::list
<Breakpoint
> brks
;
1926 m_d
->parseBreakList(output
, brks
);
1928 // merge existing information into the new list
1929 // then swap the old and new lists
1931 for (BrkptIterator bp
= brks
.begin(); bp
!= brks
.end(); ++bp
)
1933 BrkptIterator i
= breakpointById(bp
->id
);
1934 if (i
!= m_brkpts
.end())
1936 // preserve accurate location information
1937 // note that xsldbg doesn't have a location in
1938 // the listed breakpoint if it has just been set
1939 // therefore, we copy it as well if necessary
1941 if (!i
->fileName
.isEmpty()) {
1942 bp
->fileName
= i
->fileName
;
1943 bp
->lineNo
= i
->lineNo
;
1948 // orphaned breakpoints must be copied
1949 for (BrkptIterator bp
= m_brkpts
.begin(); bp
!= m_brkpts
.end(); ++bp
)
1951 if (bp
->isOrphaned())
1952 brks
.push_back(*bp
);
1955 m_brkpts
.swap(brks
);
1956 emit
breakpointsChanged();
1959 // look if there is at least one temporary breakpoint
1961 bool KDebugger::stopMayChangeBreakList() const
1963 for (BrkptROIterator bp
= m_brkpts
.begin(); bp
!= m_brkpts
.end(); ++bp
)
1965 if (bp
->temporary
|| bp
->type
== Breakpoint::watchpoint
)
1971 KDebugger::BrkptIterator
KDebugger::breakpointByFilePos(QString file
, int lineNo
,
1972 const DbgAddr
& address
)
1974 // look for exact file name match
1975 for (BrkptIterator bp
= m_brkpts
.begin(); bp
!= m_brkpts
.end(); ++bp
)
1977 if (bp
->lineNo
== lineNo
&&
1978 bp
->fileName
== file
&&
1979 (address
.isEmpty() || bp
->address
== address
))
1984 // not found, so try basename
1985 file
= QFileInfo(file
).fileName();
1987 for (BrkptIterator bp
= m_brkpts
.begin(); bp
!= m_brkpts
.end(); ++bp
)
1989 // get base name of breakpoint's file
1990 QString basename
= QFileInfo(bp
->fileName
).fileName();
1992 if (bp
->lineNo
== lineNo
&&
1994 (address
.isEmpty() || bp
->address
== address
))
2001 return m_brkpts
.end();
2004 KDebugger::BrkptIterator
KDebugger::breakpointById(int id
)
2006 for (BrkptIterator bp
= m_brkpts
.begin(); bp
!= m_brkpts
.end(); ++bp
)
2013 return m_brkpts
.end();
2016 void KDebugger::slotValuePopup(const QString
& expr
)
2018 // search the local variables for a match
2019 VarTree
* v
= m_localVariables
.topLevelExprByName(expr
);
2021 // not found, check watch expressions
2022 v
= m_watchVariables
.topLevelExprByName(expr
);
2024 // try a member of 'this'
2025 v
= m_localVariables
.topLevelExprByName("this");
2027 v
= ExprWnd::ptrMemberByName(v
, expr
);
2029 // nothing found; do nothing
2035 // construct the tip
2036 QString tip
= v
->getText() + " = ";
2037 if (!v
->value().isEmpty())
2043 // no value: we use some hint
2044 switch (v
->m_varKind
) {
2045 case VarTree::VKstruct
:
2048 case VarTree::VKarray
:
2052 tip
+= "?""?""?"; // 2 question marks in a row would be a trigraph
2056 emit
valuePopup(tip
);
2059 void KDebugger::slotDisassemble(const QString
& fileName
, int lineNo
)
2061 if (m_haveExecutable
) {
2062 CmdQueueItem
* cmd
= m_d
->queueCmd(DCinfoline
, fileName
, lineNo
,
2063 DebuggerDriver::QMoverrideMoreEqual
);
2064 cmd
->m_fileName
= fileName
;
2065 cmd
->m_lineNo
= lineNo
;
2069 void KDebugger::handleInfoLine(CmdQueueItem
* cmd
, const char* output
)
2071 QString addrFrom
, addrTo
;
2072 if (cmd
->m_lineNo
>= 0) {
2074 if (m_d
->parseInfoLine(output
, addrFrom
, addrTo
)) {
2075 // got the address range, now get the real code
2076 CmdQueueItem
* c
= m_d
->queueCmd(DCdisassemble
, addrFrom
, addrTo
,
2077 DebuggerDriver::QMoverrideMoreEqual
);
2078 c
->m_fileName
= cmd
->m_fileName
;
2079 c
->m_lineNo
= cmd
->m_lineNo
;
2082 emit
disassembled(cmd
->m_fileName
, cmd
->m_lineNo
, std::list
<DisassembledCode
>());
2085 // set program counter
2086 if (m_d
->parseInfoLine(output
, addrFrom
, addrTo
)) {
2087 // move the program counter to the start address
2088 m_d
->executeCmd(DCsetpc
, addrFrom
);
2093 void KDebugger::handleDisassemble(CmdQueueItem
* cmd
, const char* output
)
2095 emit
disassembled(cmd
->m_fileName
, cmd
->m_lineNo
,
2096 m_d
->parseDisassemble(output
));
2099 void KDebugger::handleThreadList(const char* output
)
2101 emit
threadsChanged(m_d
->parseThreadList(output
));
2104 void KDebugger::setThread(int id
)
2106 m_d
->queueCmd(DCthread
, id
, DebuggerDriver::QMoverrideMoreEqual
);
2109 void KDebugger::setMemoryExpression(const QString
& memexpr
)
2111 m_memoryExpression
= memexpr
;
2113 // queue the new expression
2114 if (!m_memoryExpression
.isEmpty() &&
2115 isProgramActive() &&
2116 !isProgramRunning())
2118 queueMemoryDump(true);
2122 void KDebugger::queueMemoryDump(bool immediate
)
2124 m_d
->queueCmd(DCexamine
, m_memoryExpression
, m_memoryFormat
,
2125 immediate
? DebuggerDriver::QMoverrideMoreEqual
:
2126 DebuggerDriver::QMoverride
);
2129 void KDebugger::handleMemoryDump(const char* output
)
2131 std::list
<MemoryDump
> memdump
;
2132 QString msg
= m_d
->parseMemoryDump(output
, memdump
);
2133 emit
memoryDumpChanged(msg
, memdump
);
2136 void KDebugger::setProgramCounter(const QString
& file
, int line
, const DbgAddr
& addr
)
2138 if (addr
.isEmpty()) {
2139 // find address of the specified line
2140 CmdQueueItem
* cmd
= m_d
->executeCmd(DCinfoline
, file
, line
);
2141 cmd
->m_lineNo
= -1; /* indicates "Set PC" UI command */
2143 // move the program counter to that address
2144 m_d
->executeCmd(DCsetpc
, addr
.asString());
2148 void KDebugger::handleSetPC(const char* /*output*/)
2150 // TODO: handle errors
2152 // now go to the top-most frame
2153 // this also modifies the program counter indicator in the UI
2157 void KDebugger::slotValueEdited(VarTree
* expr
, const QString
& text
)
2159 if (text
.simplified().isEmpty())
2160 return; /* no text entered: ignore request */
2162 ExprWnd
* wnd
= static_cast<ExprWnd
*>(expr
->treeWidget());
2163 TRACE(QString().sprintf("Changing %s to ",
2164 wnd
->name()) + text
);
2166 // determine the lvalue to edit
2167 QString lvalue
= expr
->computeExpr();
2168 CmdQueueItem
* cmd
= m_d
->executeCmd(DCsetvariable
, lvalue
, text
);
2170 cmd
->m_exprWnd
= wnd
;
2173 void KDebugger::handleSetVariable(CmdQueueItem
* cmd
, const char* output
)
2175 QString msg
= m_d
->parseSetVariable(output
);
2178 // there was an error; display it in the status bar
2179 m_statusMessage
= msg
;
2180 emit
updateStatusMessage();
2184 // get the new value
2185 QString expr
= cmd
->m_expr
->computeExpr();
2186 CmdQueueItem
* printCmd
=
2187 m_d
->queueCmd(DCprint
, expr
, DebuggerDriver::QMoverrideMoreEqual
);
2188 printCmd
->m_expr
= cmd
->m_expr
;
2189 printCmd
->m_exprWnd
= cmd
->m_exprWnd
;
2193 #include "debugger.moc"