3 // Copyright by Johannes Sixt
4 // This file is under GPL, the GNU General Public Licence
11 #include "pgmsettings.h"
14 #include <qfileinfo.h>
16 #include <qstringlist.h>
18 #include <ksimpleconfig.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
),
47 m_animationTimer(this),
48 m_animationInterval(0)
50 m_envVars
.setAutoDelete(true);
51 m_brkpts
.setAutoDelete(true);
53 connect(&m_localVariables
, SIGNAL(expanding(KTreeViewItem
*,bool&)),
54 SLOT(slotLocalsExpanding(KTreeViewItem
*,bool&)));
55 connect(&m_watchVariables
, SIGNAL(expanding(KTreeViewItem
*,bool&)),
56 SLOT(slotWatchExpanding(KTreeViewItem
*,bool&)));
58 connect(&m_btWindow
, SIGNAL(highlighted(int)), SLOT(gotoFrame(int)));
61 connect(&m_animationTimer
, SIGNAL(timeout()), SIGNAL(animationTimeout()));
62 // special update of animation
63 connect(this, SIGNAL(updateUI()), SLOT(slotUpdateAnimation()));
68 KDebugger::~KDebugger()
70 if (m_programConfig
!= 0) {
71 saveProgramSettings();
72 m_programConfig
->sync();
73 delete m_programConfig
;
80 void KDebugger::saveSettings(KConfig
* /*config*/)
84 void KDebugger::restoreSettings(KConfig
* /*config*/)
89 //////////////////////////////////////////////////////////////////////
92 const char GeneralGroup
[] = "General";
93 const char DebuggerCmdStr
[] = "DebuggerCmdStr";
94 const char TTYLevelEntry
[] = "TTYLevel";
95 const char KDebugger::DriverNameEntry
[] = "DriverName";
97 bool KDebugger::debugProgram(const QString
& name
,
98 DebuggerDriver
* driver
)
100 if (m_d
!= 0 && m_d
->isRunning())
102 QApplication::setOverrideCursor(waitCursor
);
106 QApplication::restoreOverrideCursor();
108 if (m_d
->isRunning() || m_haveExecutable
) {
109 /* timed out! We can't really do anything useful now */
110 TRACE("timed out while waiting for gdb to die!");
117 // wire up the driver
118 connect(driver
, SIGNAL(activateFileLine(const QString
&,int,const DbgAddr
&)),
119 this, SIGNAL(activateFileLine(const QString
&,int,const DbgAddr
&)));
120 connect(driver
, SIGNAL(processExited(KProcess
*)), SLOT(gdbExited(KProcess
*)));
121 connect(driver
, SIGNAL(commandReceived(CmdQueueItem
*,const char*)),
122 SLOT(parse(CmdQueueItem
*,const char*)));
123 connect(driver
, SIGNAL(wroteStdin(KProcess
*)), SIGNAL(updateUI()));
124 connect(driver
, SIGNAL(inferiorRunning()), SLOT(slotInferiorRunning()));
125 connect(driver
, SIGNAL(enterIdleState()), SLOT(backgroundUpdate()));
126 connect(driver
, SIGNAL(enterIdleState()), SIGNAL(updateUI()));
128 // create the program settings object
129 openProgramConfig(name
);
131 // get debugger command from per-program settings
132 if (m_programConfig
!= 0) {
133 m_programConfig
->setGroup(GeneralGroup
);
134 m_debuggerCmd
= m_programConfig
->readEntry(DebuggerCmdStr
);
135 // get terminal emulation level
136 m_ttyLevel
= TTYLevel(m_programConfig
->readNumEntry(TTYLevelEntry
, ttyFull
));
138 // the rest is read in later in the handler of DCexecutable
142 if (!startDriver()) {
143 TRACE("startDriver failed");
148 TRACE("before file cmd");
149 m_d
->executeCmd(DCexecutable
, name
);
153 if (!m_remoteDevice
.isEmpty()) {
154 m_d
->executeCmd(DCtargetremote
, m_remoteDevice
);
155 m_d
->queueCmd(DCbt
, DebuggerDriver::QMoverride
);
156 m_d
->queueCmd(DCframe
, 0, DebuggerDriver::QMnormal
);
157 m_programActive
= true;
158 m_haveExecutable
= true;
161 // create a type table
162 m_typeTable
= new ProgramTypeTable
;
163 m_sharedLibsListed
= false;
170 void KDebugger::shutdown()
172 // shut down debugger driver
173 if (m_d
!= 0 && m_d
->isRunning())
179 void KDebugger::useCoreFile(QString corefile
, bool batch
)
181 m_corefile
= corefile
;
183 CmdQueueItem
* cmd
= loadCoreFile();
184 cmd
->m_byUser
= true;
188 void KDebugger::programRun()
193 // when program is active, but not a core file, continue
194 // otherwise run the program
195 if (m_programActive
&& m_corefile
.isEmpty()) {
196 // gdb command: continue
197 m_d
->executeCmd(DCcont
, true);
200 m_d
->executeCmd(DCrun
, true);
201 m_corefile
= QString();
202 m_programActive
= true;
204 m_programRunning
= true;
207 void KDebugger::attachProgram(const QString
& pid
)
213 TRACE("Attaching to " + m_attachedPid
);
214 m_d
->executeCmd(DCattach
, m_attachedPid
);
215 m_programActive
= true;
216 m_programRunning
= true;
219 void KDebugger::programRunAgain()
221 if (canSingleStep()) {
222 m_d
->executeCmd(DCrun
, true);
223 m_corefile
= QString();
224 m_programRunning
= true;
228 void KDebugger::programStep()
230 if (canSingleStep()) {
231 m_d
->executeCmd(DCstep
, true);
232 m_programRunning
= true;
236 void KDebugger::programNext()
238 if (canSingleStep()) {
239 m_d
->executeCmd(DCnext
, true);
240 m_programRunning
= true;
244 void KDebugger::programStepi()
246 if (canSingleStep()) {
247 m_d
->executeCmd(DCstepi
, true);
248 m_programRunning
= true;
252 void KDebugger::programNexti()
254 if (canSingleStep()) {
255 m_d
->executeCmd(DCnexti
, true);
256 m_programRunning
= true;
260 void KDebugger::programFinish()
262 if (canSingleStep()) {
263 m_d
->executeCmd(DCfinish
, true);
264 m_programRunning
= true;
268 void KDebugger::programKill()
270 if (haveExecutable() && isProgramActive()) {
271 if (m_programRunning
) {
272 m_d
->interruptInferior();
274 // this is an emergency command; flush queues
275 m_d
->flushCommands(true);
276 m_d
->executeCmd(DCkill
, true);
280 bool KDebugger::runUntil(const QString
& fileName
, int lineNo
)
282 if (isReady() && m_programActive
&& !m_programRunning
) {
283 // strip off directory part of file name
284 QString file
= fileName
;
285 int offset
= file
.findRev("/");
287 file
.remove(0, offset
+1);
289 m_d
->executeCmd(DCuntil
, file
, lineNo
, true);
290 m_programRunning
= true;
297 void KDebugger::programBreak()
299 if (m_haveExecutable
&& m_programRunning
) {
300 m_d
->interruptInferior();
304 void KDebugger::programArgs(QWidget
* parent
)
306 if (m_haveExecutable
) {
307 QStringList allOptions
= m_d
->boolOptionList();
308 PgmArgs
dlg(parent
, m_executable
, m_envVars
, allOptions
);
309 dlg
.setArgs(m_programArgs
);
310 dlg
.setWd(m_programWD
);
311 dlg
.setOptions(m_boolOptions
);
313 updateProgEnvironment(dlg
.args(), dlg
.wd(),
314 dlg
.envVars(), dlg
.options());
319 void KDebugger::programSettings(QWidget
* parent
)
321 if (!m_haveExecutable
)
324 ProgramSettings
dlg(parent
, m_executable
);
326 dlg
.m_chooseDriver
.setDebuggerCmd(m_debuggerCmd
);
327 dlg
.m_output
.setTTYLevel(m_ttyLevel
);
329 if (dlg
.exec() == QDialog::Accepted
)
331 m_debuggerCmd
= dlg
.m_chooseDriver
.debuggerCmd();
332 m_ttyLevel
= TTYLevel(dlg
.m_output
.ttyLevel());
336 bool KDebugger::setBreakpoint(QString file
, int lineNo
,
337 const DbgAddr
& address
, bool temporary
)
343 Breakpoint
* bp
= breakpointByFilePos(file
, lineNo
, address
);
347 * No such breakpoint, so set a new one. If we have an address, we
348 * set the breakpoint exactly there. Otherwise we use the file name
351 Breakpoint
* bp
= new Breakpoint
;
352 bp
->temporary
= temporary
;
354 if (address
.isEmpty())
361 bp
->address
= address
;
363 setBreakpoint(bp
, false);
368 * If the breakpoint is disabled, enable it; if it's enabled,
369 * delete that breakpoint.
372 deleteBreakpoint(bp
);
374 enableDisableBreakpoint(bp
);
380 void KDebugger::setBreakpoint(Breakpoint
* bp
, bool queueOnly
)
383 if (!bp
->text
.isEmpty())
386 * The breakpoint was set using the text box in the breakpoint
387 * list. This is the only way in which watchpoints are set.
389 if (bp
->type
== Breakpoint::watchpoint
) {
390 cmd
= m_d
->executeCmd(DCwatchpoint
, bp
->text
);
392 cmd
= m_d
->executeCmd(DCbreaktext
, bp
->text
);
395 else if (bp
->address
.isEmpty())
397 // strip off directory part of file name
398 QString file
= bp
->fileName
;
399 int offset
= file
.findRev("/");
401 file
.remove(0, offset
+1);
404 cmd
= m_d
->queueCmd(bp
->temporary
? DCtbreakline
: DCbreakline
,
405 file
, bp
->lineNo
, DebuggerDriver::QMoverride
);
407 cmd
= m_d
->executeCmd(bp
->temporary
? DCtbreakline
: DCbreakline
,
414 cmd
= m_d
->queueCmd(bp
->temporary
? DCtbreakaddr
: DCbreakaddr
,
415 bp
->address
.asString(), DebuggerDriver::QMoverride
);
417 cmd
= m_d
->executeCmd(bp
->temporary
? DCtbreakaddr
: DCbreakaddr
,
418 bp
->address
.asString());
421 cmd
->m_brkpt
= bp
; // used in newBreakpoint()
424 bool KDebugger::enableDisableBreakpoint(QString file
, int lineNo
,
425 const DbgAddr
& address
)
427 Breakpoint
* bp
= breakpointByFilePos(file
, lineNo
, address
);
428 return bp
== 0 || enableDisableBreakpoint(bp
);
431 bool KDebugger::enableDisableBreakpoint(Breakpoint
* bp
)
434 * Toggle enabled/disabled state.
436 * The driver is not bothered if we are modifying an orphaned
439 if (!bp
->isOrphaned()) {
440 if (!canChangeBreakpoints()) {
443 m_d
->executeCmd(bp
->enabled
? DCdisable
: DCenable
, bp
->id
);
445 bp
->enabled
= !bp
->enabled
;
446 emit
breakpointsChanged();
451 bool KDebugger::conditionalBreakpoint(Breakpoint
* bp
,
452 const QString
& condition
,
456 * Change the condition and ignore count.
458 * The driver is not bothered if we are removing an orphaned
462 if (!bp
->isOrphaned()) {
463 if (!canChangeBreakpoints()) {
467 bool changed
= false;
469 if (bp
->condition
!= condition
) {
471 m_d
->executeCmd(DCcondition
, condition
, bp
->id
);
474 if (bp
->ignoreCount
!= ignoreCount
) {
475 // change ignore count
476 m_d
->executeCmd(DCignore
, bp
->id
, ignoreCount
);
481 m_d
->queueCmd(DCinfobreak
, DebuggerDriver::QMoverride
);
484 bp
->condition
= condition
;
485 bp
->ignoreCount
= ignoreCount
;
486 emit
breakpointsChanged();
491 bool KDebugger::deleteBreakpoint(Breakpoint
* bp
)
494 * Remove the breakpoint.
496 * The driver is not bothered if we are removing an orphaned
499 if (!bp
->isOrphaned()) {
500 if (!canChangeBreakpoints()) {
503 m_d
->executeCmd(DCdelete
, bp
->id
);
505 // move the last entry to bp's slot and shorten the list
506 int i
= m_brkpts
.findRef(bp
);
507 m_brkpts
.insert(i
, m_brkpts
.take(m_brkpts
.size()-1));
508 m_brkpts
.resize(m_brkpts
.size()-1);
509 emit
breakpointsChanged();
514 bool KDebugger::canSingleStep()
516 return isReady() && m_programActive
&& !m_programRunning
;
519 bool KDebugger::canChangeBreakpoints()
521 return isReady() && !m_programRunning
;
524 bool KDebugger::isReady() const
526 return m_haveExecutable
&&
527 m_d
!= 0 && m_d
->canExecuteImmediately();
530 bool KDebugger::isIdle() const
532 return m_d
== 0 || m_d
->isIdle();
536 //////////////////////////////////////////////////////////
539 bool KDebugger::startDriver()
541 emit
debuggerStarting(); /* must set m_inferiorTerminal */
544 * If the per-program command string is empty, use the global setting
545 * (which might also be empty, in which case the driver uses its
548 m_explicitKill
= false;
549 if (!m_d
->startup(m_debuggerCmd
)) {
554 * If we have an output terminal, we use it. Otherwise we will run the
555 * program with input and output redirected to /dev/null. Other
556 * redirections are also necessary depending on the tty emulation
559 int redirect
= RDNstdin
|RDNstdout
|RDNstderr
; /* redirect everything */
560 if (!m_inferiorTerminal
.isEmpty()) {
561 switch (m_ttyLevel
) {
564 // redirect everything
566 case ttySimpleOutputOnly
:
574 m_d
->executeCmd(DCtty
, m_inferiorTerminal
, redirect
);
579 void KDebugger::stopDriver()
581 m_explicitKill
= true;
583 if (m_attachedPid
.isEmpty()) {
586 m_d
->detachAndTerminate();
590 * We MUST wait until the slot gdbExited() has been called. But to
591 * avoid a deadlock, we wait only for some certain maximum time. Should
592 * this timeout be reached, the only reasonable thing one could do then
595 kapp
->processEvents(1000); /* ideally, this will already shut it down */
596 int maxTime
= 20; /* about 20 seconds */
597 while (m_haveExecutable
&& maxTime
> 0) {
598 // give gdb time to die (and send a SIGCLD)
601 kapp
->processEvents(1000);
605 void KDebugger::gdbExited(KProcess
*)
608 * Save settings, but only if gdb has already processed "info line
609 * main", otherwise we would save an empty config file, because it
610 * isn't read in until then!
612 if (m_programConfig
!= 0) {
613 if (m_haveExecutable
) {
614 saveProgramSettings();
615 m_programConfig
->sync();
617 delete m_programConfig
;
625 if (m_explicitKill
) {
626 TRACE(m_d
->driverName() + " exited normally");
628 QString msg
= i18n("%1 exited unexpectedly.\n"
629 "Restart the session (e.g. with File|Executable).");
630 KMessageBox::error(parentWidget(), msg
.arg(m_d
->driverName()));
634 m_haveExecutable
= false;
636 m_programActive
= false;
637 m_programRunning
= false;
638 m_explicitKill
= false;
639 m_debuggerCmd
= QString(); /* use global setting at next start! */
640 m_attachedPid
= QString(); /* we are no longer attached to a process */
641 m_ttyLevel
= ttyFull
;
644 // stop gear wheel and erase PC
646 emit
updatePC(QString(), -1, DbgAddr(), 0);
649 QString
KDebugger::getConfigForExe(const QString
& name
)
652 QString pgmConfigFile
= fi
.dirPath(true);
653 if (!pgmConfigFile
.isEmpty()) {
654 pgmConfigFile
+= '/';
656 pgmConfigFile
+= ".kdbgrc." + fi
.fileName();
657 TRACE("program config file = " + pgmConfigFile
);
658 return pgmConfigFile
;
661 void KDebugger::openProgramConfig(const QString
& name
)
663 ASSERT(m_programConfig
== 0);
665 QString pgmConfigFile
= getConfigForExe(name
);
666 // check whether we can write to the file
667 QFile
file(pgmConfigFile
);
668 bool readonly
= true;
670 if (file
.open(IO_ReadWrite
)) { /* don't truncate! */
672 // the file exists now
673 } else if (!file
.open(IO_ReadOnly
)) {
674 /* file does not exist and cannot be created: don't use it */
678 m_programConfig
= new KSimpleConfig(pgmConfigFile
, readonly
);
682 const char EnvironmentGroup
[] = "Environment";
683 const char WatchGroup
[] = "Watches";
684 const char FileVersion
[] = "FileVersion";
685 const char ProgramArgs
[] = "ProgramArgs";
686 const char WorkingDirectory
[] = "WorkingDirectory";
687 const char OptionsSelected
[] = "OptionsSelected";
688 const char Variable
[] = "Var%d";
689 const char Value
[] = "Value%d";
690 const char ExprFmt
[] = "Expr%d";
692 void KDebugger::saveProgramSettings()
694 ASSERT(m_programConfig
!= 0);
695 m_programConfig
->setGroup(GeneralGroup
);
696 m_programConfig
->writeEntry(FileVersion
, 1);
697 m_programConfig
->writeEntry(ProgramArgs
, m_programArgs
);
698 m_programConfig
->writeEntry(WorkingDirectory
, m_programWD
);
699 m_programConfig
->writeEntry(OptionsSelected
, m_boolOptions
);
700 m_programConfig
->writeEntry(DebuggerCmdStr
, m_debuggerCmd
);
701 m_programConfig
->writeEntry(TTYLevelEntry
, int(m_ttyLevel
));
704 driverName
= m_d
->driverName();
705 m_programConfig
->writeEntry(DriverNameEntry
, driverName
);
707 // write environment variables
708 m_programConfig
->deleteGroup(EnvironmentGroup
);
709 m_programConfig
->setGroup(EnvironmentGroup
);
710 QDictIterator
<EnvVar
> it
= m_envVars
;
714 for (int i
= 0; (var
= it
) != 0; ++it
, ++i
) {
715 varName
.sprintf(Variable
, i
);
716 varValue
.sprintf(Value
, i
);
717 m_programConfig
->writeEntry(varName
, it
.currentKey());
718 m_programConfig
->writeEntry(varValue
, var
->value
);
721 saveBreakpoints(m_programConfig
);
724 // first get rid of whatever was in this group
725 m_programConfig
->deleteGroup(WatchGroup
);
726 // then start a new group
727 m_programConfig
->setGroup(WatchGroup
);
728 KTreeViewItem
* item
= m_watchVariables
.itemAt(0);
730 for (; item
!= 0; item
= item
->getSibling(), ++watchNum
) {
731 varName
.sprintf(ExprFmt
, watchNum
);
732 m_programConfig
->writeEntry(varName
, item
->getText());
735 // give others a chance
736 emit
saveProgramSpecific(m_programConfig
);
739 void KDebugger::restoreProgramSettings()
741 ASSERT(m_programConfig
!= 0);
742 m_programConfig
->setGroup(GeneralGroup
);
744 * We ignore file version for now we will use it in the future to
745 * distinguish different versions of this configuration file.
747 m_debuggerCmd
= m_programConfig
->readEntry(DebuggerCmdStr
);
748 // m_ttyLevel has been read in already
749 QString pgmArgs
= m_programConfig
->readEntry(ProgramArgs
);
750 QString pgmWd
= m_programConfig
->readEntry(WorkingDirectory
);
751 QStringList boolOptions
= m_programConfig
->readListEntry(OptionsSelected
);
752 m_boolOptions
= QStringList();
754 // read environment variables
755 m_programConfig
->setGroup(EnvironmentGroup
);
757 QDict
<EnvVar
> pgmVars
;
761 for (int i
= 0;; ++i
) {
762 varName
.sprintf(Variable
, i
);
763 varValue
.sprintf(Value
, i
);
764 if (!m_programConfig
->hasKey(varName
)) {
765 /* entry not present, assume that we've hit them all */
768 QString name
= m_programConfig
->readEntry(varName
);
769 if (name
.isEmpty()) {
774 var
->value
= m_programConfig
->readEntry(varValue
);
775 var
->status
= EnvVar::EVnew
;
776 pgmVars
.insert(name
, var
);
779 updateProgEnvironment(pgmArgs
, pgmWd
, pgmVars
, boolOptions
);
781 restoreBreakpoints(m_programConfig
);
784 m_programConfig
->setGroup(WatchGroup
);
785 m_watchVariables
.clear();
786 for (int i
= 0;; ++i
) {
787 varName
.sprintf(ExprFmt
, i
);
788 if (!m_programConfig
->hasKey(varName
)) {
789 /* entry not present, assume that we've hit them all */
792 QString expr
= m_programConfig
->readEntry(varName
);
793 if (expr
.isEmpty()) {
794 // skip empty expressions
800 // give others a chance
801 emit
restoreProgramSpecific(m_programConfig
);
805 * Breakpoints are saved one per group.
807 const char BPGroup
[] = "Breakpoint %d";
808 const char File
[] = "File";
809 const char Line
[] = "Line";
810 const char Text
[] = "Text";
811 const char Address
[] = "Address";
812 const char Temporary
[] = "Temporary";
813 const char Enabled
[] = "Enabled";
814 const char Condition
[] = "Condition";
816 void KDebugger::saveBreakpoints(KSimpleConfig
* config
)
820 for (uint j
= 0; j
< m_brkpts
.size(); j
++) {
821 Breakpoint
* bp
= m_brkpts
[j
];
822 if (bp
->type
== Breakpoint::watchpoint
)
823 continue; /* don't save watchpoints */
824 groupName
.sprintf(BPGroup
, i
++);
826 /* remove remmants */
827 config
->deleteGroup(groupName
);
829 config
->setGroup(groupName
);
830 if (!bp
->text
.isEmpty()) {
832 * The breakpoint was set using the text box in the breakpoint
833 * list. We do not save the location by filename+line number,
834 * but instead honor what the user typed (a function name, for
835 * example, which could move between sessions).
837 config
->writeEntry(Text
, bp
->text
);
838 } else if (!bp
->fileName
.isEmpty()) {
839 config
->writeEntry(File
, bp
->fileName
);
840 config
->writeEntry(Line
, bp
->lineNo
);
842 * Addresses are hardly correct across sessions, so we don't
846 config
->writeEntry(Address
, bp
->address
.asString());
848 config
->writeEntry(Temporary
, bp
->temporary
);
849 config
->writeEntry(Enabled
, bp
->enabled
);
850 if (!bp
->condition
.isEmpty())
851 config
->writeEntry(Condition
, bp
->condition
);
852 // we do not save the ignore count
854 // delete remaining groups
855 // we recognize that a group is present if there is an Enabled entry
857 groupName
.sprintf(BPGroup
, i
);
858 config
->setGroup(groupName
);
859 if (!config
->hasKey(Enabled
)) {
860 /* group not present, assume that we've hit them all */
863 config
->deleteGroup(groupName
);
867 void KDebugger::restoreBreakpoints(KSimpleConfig
* config
)
871 * We recognize the end of the list if there is no Enabled entry
874 for (int i
= 0;; i
++) {
875 groupName
.sprintf(BPGroup
, i
);
876 config
->setGroup(groupName
);
877 if (!config
->hasKey(Enabled
)) {
878 /* group not present, assume that we've hit them all */
881 Breakpoint
* bp
= new Breakpoint
;
882 bp
->fileName
= config
->readEntry(File
);
883 bp
->lineNo
= config
->readNumEntry(Line
, -1);
884 bp
->text
= config
->readEntry(Text
);
885 bp
->address
= config
->readEntry(Address
);
887 if ((bp
->fileName
.isEmpty() || bp
->lineNo
< 0) &&
888 bp
->text
.isEmpty() &&
889 bp
->address
.isEmpty())
894 bp
->enabled
= config
->readBoolEntry(Enabled
, true);
895 bp
->temporary
= config
->readBoolEntry(Temporary
, false);
896 bp
->condition
= config
->readEntry(Condition
);
899 * Add the breakpoint.
901 setBreakpoint(bp
, false);
902 // the new breakpoint is disabled or conditionalized later
903 // in newBreakpoint()
905 m_d
->queueCmd(DCinfobreak
, DebuggerDriver::QMoverride
);
909 // parse output of command cmd
910 void KDebugger::parse(CmdQueueItem
* cmd
, const char* output
)
912 ASSERT(cmd
!= 0); /* queue mustn't be empty */
914 TRACE(QString(__PRETTY_FUNCTION__
) + " parsing " + output
);
916 switch (cmd
->m_cmd
) {
918 // the output (if any) is uninteresting
921 // there is no output
925 /* if value is empty, we see output, but we don't care */
928 /* display gdb's message in the status bar */
929 m_d
->parseChangeWD(output
, m_statusMessage
);
930 emit
updateStatusMessage();
935 if (m_d
->parseChangeExecutable(output
, m_statusMessage
))
937 // success; restore breakpoints etc.
938 if (m_programConfig
!= 0) {
939 restoreProgramSettings();
941 // load file containing main() or core file
942 if (m_corefile
.isEmpty()) {
943 if (m_remoteDevice
.isEmpty())
944 m_d
->queueCmd(DCinfolinemain
, DebuggerDriver::QMnormal
);
949 if (!m_statusMessage
.isEmpty())
950 emit
updateStatusMessage();
952 QString msg
= m_d
->driverName() + ": " + m_statusMessage
;
953 KMessageBox::sorry(parentWidget(), msg
);
955 m_corefile
= ""; /* don't process core file */
956 m_haveExecutable
= false;
960 // in any event we have an executable at this point
961 m_haveExecutable
= true;
962 if (m_d
->parseCoreFile(output
)) {
963 // loading a core is like stopping at a breakpoint
964 m_programActive
= true;
965 handleRunCommands(output
);
966 // do not reset m_corefile
969 QString msg
= m_d
->driverName() + ": " + QString(output
);
970 KMessageBox::sorry(parentWidget(), msg
);
972 // if core file was loaded from command line, revert to info line main
973 if (!cmd
->m_byUser
) {
974 m_d
->queueCmd(DCinfolinemain
, DebuggerDriver::QMnormal
);
976 m_corefile
= QString(); /* core file not available any more */
980 // ignore the output, marked file info follows
981 m_haveExecutable
= true;
984 // parse local variables
985 if (output
[0] != '\0') {
986 handleLocals(output
);
989 case DCinforegisters
:
990 handleRegisters(output
);
993 handleMemoryDump(output
);
996 handleInfoLine(cmd
, output
);
999 handleDisassemble(cmd
, output
);
1002 handleFrameChange(output
);
1006 handleBacktrace(output
);
1010 handlePrint(cmd
, output
);
1022 handleRunCommands(output
);
1025 m_programRunning
= m_programActive
= false;
1027 emit
updatePC(QString(), -1, DbgAddr(), 0);
1035 newBreakpoint(cmd
, output
);
1040 // these commands need immediate response
1041 m_d
->queueCmd(DCinfobreak
, DebuggerDriver::QMoverrideMoreEqual
);
1044 // note: this handler must not enqueue a command, since
1045 // DCinfobreak is used at various different places.
1046 updateBreakList(output
);
1049 handleFindType(cmd
, output
);
1052 case DCprintQStringStruct
:
1053 handlePrintStruct(cmd
, output
);
1055 case DCinfosharedlib
:
1056 handleSharedLibs(output
);
1060 // we are not interested in the output
1063 handleThreadList(output
);
1066 handleSetPC(output
);
1071 void KDebugger::backgroundUpdate()
1074 * If there are still expressions that need to be updated, then do so.
1076 if (m_programActive
)
1080 void KDebugger::handleRunCommands(const char* output
)
1082 uint flags
= m_d
->parseProgramStopped(output
, m_statusMessage
);
1083 emit
updateStatusMessage();
1085 m_programActive
= flags
& DebuggerDriver::SFprogramActive
;
1087 // refresh files if necessary
1088 if (flags
& DebuggerDriver::SFrefreshSource
) {
1089 TRACE("re-reading files");
1090 emit
executableUpdated();
1094 * Try to set any orphaned breakpoints now.
1096 for (int i
= m_brkpts
.size()-1; i
>= 0; i
--) {
1097 if (m_brkpts
[i
]->isOrphaned()) {
1098 TRACE("re-trying brkpt loc: "+m_brkpts
[i
]->location
+
1099 " file: "+m_brkpts
[i
]->fileName
+
1100 QString().sprintf(" line: %d", m_brkpts
[i
]->lineNo
));
1101 setBreakpoint(m_brkpts
[i
], true);
1102 flags
|= DebuggerDriver::SFrefreshBreak
;
1107 * If we stopped at a breakpoint, we must update the breakpoint list
1108 * because the hit count changes. Also, if the breakpoint was temporary
1109 * it would go away now.
1111 if ((flags
& (DebuggerDriver::SFrefreshBreak
|DebuggerDriver::SFrefreshSource
)) ||
1112 stopMayChangeBreakList())
1114 m_d
->queueCmd(DCinfobreak
, DebuggerDriver::QMoverride
);
1118 * If we haven't listed the shared libraries yet, do so. We must do
1119 * this before we emit any commands that list variables, since the type
1120 * libraries depend on the shared libraries.
1122 if (!m_sharedLibsListed
) {
1123 // must be a high-priority command!
1124 m_d
->executeCmd(DCinfosharedlib
);
1127 // get the backtrace if the program is running
1128 if (m_programActive
) {
1129 m_d
->queueCmd(DCbt
, DebuggerDriver::QMoverride
);
1131 // program finished: erase PC
1132 emit
updatePC(QString(), -1, DbgAddr(), 0);
1133 // dequeue any commands in the queues
1134 m_d
->flushCommands();
1137 /* Update threads list */
1138 if (flags
& DebuggerDriver::SFrefreshThreads
) {
1139 m_d
->queueCmd(DCinfothreads
, DebuggerDriver::QMoverride
);
1142 m_programRunning
= false;
1143 emit
programStopped();
1146 void KDebugger::slotInferiorRunning()
1148 m_programRunning
= true;
1151 void KDebugger::updateAllExprs()
1153 if (!m_programActive
)
1156 // retrieve local variables
1157 m_d
->queueCmd(DCinfolocals
, DebuggerDriver::QMoverride
);
1159 // retrieve registers
1160 m_d
->queueCmd(DCinforegisters
, DebuggerDriver::QMoverride
);
1162 // get new memory dump
1163 if (!m_memoryExpression
.isEmpty()) {
1164 queueMemoryDump(false);
1167 // update watch expressions
1168 KTreeViewItem
* item
= m_watchVariables
.itemAt(0);
1169 for (; item
!= 0; item
= item
->getSibling()) {
1170 m_watchEvalExpr
.append(static_cast<VarTree
*>(item
));
1174 void KDebugger::updateProgEnvironment(const QString
& args
, const QString
& wd
,
1175 const QDict
<EnvVar
>& newVars
,
1176 const QStringList
& newOptions
)
1178 m_programArgs
= args
;
1179 m_d
->executeCmd(DCsetargs
, m_programArgs
);
1180 TRACE("new pgm args: " + m_programArgs
+ "\n");
1182 m_programWD
= wd
.stripWhiteSpace();
1183 if (!m_programWD
.isEmpty()) {
1184 m_d
->executeCmd(DCcd
, m_programWD
);
1185 TRACE("new wd: " + m_programWD
+ "\n");
1188 // update environment variables
1189 QDictIterator
<EnvVar
> it
= newVars
;
1191 for (; (val
= it
) != 0; ++it
) {
1192 QString var
= it
.currentKey();
1193 switch (val
->status
) {
1195 m_envVars
.insert(var
, val
);
1197 case EnvVar::EVdirty
:
1198 // the value must be in our list
1199 ASSERT(m_envVars
[var
] == val
);
1201 m_d
->executeCmd(DCsetenv
, var
, val
->value
);
1203 case EnvVar::EVdeleted
:
1204 // must be in our list
1205 ASSERT(m_envVars
[var
] == val
);
1207 m_d
->executeCmd(DCunsetenv
, var
);
1208 m_envVars
.remove(var
);
1212 case EnvVar::EVclean
:
1213 // variable not changed
1219 QStringList::ConstIterator oi
;
1220 for (oi
= newOptions
.begin(); oi
!= newOptions
.end(); ++oi
)
1222 if (m_boolOptions
.findIndex(*oi
) < 0) {
1223 // the options is currently not set, so set it
1224 m_d
->executeCmd(DCsetoption
, *oi
, 1);
1226 // option is set, no action required, but move it to the end
1227 m_boolOptions
.remove(*oi
);
1229 m_boolOptions
.append(*oi
);
1232 * Now all options that should be set are at the end of m_boolOptions.
1233 * If some options need to be unset, they are at the front of the list.
1234 * Here we unset and remove them.
1236 while (m_boolOptions
.count() > newOptions
.count()) {
1237 m_d
->executeCmd(DCsetoption
, m_boolOptions
.first(), 0);
1238 m_boolOptions
.remove(m_boolOptions
.begin());
1242 void KDebugger::handleLocals(const char* output
)
1244 // retrieve old list of local variables
1246 m_localVariables
.exprList(oldVars
);
1249 * Get local variables.
1251 QList
<VarTree
> newVars
;
1252 parseLocals(output
, newVars
);
1255 * Clear any old VarTree item pointers, so that later we don't access
1256 * dangling pointers.
1258 m_localVariables
.clearPendingUpdates();
1261 bool autoU
= m_localVariables
.autoUpdate();
1262 m_localVariables
.setAutoUpdate(false);
1263 bool repaintNeeded
= false;
1266 * Match old variables against new ones.
1268 for (const char* n
= oldVars
.first(); n
!= 0; n
= oldVars
.next()) {
1269 // lookup this variable in the list of new variables
1270 VarTree
* v
= newVars
.first();
1271 while (v
!= 0 && strcmp(v
->getText(), n
) != 0) {
1275 // old variable not in the new variables
1276 TRACE(QString("old var deleted: ") + n
);
1277 v
= m_localVariables
.topLevelExprByName(n
);
1278 removeExpr(&m_localVariables
, v
);
1279 if (v
!= 0) repaintNeeded
= true;
1281 // variable in both old and new lists: update
1282 TRACE(QString("update var: ") + n
);
1283 m_localVariables
.updateExpr(newVars
.current());
1284 // remove the new variable from the list
1287 repaintNeeded
= true;
1290 // insert all remaining new variables
1291 for (VarTree
* v
= newVars
.first(); v
!= 0; v
= newVars
.next()) {
1292 TRACE("new var: " + v
->getText());
1293 m_localVariables
.insertExpr(v
);
1294 repaintNeeded
= true;
1298 m_localVariables
.setAutoUpdate(autoU
);
1299 if (repaintNeeded
&& autoU
&& m_localVariables
.isVisible())
1300 m_localVariables
.repaint();
1303 void KDebugger::parseLocals(const char* output
, QList
<VarTree
>& newVars
)
1305 QList
<VarTree
> vars
;
1306 m_d
->parseLocals(output
, vars
);
1308 QString origName
; /* used in renaming variables */
1309 while (vars
.count() > 0)
1311 VarTree
* variable
= vars
.take(0);
1313 variable
->inferTypesOfChildren(*m_typeTable
);
1315 * When gdb prints local variables, those from the innermost block
1316 * come first. We run through the list of already parsed variables
1317 * to find duplicates (ie. variables that hide local variables from
1318 * a surrounding block). We keep the name of the inner variable, but
1319 * rename those from the outer block so that, when the value is
1320 * updated in the window, the value of the variable that is
1321 * _visible_ changes the color!
1324 origName
= variable
->getText();
1325 for (VarTree
* v
= newVars
.first(); v
!= 0; v
= newVars
.next()) {
1326 if (variable
->getText() == v
->getText()) {
1327 // we found a duplicate, change name
1329 QString newName
= origName
+ " (" + QString().setNum(block
) + ")";
1330 variable
->setText(newName
);
1333 newVars
.append(variable
);
1337 bool KDebugger::handlePrint(CmdQueueItem
* cmd
, const char* output
)
1339 ASSERT(cmd
->m_expr
!= 0);
1341 VarTree
* variable
= parseExpr(output
, true);
1345 // set expression "name"
1346 variable
->setText(cmd
->m_expr
->getText());
1348 if (cmd
->m_expr
->m_varKind
== VarTree::VKpointer
) {
1350 * We must insert a dummy parent, because otherwise variable's value
1351 * would overwrite cmd->m_expr's value.
1353 VarTree
* dummyParent
= new VarTree(variable
->getText(), VarTree::NKplain
);
1354 dummyParent
->m_varKind
= VarTree::VKdummy
;
1355 // the name of the parsed variable is the address of the pointer
1356 QString addr
= "*" + cmd
->m_expr
->m_value
;
1357 variable
->setText(addr
);
1358 variable
->m_nameKind
= VarTree::NKaddress
;
1360 dummyParent
->appendChild(variable
);
1361 dummyParent
->setDeleteChildren(true);
1362 // expand the first level for convenience
1363 variable
->setExpanded(true);
1364 TRACE("update ptr: " + cmd
->m_expr
->getText());
1365 cmd
->m_exprWnd
->updateExpr(cmd
->m_expr
, dummyParent
);
1368 TRACE("update expr: " + cmd
->m_expr
->getText());
1369 cmd
->m_exprWnd
->updateExpr(cmd
->m_expr
, variable
);
1373 evalExpressions(); /* enqueue dereferenced pointers */
1378 VarTree
* KDebugger::parseExpr(const char* output
, bool wantErrorValue
)
1382 // check for error conditions
1383 bool goodValue
= m_d
->parsePrintExpr(output
, wantErrorValue
, variable
);
1385 if (variable
!= 0 && goodValue
)
1388 variable
->inferTypesOfChildren(*m_typeTable
);
1393 // parse the output of bt
1394 void KDebugger::handleBacktrace(const char* output
)
1397 m_btWindow
.setAutoUpdate(false);
1401 QList
<StackFrame
> stack
;
1402 m_d
->parseBackTrace(output
, stack
);
1404 if (stack
.count() > 0) {
1405 StackFrame
* frm
= stack
.take(0);
1406 // first frame must set PC
1407 // note: frm->lineNo is zero-based
1408 emit
updatePC(frm
->fileName
, frm
->lineNo
, frm
->address
, frm
->frameNo
);
1413 func
= frm
->var
->getText();
1415 func
= frm
->fileName
+ ":" + QString().setNum(frm
->lineNo
+1);
1416 m_btWindow
.insertItem(func
);
1417 TRACE("frame " + func
+ " (" + frm
->fileName
+ ":" +
1418 QString().setNum(frm
->lineNo
+1) + ")");
1421 while ((frm
= stack
.take()) != 0);
1424 m_btWindow
.setAutoUpdate(true);
1425 m_btWindow
.repaint();
1428 void KDebugger::gotoFrame(int frame
)
1430 m_d
->executeCmd(DCframe
, frame
);
1433 void KDebugger::handleFrameChange(const char* output
)
1439 if (m_d
->parseFrameChange(output
, frameNo
, fileName
, lineNo
, address
)) {
1440 /* lineNo can be negative here if we can't find a file name */
1441 emit
updatePC(fileName
, lineNo
, address
, frameNo
);
1443 emit
updatePC(fileName
, -1, address
, frameNo
);
1447 void KDebugger::evalExpressions()
1449 // evaluate expressions in the following order:
1450 // watch expressions
1451 // pointers in local variables
1452 // pointers in watch expressions
1453 // types in local variables
1454 // types in watch expressions
1455 // pointers in 'this'
1458 VarTree
* exprItem
= m_watchEvalExpr
.first();
1459 if (exprItem
!= 0) {
1460 m_watchEvalExpr
.remove();
1461 QString expr
= exprItem
->computeExpr();
1462 TRACE("watch expr: " + expr
);
1463 CmdQueueItem
* cmd
= m_d
->queueCmd(DCprint
, expr
, DebuggerDriver::QMoverride
);
1464 // remember which expr this was
1465 cmd
->m_expr
= exprItem
;
1466 cmd
->m_exprWnd
= &m_watchVariables
;
1470 #define POINTER(widget) \
1472 exprItem = widget.nextUpdatePtr(); \
1473 if (exprItem != 0) goto pointer
1474 #define STRUCT(widget) \
1476 exprItem = widget.nextUpdateStruct(); \
1477 if (exprItem != 0) goto ustruct
1478 #define TYPE(widget) \
1480 exprItem = widget.nextUpdateType(); \
1481 if (exprItem != 0) goto type
1483 POINTER(m_localVariables
);
1484 POINTER(m_watchVariables
);
1485 STRUCT(m_localVariables
);
1486 STRUCT(m_watchVariables
);
1487 TYPE(m_localVariables
);
1488 TYPE(m_watchVariables
);
1495 // we have an expression to send
1496 dereferencePointer(wnd
, exprItem
, false);
1501 if (exprItem
->m_type
== 0 || exprItem
->m_type
== TypeInfo::unknownType())
1503 evalInitialStructExpression(exprItem
, wnd
, false);
1508 * Sometimes a VarTree gets registered twice for a type update. So
1509 * it may happen that it has already been updated. Hence, we ignore
1510 * it here and go on to the next task.
1512 if (exprItem
->m_type
!= 0)
1514 determineType(wnd
, exprItem
);
1518 void KDebugger::dereferencePointer(ExprWnd
* wnd
, VarTree
* exprItem
,
1521 ASSERT(exprItem
->m_varKind
== VarTree::VKpointer
);
1523 QString expr
= exprItem
->computeExpr();
1524 TRACE("dereferencing pointer: " + expr
);
1525 QString queueExpr
= "*(" + expr
+ ")";
1528 cmd
= m_d
->queueCmd(DCprint
, queueExpr
, DebuggerDriver::QMoverrideMoreEqual
);
1530 cmd
= m_d
->queueCmd(DCprint
, queueExpr
, DebuggerDriver::QMoverride
);
1532 // remember which expr this was
1533 cmd
->m_expr
= exprItem
;
1534 cmd
->m_exprWnd
= wnd
;
1537 void KDebugger::determineType(ExprWnd
* wnd
, VarTree
* exprItem
)
1539 ASSERT(exprItem
->m_varKind
== VarTree::VKstruct
);
1541 QString expr
= exprItem
->computeExpr();
1542 TRACE("get type of: " + expr
);
1544 cmd
= m_d
->queueCmd(DCfindType
, expr
, DebuggerDriver::QMoverride
);
1546 // remember which expr this was
1547 cmd
->m_expr
= exprItem
;
1548 cmd
->m_exprWnd
= wnd
;
1551 void KDebugger::handleFindType(CmdQueueItem
* cmd
, const char* output
)
1554 if (m_d
->parseFindType(output
, type
))
1556 ASSERT(cmd
!= 0 && cmd
->m_expr
!= 0);
1558 TypeInfo
* info
= m_typeTable
->lookup(type
);
1562 * We've asked gdb for the type of the expression in
1563 * cmd->m_expr, but it returned a name we don't know. The base
1564 * class (and member) types have been checked already (at the
1565 * time when we parsed that particular expression). Now it's
1566 * time to derive the type from the base classes as a last
1569 info
= cmd
->m_expr
->inferTypeFromBaseClass();
1570 // if we found a type through this method, register an alias
1572 TRACE("infered alias: " + type
);
1573 m_typeTable
->registerAlias(type
, info
);
1577 TRACE("unknown type");
1578 cmd
->m_expr
->m_type
= TypeInfo::unknownType();
1580 cmd
->m_expr
->m_type
= info
;
1581 /* since this node has a new type, we get its value immediately */
1582 evalInitialStructExpression(cmd
->m_expr
, cmd
->m_exprWnd
, false);
1587 evalExpressions(); /* queue more of them */
1590 void KDebugger::handlePrintStruct(CmdQueueItem
* cmd
, const char* output
)
1592 VarTree
* var
= cmd
->m_expr
;
1594 ASSERT(var
->m_varKind
== VarTree::VKstruct
);
1597 if (cmd
->m_cmd
!= DCprintQStringStruct
) {
1598 partExpr
= parseExpr(output
, false);
1600 partExpr
= m_d
->parseQCharArray(output
, false, m_typeTable
->qCharIsShort());
1604 /* we only allow simple values at the moment */
1605 partExpr
->childCount() != 0;
1610 partValue
= "?""?""?"; // 2 question marks in a row would be a trigraph
1612 partValue
= partExpr
->m_value
;
1618 * Updating a struct value works like this: var->m_partialValue holds
1619 * the value that we have gathered so far (it's been initialized with
1620 * var->m_type->m_displayString[0] earlier). Each time we arrive here,
1621 * we append the printed result followed by the next
1622 * var->m_type->m_displayString to var->m_partialValue.
1624 * If the expression we just evaluated was a guard expression, and it
1625 * resulted in an error, we must not evaluate the real expression, but
1626 * go on to the next index. (We must still add the question marks to
1629 * Next, if this was the length expression, we still have not seen the
1630 * real expression, but the length of a QString.
1632 ASSERT(var
->m_exprIndex
>= 0 && var
->m_exprIndex
<= typeInfoMaxExpr
);
1634 if (errorValue
|| !var
->m_exprIndexUseGuard
)
1636 // add current partValue (which might be the question marks)
1637 var
->m_partialValue
+= partValue
;
1638 var
->m_exprIndex
++; /* next part */
1639 var
->m_exprIndexUseGuard
= true;
1640 var
->m_partialValue
+= var
->m_type
->m_displayString
[var
->m_exprIndex
];
1644 // this was a guard expression that succeeded
1645 // go for the real expression
1646 var
->m_exprIndexUseGuard
= false;
1649 /* go for more sub-expressions if needed */
1650 if (var
->m_exprIndex
< var
->m_type
->m_numExprs
) {
1651 /* queue a new print command with quite high priority */
1652 evalStructExpression(var
, cmd
->m_exprWnd
, true);
1656 cmd
->m_exprWnd
->updateStructValue(var
);
1658 evalExpressions(); /* enqueue dereferenced pointers */
1661 /* queues the first printStruct command for a struct */
1662 void KDebugger::evalInitialStructExpression(VarTree
* var
, ExprWnd
* wnd
, bool immediate
)
1664 var
->m_exprIndex
= 0;
1665 var
->m_exprIndexUseGuard
= true;
1666 var
->m_partialValue
= var
->m_type
->m_displayString
[0];
1667 evalStructExpression(var
, wnd
, immediate
);
1670 /* queues a printStruct command; var must have been initialized correctly */
1671 void KDebugger::evalStructExpression(VarTree
* var
, ExprWnd
* wnd
, bool immediate
)
1673 QString base
= var
->computeExpr();
1675 if (var
->m_exprIndexUseGuard
) {
1676 exprFmt
= var
->m_type
->m_guardStrings
[var
->m_exprIndex
];
1677 if (exprFmt
.isEmpty()) {
1678 // no guard, omit it and go to expression
1679 var
->m_exprIndexUseGuard
= false;
1682 if (!var
->m_exprIndexUseGuard
) {
1683 exprFmt
= var
->m_type
->m_exprStrings
[var
->m_exprIndex
];
1686 SIZED_QString(expr
, exprFmt
.length() + base
.length() + 10);
1687 expr
.sprintf(exprFmt
, base
.data());
1689 DbgCommand dbgCmd
= DCprintStruct
;
1690 // check if this is a QString::Data
1691 if (strncmp(expr
, "/QString::Data ", 15) == 0)
1693 if (m_typeTable
->parseQt2QStrings())
1695 expr
= expr
.mid(15, expr
.length()); /* strip off /QString::Data */
1696 dbgCmd
= DCprintQStringStruct
;
1699 * This should not happen: the type libraries should be set up
1700 * in a way that this can't happen. If this happens
1701 * nevertheless it means that, eg., kdecore was loaded but qt2
1702 * was not (only qt2 enables the QString feature).
1704 // TODO: remove this "print"; queue the next printStruct instead
1710 TRACE("evalStruct: " + expr
+ (var
->m_exprIndexUseGuard
? " // guard" : " // real"));
1711 CmdQueueItem
* cmd
= m_d
->queueCmd(dbgCmd
, expr
,
1712 immediate
? DebuggerDriver::QMoverrideMoreEqual
1713 : DebuggerDriver::QMnormal
);
1715 // remember which expression this was
1717 cmd
->m_exprWnd
= wnd
;
1720 /* removes expression from window */
1721 void KDebugger::removeExpr(ExprWnd
* wnd
, VarTree
* var
)
1726 // must remove any references to var from command queues
1727 m_d
->dequeueCmdByVar(var
);
1729 wnd
->removeExpr(var
);
1732 void KDebugger::handleSharedLibs(const char* output
)
1734 // delete all known libraries
1735 m_sharedLibs
.clear();
1737 // parse the table of shared libraries
1738 m_d
->parseSharedLibs(output
, m_sharedLibs
);
1739 m_sharedLibsListed
= true;
1741 // get type libraries
1742 m_typeTable
->loadLibTypes(m_sharedLibs
);
1745 CmdQueueItem
* KDebugger::loadCoreFile()
1747 return m_d
->queueCmd(DCcorefile
, m_corefile
, DebuggerDriver::QMoverride
);
1750 void KDebugger::slotLocalsExpanding(KTreeViewItem
* item
, bool& allow
)
1752 exprExpandingHelper(&m_localVariables
, item
, allow
);
1755 void KDebugger::slotWatchExpanding(KTreeViewItem
* item
, bool& allow
)
1757 exprExpandingHelper(&m_watchVariables
, item
, allow
);
1760 void KDebugger::exprExpandingHelper(ExprWnd
* wnd
, KTreeViewItem
* item
, bool&)
1762 VarTree
* exprItem
= static_cast<VarTree
*>(item
);
1763 if (exprItem
->m_varKind
!= VarTree::VKpointer
) {
1766 dereferencePointer(wnd
, exprItem
, true);
1769 // add the expression in the edit field to the watch expressions
1770 void KDebugger::addWatch(const QString
& t
)
1772 QString expr
= t
.stripWhiteSpace();
1775 VarTree
* exprItem
= new VarTree(expr
, VarTree::NKplain
);
1776 m_watchVariables
.insertExpr(exprItem
);
1778 // if we are boring ourselves, send down the command
1779 if (m_programActive
) {
1780 m_watchEvalExpr
.append(exprItem
);
1781 if (m_d
->isIdle()) {
1787 // delete a toplevel watch expression
1788 void KDebugger::slotDeleteWatch()
1790 // delete only allowed while debugger is idle; or else we might delete
1791 // the very expression the debugger is currently working on...
1795 int index
= m_watchVariables
.currentItem();
1799 VarTree
* item
= static_cast<VarTree
*>(m_watchVariables
.itemAt(index
));
1800 if (!item
->isToplevelExpr())
1803 // remove the variable from the list to evaluate
1804 if (m_watchEvalExpr
.findRef(item
) >= 0) {
1805 m_watchEvalExpr
.remove();
1807 removeExpr(&m_watchVariables
, item
);
1808 // item is invalid at this point!
1811 void KDebugger::startAnimation(bool fast
)
1813 int interval
= fast
? 50 : 150;
1814 if (!m_animationTimer
.isActive()) {
1815 m_animationTimer
.start(interval
);
1816 } else if (m_animationInterval
!= interval
) {
1817 m_animationTimer
.changeInterval(interval
);
1819 m_animationInterval
= interval
;
1822 void KDebugger::stopAnimation()
1824 if (m_animationTimer
.isActive()) {
1825 m_animationTimer
.stop();
1826 m_animationInterval
= 0;
1830 void KDebugger::slotUpdateAnimation()
1836 * Slow animation while program is stopped (i.e. while variables
1839 bool slow
= isReady() && m_programActive
&& !m_programRunning
;
1840 startAnimation(!slow
);
1844 void KDebugger::handleRegisters(const char* output
)
1846 QList
<RegisterInfo
> regs
;
1847 m_d
->parseRegisters(output
, regs
);
1849 emit
registersChanged(regs
);
1852 regs
.setAutoDelete(true);
1856 * The output of the DCbreak* commands has more accurate information about
1857 * the file and the line number.
1859 * All newly set breakpoints are inserted in the m_brkpts, even those that
1860 * were not set sucessfully. The unsuccessful breakpoints ("orphaned
1861 * breakpoints") are assigned negative ids, and they are tried to set later
1862 * when the program stops again at a breakpoint.
1864 void KDebugger::newBreakpoint(CmdQueueItem
* cmd
, const char* output
)
1866 Breakpoint
* bp
= cmd
->m_brkpt
;
1871 // if this is a new breakpoint, put it in the list
1872 bool isNew
= !m_brkpts
.contains(bp
);
1874 assert(bp
->id
== 0);
1875 int n
= m_brkpts
.size();
1876 m_brkpts
.resize(n
+1);
1877 m_brkpts
.insert(n
, bp
);
1880 // parse the output to determine success or failure
1885 if (!m_d
->parseBreakpoint(output
, id
, file
, lineNo
, address
))
1888 * Failure, the breakpoint could not be set. If this is a new
1889 * breakpoint, assign it a negative id. We look for the minimal id
1890 * of all breakpoints (that are already in the list) to get the new
1895 assert(bp
->id
== 0);
1896 for (int i
= m_brkpts
.size()-2; i
>= 0; i
--) {
1897 if (m_brkpts
[i
]->id
< bp
->id
) {
1898 bp
->id
= m_brkpts
[i
]->id
;
1907 // The breakpoint was successfully set.
1910 // this is a new or orphaned breakpoint:
1911 // set the remaining properties
1912 if (!cmd
->m_brkpt
->enabled
) {
1913 m_d
->executeCmd(DCdisable
, id
);
1915 if (!cmd
->m_brkpt
->condition
.isEmpty()) {
1916 m_d
->executeCmd(DCcondition
, cmd
->m_brkpt
->condition
, id
);
1921 bp
->fileName
= file
;
1922 bp
->lineNo
= lineNo
;
1923 if (!address
.isEmpty())
1924 bp
->address
= address
;
1927 void KDebugger::updateBreakList(const char* output
)
1930 QList
<Breakpoint
> brks
;
1931 brks
.setAutoDelete(false);
1932 m_d
->parseBreakList(output
, brks
);
1934 // merge new information into existing breakpoints
1936 for (int i
= m_brkpts
.size()-1; i
>= 0; i
--) // decrement!
1938 // skip orphaned breakpoints
1939 if (m_brkpts
[i
]->id
< 0)
1942 for (Breakpoint
* bp
= brks
.first(); bp
!= 0; bp
= brks
.next())
1944 if (bp
->id
== m_brkpts
[i
]->id
) {
1945 // keep accurate location
1946 // except that xsldbg doesn't have a location in
1947 // the old breakpoint if it's just been set
1948 bp
->text
= m_brkpts
[i
]->text
;
1949 if (!m_brkpts
[i
]->fileName
.isEmpty()) {
1950 bp
->fileName
= m_brkpts
[i
]->fileName
;
1951 bp
->lineNo
= m_brkpts
[i
]->lineNo
;
1953 m_brkpts
.insert(i
, bp
); // old object is deleted
1958 * If we get here, this breakpoint is no longer present.
1960 * To delete the breakpoint at i, we place the last breakpoint in
1961 * the list into the slot i. This will delete the old object at i.
1962 * Then we shorten the list by one.
1964 m_brkpts
.insert(i
, m_brkpts
.take(m_brkpts
.size()-1));
1965 m_brkpts
.resize(m_brkpts
.size()-1);
1966 TRACE(QString().sprintf("deleted brkpt %d, have now %d brkpts", i
, m_brkpts
.size()));
1971 // brks may contain new breakpoints not already in m_brkpts
1972 for (const Breakpoint
* bp
= brks
.first(); bp
!= 0; bp
= brks
.next())
1975 for (uint i
= 0; i
< m_brkpts
.size(); i
++) {
1976 if (bp
->id
== m_brkpts
[i
]->id
) {
1982 int n
= m_brkpts
.size();
1983 m_brkpts
.resize(n
+1);
1984 m_brkpts
.insert(n
, bp
);
1988 emit
breakpointsChanged();
1991 // look if there is at least one temporary breakpoint
1993 bool KDebugger::stopMayChangeBreakList() const
1995 for (int i
= m_brkpts
.size()-1; i
>= 0; i
--) {
1996 Breakpoint
* bp
= m_brkpts
[i
];
1997 if (bp
->temporary
|| bp
->type
== Breakpoint::watchpoint
)
2003 Breakpoint
* KDebugger::breakpointByFilePos(QString file
, int lineNo
,
2004 const DbgAddr
& address
)
2006 // look for exact file name match
2008 for (i
= m_brkpts
.size()-1; i
>= 0; i
--) {
2009 if (m_brkpts
[i
]->lineNo
== lineNo
&&
2010 m_brkpts
[i
]->fileName
== file
&&
2011 (address
.isEmpty() || m_brkpts
[i
]->address
== address
))
2016 // not found, so try basename
2017 // strip off directory part of file name
2018 int offset
= file
.findRev("/");
2019 file
.remove(0, offset
+1);
2021 for (i
= m_brkpts
.size()-1; i
>= 0; i
--) {
2022 // get base name of breakpoint's file
2023 QString basename
= m_brkpts
[i
]->fileName
;
2024 int offset
= basename
.findRev("/");
2026 basename
.remove(0, offset
+1);
2029 if (m_brkpts
[i
]->lineNo
== lineNo
&&
2031 (address
.isEmpty() || m_brkpts
[i
]->address
== address
))
2041 Breakpoint
* KDebugger::breakpointById(int id
)
2043 for (int i
= m_brkpts
.size()-1; i
>= 0; i
--)
2045 if (m_brkpts
[i
]->id
== id
) {
2053 void KDebugger::slotValuePopup(const QString
& expr
)
2055 // search the local variables for a match
2056 VarTree
* v
= m_localVariables
.topLevelExprByName(expr
);
2058 // not found, check watch expressions
2059 v
= m_watchVariables
.topLevelExprByName(expr
);
2061 // nothing found; do nothing
2066 // construct the tip
2067 QString tip
= v
->getText() + " = ";
2068 if (!v
->m_value
.isEmpty())
2074 // no value: we use some hint
2075 switch (v
->m_varKind
) {
2076 case VarTree::VKstruct
:
2079 case VarTree::VKarray
:
2083 tip
+= "?""?""?"; // 2 question marks in a row would be a trigraph
2087 emit
valuePopup(tip
);
2090 void KDebugger::slotDisassemble(const QString
& fileName
, int lineNo
)
2092 CmdQueueItem
* cmd
= m_d
->queueCmd(DCinfoline
, fileName
, lineNo
,
2093 DebuggerDriver::QMoverrideMoreEqual
);
2094 cmd
->m_fileName
= fileName
;
2095 cmd
->m_lineNo
= lineNo
;
2098 void KDebugger::handleInfoLine(CmdQueueItem
* cmd
, const char* output
)
2100 QString addrFrom
, addrTo
;
2101 if (cmd
->m_lineNo
>= 0) {
2103 if (m_d
->parseInfoLine(output
, addrFrom
, addrTo
)) {
2104 // got the address range, now get the real code
2105 CmdQueueItem
* c
= m_d
->queueCmd(DCdisassemble
, addrFrom
, addrTo
,
2106 DebuggerDriver::QMoverrideMoreEqual
);
2107 c
->m_fileName
= cmd
->m_fileName
;
2108 c
->m_lineNo
= cmd
->m_lineNo
;
2111 QList
<DisassembledCode
> empty
;
2112 emit
disassembled(cmd
->m_fileName
, cmd
->m_lineNo
, empty
);
2115 // set program counter
2116 if (m_d
->parseInfoLine(output
, addrFrom
, addrTo
)) {
2117 // move the program counter to the start address
2118 m_d
->executeCmd(DCsetpc
, addrFrom
);
2123 void KDebugger::handleDisassemble(CmdQueueItem
* cmd
, const char* output
)
2125 QList
<DisassembledCode
> code
;
2126 code
.setAutoDelete(true);
2127 m_d
->parseDisassemble(output
, code
);
2128 emit
disassembled(cmd
->m_fileName
, cmd
->m_lineNo
, code
);
2131 void KDebugger::handleThreadList(const char* output
)
2133 QList
<ThreadInfo
> threads
;
2134 threads
.setAutoDelete(true);
2135 m_d
->parseThreadList(output
, threads
);
2136 emit
threadsChanged(threads
);
2139 void KDebugger::setThread(int id
)
2141 m_d
->queueCmd(DCthread
, id
, DebuggerDriver::QMoverrideMoreEqual
);
2144 void KDebugger::setMemoryExpression(const QString
& memexpr
)
2146 m_memoryExpression
= memexpr
;
2148 // queue the new expression
2149 if (!m_memoryExpression
.isEmpty() &&
2150 isProgramActive() &&
2151 !isProgramRunning())
2153 queueMemoryDump(true);
2157 void KDebugger::queueMemoryDump(bool immediate
)
2159 m_d
->queueCmd(DCexamine
, m_memoryExpression
, m_memoryFormat
,
2160 immediate
? DebuggerDriver::QMoverrideMoreEqual
:
2161 DebuggerDriver::QMoverride
);
2164 void KDebugger::handleMemoryDump(const char* output
)
2166 QList
<MemoryDump
> memdump
;
2167 memdump
.setAutoDelete(true);
2168 QString msg
= m_d
->parseMemoryDump(output
, memdump
);
2169 emit
memoryDumpChanged(msg
, memdump
);
2172 void KDebugger::setProgramCounter(const QString
& file
, int line
, const DbgAddr
& addr
)
2174 if (addr
.isEmpty()) {
2175 // find address of the specified line
2176 CmdQueueItem
* cmd
= m_d
->executeCmd(DCinfoline
, file
, line
);
2177 cmd
->m_lineNo
= -1; /* indicates "Set PC" UI command */
2179 // move the program counter to that address
2180 m_d
->executeCmd(DCsetpc
, addr
.asString());
2184 void KDebugger::handleSetPC(const char* /*output*/)
2186 // TODO: handle errors
2188 // now go to the top-most frame
2189 // this also modifies the program counter indicator in the UI
2194 #include "debugger.moc"