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