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