2 * Copyright Johannes Sixt
3 * This file is licensed under the GNU General Public License Version 2.
4 * See the file COPYING in the toplevel directory of the source directory.
10 #include "typetable.h"
12 #include "pgmsettings.h"
13 #include "programconfig.h"
16 #include <qfileinfo.h>
18 #include <qstringlist.h>
21 #include <klocale.h> /* i18n */
22 #include <kmessagebox.h>
24 #include <stdlib.h> /* strtol, atoi */
26 #include <unistd.h> /* sleep(3) */
31 KDebugger::KDebugger(QWidget
* parent
,
34 QListBox
* backtrace
) :
35 QObject(parent
, "debugger"),
37 m_memoryFormat(MDTword
| MDThex
),
38 m_haveExecutable(false),
39 m_programActive(false),
40 m_programRunning(false),
41 m_sharedLibsListed(false),
45 m_localVariables(*localVars
),
46 m_watchVariables(*watchVars
),
47 m_btWindow(*backtrace
)
49 m_envVars
.setAutoDelete(true);
50 m_brkpts
.setAutoDelete(true);
52 connect(&m_localVariables
, SIGNAL(expanded(QListViewItem
*)),
53 SLOT(slotExpanding(QListViewItem
*)));
54 connect(&m_watchVariables
, SIGNAL(expanded(QListViewItem
*)),
55 SLOT(slotExpanding(QListViewItem
*)));
56 connect(&m_localVariables
, SIGNAL(editValueCommitted(VarTree
*, const QString
&)),
57 SLOT(slotValueEdited(VarTree
*, const QString
&)));
58 connect(&m_watchVariables
, SIGNAL(editValueCommitted(VarTree
*, const QString
&)),
59 SLOT(slotValueEdited(VarTree
*, const QString
&)));
61 connect(&m_btWindow
, SIGNAL(highlighted(int)), SLOT(gotoFrame(int)));
66 KDebugger::~KDebugger()
68 if (m_programConfig
!= 0) {
69 saveProgramSettings();
70 m_programConfig
->sync();
71 delete m_programConfig
;
78 void KDebugger::saveSettings(KConfig
* /*config*/)
82 void KDebugger::restoreSettings(KConfig
* /*config*/)
87 //////////////////////////////////////////////////////////////////////
90 const char GeneralGroup
[] = "General";
91 const char DebuggerCmdStr
[] = "DebuggerCmdStr";
92 const char TTYLevelEntry
[] = "TTYLevel";
93 const char KDebugger::DriverNameEntry
[] = "DriverName";
95 bool KDebugger::debugProgram(const QString
& name
,
96 DebuggerDriver
* driver
)
98 if (m_d
!= 0 && m_d
->isRunning())
100 QApplication::setOverrideCursor(waitCursor
);
104 QApplication::restoreOverrideCursor();
106 if (m_d
->isRunning() || m_haveExecutable
) {
107 /* timed out! We can't really do anything useful now */
108 TRACE("timed out while waiting for gdb to die!");
115 // wire up the driver
116 connect(driver
, SIGNAL(activateFileLine(const QString
&,int,const DbgAddr
&)),
117 this, SIGNAL(activateFileLine(const QString
&,int,const DbgAddr
&)));
118 connect(driver
, SIGNAL(processExited(KProcess
*)), SLOT(gdbExited(KProcess
*)));
119 connect(driver
, SIGNAL(commandReceived(CmdQueueItem
*,const char*)),
120 SLOT(parse(CmdQueueItem
*,const char*)));
121 connect(driver
, SIGNAL(wroteStdin(KProcess
*)), SIGNAL(updateUI()));
122 connect(driver
, SIGNAL(inferiorRunning()), SLOT(slotInferiorRunning()));
123 connect(driver
, SIGNAL(enterIdleState()), SLOT(backgroundUpdate()));
124 connect(driver
, SIGNAL(enterIdleState()), SIGNAL(updateUI()));
125 connect(&m_localVariables
, SIGNAL(removingItem(VarTree
*)),
126 driver
, SLOT(dequeueCmdByVar(VarTree
*)));
127 connect(&m_watchVariables
, SIGNAL(removingItem(VarTree
*)),
128 driver
, SLOT(dequeueCmdByVar(VarTree
*)));
130 // create the program settings object
131 openProgramConfig(name
);
133 // get debugger command from per-program settings
134 if (m_programConfig
!= 0) {
135 m_programConfig
->setGroup(GeneralGroup
);
136 m_debuggerCmd
= readDebuggerCmd();
137 // get terminal emulation level
138 m_ttyLevel
= TTYLevel(m_programConfig
->readNumEntry(TTYLevelEntry
, ttyFull
));
140 // the rest is read in later in the handler of DCexecutable
144 if (!startDriver()) {
145 TRACE("startDriver failed");
150 TRACE("before file cmd");
151 m_d
->executeCmd(DCexecutable
, name
);
155 if (!m_remoteDevice
.isEmpty()) {
156 m_d
->executeCmd(DCtargetremote
, m_remoteDevice
);
157 m_d
->queueCmd(DCbt
, DebuggerDriver::QMoverride
);
158 m_d
->queueCmd(DCframe
, 0, DebuggerDriver::QMnormal
);
159 m_programActive
= true;
160 m_haveExecutable
= true;
163 // create a type table
164 m_typeTable
= new ProgramTypeTable
;
165 m_sharedLibsListed
= false;
172 void KDebugger::shutdown()
174 // shut down debugger driver
175 if (m_d
!= 0 && m_d
->isRunning())
181 void KDebugger::useCoreFile(QString corefile
, bool batch
)
183 m_corefile
= corefile
;
185 CmdQueueItem
* cmd
= loadCoreFile();
186 cmd
->m_byUser
= true;
190 void KDebugger::setAttachPid(const QString
& pid
)
195 void KDebugger::programRun()
200 // when program is active, but not a core file, continue
201 // otherwise run the program
202 if (m_programActive
&& m_corefile
.isEmpty()) {
203 // gdb command: continue
204 m_d
->executeCmd(DCcont
, true);
207 m_d
->executeCmd(DCrun
, true);
208 m_corefile
= QString();
209 m_programActive
= true;
211 m_programRunning
= true;
214 void KDebugger::attachProgram(const QString
& pid
)
220 TRACE("Attaching to " + m_attachedPid
);
221 m_d
->executeCmd(DCattach
, m_attachedPid
);
222 m_programActive
= true;
223 m_programRunning
= true;
226 void KDebugger::programRunAgain()
228 if (canSingleStep()) {
229 m_d
->executeCmd(DCrun
, true);
230 m_corefile
= QString();
231 m_programRunning
= true;
235 void KDebugger::programStep()
237 if (canSingleStep()) {
238 m_d
->executeCmd(DCstep
, true);
239 m_programRunning
= true;
243 void KDebugger::programNext()
245 if (canSingleStep()) {
246 m_d
->executeCmd(DCnext
, true);
247 m_programRunning
= true;
251 void KDebugger::programStepi()
253 if (canSingleStep()) {
254 m_d
->executeCmd(DCstepi
, true);
255 m_programRunning
= true;
259 void KDebugger::programNexti()
261 if (canSingleStep()) {
262 m_d
->executeCmd(DCnexti
, true);
263 m_programRunning
= true;
267 void KDebugger::programFinish()
269 if (canSingleStep()) {
270 m_d
->executeCmd(DCfinish
, true);
271 m_programRunning
= true;
275 void KDebugger::programKill()
277 if (haveExecutable() && isProgramActive()) {
278 if (m_programRunning
) {
279 m_d
->interruptInferior();
281 // this is an emergency command; flush queues
282 m_d
->flushCommands(true);
283 m_d
->executeCmd(DCkill
, true);
287 bool KDebugger::runUntil(const QString
& fileName
, int lineNo
)
289 if (isReady() && m_programActive
&& !m_programRunning
) {
290 // strip off directory part of file name
291 QString file
= fileName
;
292 int offset
= file
.findRev("/");
294 file
.remove(0, offset
+1);
296 m_d
->executeCmd(DCuntil
, file
, lineNo
, true);
297 m_programRunning
= true;
304 void KDebugger::programBreak()
306 if (m_haveExecutable
&& m_programRunning
) {
307 m_d
->interruptInferior();
311 void KDebugger::programArgs(QWidget
* parent
)
313 if (m_haveExecutable
) {
314 QStringList allOptions
= m_d
->boolOptionList();
315 PgmArgs
dlg(parent
, m_executable
, m_envVars
, allOptions
);
316 dlg
.setArgs(m_programArgs
);
317 dlg
.setWd(m_programWD
);
318 dlg
.setOptions(m_boolOptions
);
320 updateProgEnvironment(dlg
.args(), dlg
.wd(),
321 dlg
.envVars(), dlg
.options());
326 void KDebugger::programSettings(QWidget
* parent
)
328 if (!m_haveExecutable
)
331 ProgramSettings
dlg(parent
, m_executable
);
333 dlg
.m_chooseDriver
.setDebuggerCmd(m_debuggerCmd
);
334 dlg
.m_output
.setTTYLevel(m_ttyLevel
);
336 if (dlg
.exec() == QDialog::Accepted
)
338 m_debuggerCmd
= dlg
.m_chooseDriver
.debuggerCmd();
339 m_ttyLevel
= TTYLevel(dlg
.m_output
.ttyLevel());
343 bool KDebugger::setBreakpoint(QString file
, int lineNo
,
344 const DbgAddr
& address
, bool temporary
)
350 Breakpoint
* bp
= breakpointByFilePos(file
, lineNo
, address
);
354 * No such breakpoint, so set a new one. If we have an address, we
355 * set the breakpoint exactly there. Otherwise we use the file name
358 Breakpoint
* bp
= new Breakpoint
;
359 bp
->temporary
= temporary
;
361 if (address
.isEmpty())
368 bp
->address
= address
;
370 setBreakpoint(bp
, false);
375 * If the breakpoint is disabled, enable it; if it's enabled,
376 * delete that breakpoint.
379 deleteBreakpoint(bp
);
381 enableDisableBreakpoint(bp
);
387 void KDebugger::setBreakpoint(Breakpoint
* bp
, bool queueOnly
)
390 if (!bp
->text
.isEmpty())
393 * The breakpoint was set using the text box in the breakpoint
394 * list. This is the only way in which watchpoints are set.
396 if (bp
->type
== Breakpoint::watchpoint
) {
397 cmd
= m_d
->executeCmd(DCwatchpoint
, bp
->text
);
399 cmd
= m_d
->executeCmd(DCbreaktext
, bp
->text
);
402 else if (bp
->address
.isEmpty())
404 // strip off directory part of file name
405 QString file
= bp
->fileName
;
406 int offset
= file
.findRev("/");
408 file
.remove(0, offset
+1);
411 cmd
= m_d
->queueCmd(bp
->temporary
? DCtbreakline
: DCbreakline
,
412 file
, bp
->lineNo
, DebuggerDriver::QMoverride
);
414 cmd
= m_d
->executeCmd(bp
->temporary
? DCtbreakline
: DCbreakline
,
421 cmd
= m_d
->queueCmd(bp
->temporary
? DCtbreakaddr
: DCbreakaddr
,
422 bp
->address
.asString(), DebuggerDriver::QMoverride
);
424 cmd
= m_d
->executeCmd(bp
->temporary
? DCtbreakaddr
: DCbreakaddr
,
425 bp
->address
.asString());
428 cmd
->m_brkpt
= bp
; // used in newBreakpoint()
431 bool KDebugger::enableDisableBreakpoint(QString file
, int lineNo
,
432 const DbgAddr
& address
)
434 Breakpoint
* bp
= breakpointByFilePos(file
, lineNo
, address
);
435 return bp
== 0 || enableDisableBreakpoint(bp
);
438 bool KDebugger::enableDisableBreakpoint(Breakpoint
* bp
)
441 * Toggle enabled/disabled state.
443 * The driver is not bothered if we are modifying an orphaned
446 if (!bp
->isOrphaned()) {
447 if (!canChangeBreakpoints()) {
450 m_d
->executeCmd(bp
->enabled
? DCdisable
: DCenable
, bp
->id
);
452 bp
->enabled
= !bp
->enabled
;
453 emit
breakpointsChanged();
458 bool KDebugger::conditionalBreakpoint(Breakpoint
* bp
,
459 const QString
& condition
,
463 * Change the condition and ignore count.
465 * The driver is not bothered if we are removing an orphaned
469 if (!bp
->isOrphaned()) {
470 if (!canChangeBreakpoints()) {
474 bool changed
= false;
476 if (bp
->condition
!= condition
) {
478 m_d
->executeCmd(DCcondition
, condition
, bp
->id
);
481 if (bp
->ignoreCount
!= ignoreCount
) {
482 // change ignore count
483 m_d
->executeCmd(DCignore
, bp
->id
, ignoreCount
);
488 m_d
->queueCmd(DCinfobreak
, DebuggerDriver::QMoverride
);
491 bp
->condition
= condition
;
492 bp
->ignoreCount
= ignoreCount
;
493 emit
breakpointsChanged();
498 bool KDebugger::deleteBreakpoint(Breakpoint
* bp
)
501 * Remove the breakpoint.
503 * The driver is not bothered if we are removing an orphaned
506 if (!bp
->isOrphaned()) {
507 if (!canChangeBreakpoints()) {
510 m_d
->executeCmd(DCdelete
, bp
->id
);
512 // move the last entry to bp's slot and shorten the list
513 int i
= m_brkpts
.findRef(bp
);
514 m_brkpts
.insert(i
, m_brkpts
.take(m_brkpts
.size()-1));
515 m_brkpts
.resize(m_brkpts
.size()-1);
516 emit
breakpointsChanged();
521 bool KDebugger::canSingleStep()
523 return isReady() && m_programActive
&& !m_programRunning
;
526 bool KDebugger::canChangeBreakpoints()
528 return isReady() && !m_programRunning
;
531 bool KDebugger::canStart()
533 return isReady() && !m_programActive
;
536 bool KDebugger::isReady() const
538 return m_haveExecutable
&&
539 m_d
!= 0 && m_d
->canExecuteImmediately();
542 bool KDebugger::isIdle() const
544 return m_d
== 0 || m_d
->isIdle();
548 //////////////////////////////////////////////////////////
551 bool KDebugger::startDriver()
553 emit
debuggerStarting(); /* must set m_inferiorTerminal */
556 * If the per-program command string is empty, use the global setting
557 * (which might also be empty, in which case the driver uses its
560 m_explicitKill
= false;
561 if (!m_d
->startup(m_debuggerCmd
)) {
566 * If we have an output terminal, we use it. Otherwise we will run the
567 * program with input and output redirected to /dev/null. Other
568 * redirections are also necessary depending on the tty emulation
571 int redirect
= RDNstdin
|RDNstdout
|RDNstderr
; /* redirect everything */
572 if (!m_inferiorTerminal
.isEmpty()) {
573 switch (m_ttyLevel
) {
576 // redirect everything
578 case ttySimpleOutputOnly
:
586 m_d
->executeCmd(DCtty
, m_inferiorTerminal
, redirect
);
591 void KDebugger::stopDriver()
593 m_explicitKill
= true;
595 if (m_attachedPid
.isEmpty()) {
598 m_d
->detachAndTerminate();
602 * We MUST wait until the slot gdbExited() has been called. But to
603 * avoid a deadlock, we wait only for some certain maximum time. Should
604 * this timeout be reached, the only reasonable thing one could do then
607 kapp
->processEvents(1000); /* ideally, this will already shut it down */
608 int maxTime
= 20; /* about 20 seconds */
609 while (m_haveExecutable
&& maxTime
> 0) {
610 // give gdb time to die (and send a SIGCLD)
613 kapp
->processEvents(1000);
617 void KDebugger::gdbExited(KProcess
*)
620 * Save settings, but only if gdb has already processed "info line
621 * main", otherwise we would save an empty config file, because it
622 * isn't read in until then!
624 if (m_programConfig
!= 0) {
625 if (m_haveExecutable
) {
626 saveProgramSettings();
627 m_programConfig
->sync();
629 delete m_programConfig
;
637 if (m_explicitKill
) {
638 TRACE(m_d
->driverName() + " exited normally");
640 QString msg
= i18n("%1 exited unexpectedly.\n"
641 "Restart the session (e.g. with File|Executable).");
642 KMessageBox::error(parentWidget(), msg
.arg(m_d
->driverName()));
646 m_haveExecutable
= false;
648 m_programActive
= false;
649 m_programRunning
= false;
650 m_explicitKill
= false;
651 m_debuggerCmd
= QString(); /* use global setting at next start! */
652 m_attachedPid
= QString(); /* we are no longer attached to a process */
653 m_ttyLevel
= ttyFull
;
657 emit
updatePC(QString(), -1, DbgAddr(), 0);
660 QString
KDebugger::getConfigForExe(const QString
& name
)
663 QString pgmConfigFile
= fi
.dirPath(true);
664 if (!pgmConfigFile
.isEmpty()) {
665 pgmConfigFile
+= '/';
667 pgmConfigFile
+= ".kdbgrc." + fi
.fileName();
668 TRACE("program config file = " + pgmConfigFile
);
669 return pgmConfigFile
;
672 void KDebugger::openProgramConfig(const QString
& name
)
674 ASSERT(m_programConfig
== 0);
676 QString pgmConfigFile
= getConfigForExe(name
);
678 m_programConfig
= new ProgramConfig(pgmConfigFile
);
681 const char EnvironmentGroup
[] = "Environment";
682 const char WatchGroup
[] = "Watches";
683 const char FileVersion
[] = "FileVersion";
684 const char ProgramArgs
[] = "ProgramArgs";
685 const char WorkingDirectory
[] = "WorkingDirectory";
686 const char OptionsSelected
[] = "OptionsSelected";
687 const char Variable
[] = "Var%d";
688 const char Value
[] = "Value%d";
689 const char ExprFmt
[] = "Expr%d";
691 void KDebugger::saveProgramSettings()
693 ASSERT(m_programConfig
!= 0);
694 m_programConfig
->setGroup(GeneralGroup
);
695 m_programConfig
->writeEntry(FileVersion
, 1);
696 m_programConfig
->writeEntry(ProgramArgs
, m_programArgs
);
697 m_programConfig
->writeEntry(WorkingDirectory
, m_programWD
);
698 m_programConfig
->writeEntry(OptionsSelected
, m_boolOptions
);
699 m_programConfig
->writeEntry(DebuggerCmdStr
, m_debuggerCmd
);
700 m_programConfig
->writeEntry(TTYLevelEntry
, int(m_ttyLevel
));
703 driverName
= m_d
->driverName();
704 m_programConfig
->writeEntry(DriverNameEntry
, driverName
);
706 // write environment variables
707 m_programConfig
->deleteGroup(EnvironmentGroup
);
708 m_programConfig
->setGroup(EnvironmentGroup
);
709 QDictIterator
<EnvVar
> it
= m_envVars
;
713 for (int i
= 0; (var
= it
) != 0; ++it
, ++i
) {
714 varName
.sprintf(Variable
, i
);
715 varValue
.sprintf(Value
, i
);
716 m_programConfig
->writeEntry(varName
, it
.currentKey());
717 m_programConfig
->writeEntry(varValue
, var
->value
);
720 saveBreakpoints(m_programConfig
);
723 // first get rid of whatever was in this group
724 m_programConfig
->deleteGroup(WatchGroup
);
725 // then start a new group
726 m_programConfig
->setGroup(WatchGroup
);
727 VarTree
* item
= m_watchVariables
.firstChild();
729 for (; item
!= 0; item
= item
->nextSibling(), ++watchNum
) {
730 varName
.sprintf(ExprFmt
, watchNum
);
731 m_programConfig
->writeEntry(varName
, item
->getText());
734 // give others a chance
735 emit
saveProgramSpecific(m_programConfig
);
738 void KDebugger::overrideProgramArguments(const QString
& args
)
740 ASSERT(m_programConfig
!= 0);
741 m_programConfig
->setGroup(GeneralGroup
);
742 m_programConfig
->writeEntry(ProgramArgs
, args
);
745 void KDebugger::restoreProgramSettings()
747 ASSERT(m_programConfig
!= 0);
748 m_programConfig
->setGroup(GeneralGroup
);
750 * We ignore file version for now we will use it in the future to
751 * distinguish different versions of this configuration file.
753 // m_debuggerCmd has been read in already
754 // m_ttyLevel has been read in already
755 QString pgmArgs
= m_programConfig
->readEntry(ProgramArgs
);
756 QString pgmWd
= m_programConfig
->readEntry(WorkingDirectory
);
757 QStringList boolOptions
= m_programConfig
->readListEntry(OptionsSelected
);
758 m_boolOptions
= QStringList();
760 // read environment variables
761 m_programConfig
->setGroup(EnvironmentGroup
);
763 QDict
<EnvVar
> pgmVars
;
767 for (int i
= 0;; ++i
) {
768 varName
.sprintf(Variable
, i
);
769 varValue
.sprintf(Value
, i
);
770 if (!m_programConfig
->hasKey(varName
)) {
771 /* entry not present, assume that we've hit them all */
774 QString name
= m_programConfig
->readEntry(varName
);
775 if (name
.isEmpty()) {
780 var
->value
= m_programConfig
->readEntry(varValue
);
781 var
->status
= EnvVar::EVnew
;
782 pgmVars
.insert(name
, var
);
785 updateProgEnvironment(pgmArgs
, pgmWd
, pgmVars
, boolOptions
);
787 restoreBreakpoints(m_programConfig
);
790 m_programConfig
->setGroup(WatchGroup
);
791 m_watchVariables
.clear();
792 for (int i
= 0;; ++i
) {
793 varName
.sprintf(ExprFmt
, i
);
794 if (!m_programConfig
->hasKey(varName
)) {
795 /* entry not present, assume that we've hit them all */
798 QString expr
= m_programConfig
->readEntry(varName
);
799 if (expr
.isEmpty()) {
800 // skip empty expressions
806 // give others a chance
807 emit
restoreProgramSpecific(m_programConfig
);
811 * Reads the debugger command line from the program settings. The config
812 * group must have been set by the caller.
814 QString
KDebugger::readDebuggerCmd()
816 QString debuggerCmd
= m_programConfig
->readEntry(DebuggerCmdStr
);
818 // always let the user confirm the debugger cmd if we are root
819 if (::geteuid() == 0)
821 if (!debuggerCmd
.isEmpty()) {
823 "The settings for this program specify "
824 "the following debugger command:\n%1\n"
825 "Shall this command be used?");
826 if (KMessageBox::warningYesNo(parentWidget(), msg
.arg(debuggerCmd
))
830 debuggerCmd
= QString();
838 * Breakpoints are saved one per group.
840 const char BPGroup
[] = "Breakpoint %d";
841 const char File
[] = "File";
842 const char Line
[] = "Line";
843 const char Text
[] = "Text";
844 const char Address
[] = "Address";
845 const char Temporary
[] = "Temporary";
846 const char Enabled
[] = "Enabled";
847 const char Condition
[] = "Condition";
849 void KDebugger::saveBreakpoints(ProgramConfig
* config
)
853 for (uint j
= 0; j
< m_brkpts
.size(); j
++) {
854 Breakpoint
* bp
= m_brkpts
[j
];
855 if (bp
->type
== Breakpoint::watchpoint
)
856 continue; /* don't save watchpoints */
857 groupName
.sprintf(BPGroup
, i
++);
859 /* remove remmants */
860 config
->deleteGroup(groupName
);
862 config
->setGroup(groupName
);
863 if (!bp
->text
.isEmpty()) {
865 * The breakpoint was set using the text box in the breakpoint
866 * list. We do not save the location by filename+line number,
867 * but instead honor what the user typed (a function name, for
868 * example, which could move between sessions).
870 config
->writeEntry(Text
, bp
->text
);
871 } else if (!bp
->fileName
.isEmpty()) {
872 config
->writeEntry(File
, bp
->fileName
);
873 config
->writeEntry(Line
, bp
->lineNo
);
875 * Addresses are hardly correct across sessions, so we don't
879 config
->writeEntry(Address
, bp
->address
.asString());
881 config
->writeEntry(Temporary
, bp
->temporary
);
882 config
->writeEntry(Enabled
, bp
->enabled
);
883 if (!bp
->condition
.isEmpty())
884 config
->writeEntry(Condition
, bp
->condition
);
885 // we do not save the ignore count
887 // delete remaining groups
888 // we recognize that a group is present if there is an Enabled entry
890 groupName
.sprintf(BPGroup
, i
);
891 config
->setGroup(groupName
);
892 if (!config
->hasKey(Enabled
)) {
893 /* group not present, assume that we've hit them all */
896 config
->deleteGroup(groupName
);
900 void KDebugger::restoreBreakpoints(ProgramConfig
* config
)
904 * We recognize the end of the list if there is no Enabled entry
907 for (int i
= 0;; i
++) {
908 groupName
.sprintf(BPGroup
, i
);
909 config
->setGroup(groupName
);
910 if (!config
->hasKey(Enabled
)) {
911 /* group not present, assume that we've hit them all */
914 Breakpoint
* bp
= new Breakpoint
;
915 bp
->fileName
= config
->readEntry(File
);
916 bp
->lineNo
= config
->readNumEntry(Line
, -1);
917 bp
->text
= config
->readEntry(Text
);
918 bp
->address
= config
->readEntry(Address
);
920 if ((bp
->fileName
.isEmpty() || bp
->lineNo
< 0) &&
921 bp
->text
.isEmpty() &&
922 bp
->address
.isEmpty())
927 bp
->enabled
= config
->readBoolEntry(Enabled
, true);
928 bp
->temporary
= config
->readBoolEntry(Temporary
, false);
929 bp
->condition
= config
->readEntry(Condition
);
932 * Add the breakpoint.
934 setBreakpoint(bp
, false);
935 // the new breakpoint is disabled or conditionalized later
936 // in newBreakpoint()
938 m_d
->queueCmd(DCinfobreak
, DebuggerDriver::QMoverride
);
942 // parse output of command cmd
943 void KDebugger::parse(CmdQueueItem
* cmd
, const char* output
)
945 ASSERT(cmd
!= 0); /* queue mustn't be empty */
947 TRACE(QString(__PRETTY_FUNCTION__
) + " parsing " + output
);
949 switch (cmd
->m_cmd
) {
951 // the output (if any) is uninteresting
954 // there is no output
958 /* if value is empty, we see output, but we don't care */
961 /* display gdb's message in the status bar */
962 m_d
->parseChangeWD(output
, m_statusMessage
);
963 emit
updateStatusMessage();
968 if (m_d
->parseChangeExecutable(output
, m_statusMessage
))
970 // success; restore breakpoints etc.
971 if (m_programConfig
!= 0) {
972 restoreProgramSettings();
974 // load file containing main() or core file
975 if (!m_corefile
.isEmpty())
980 else if (!m_attachedPid
.isEmpty())
982 m_d
->queueCmd(DCattach
, m_attachedPid
, DebuggerDriver::QMoverride
);
983 m_programActive
= true;
984 m_programRunning
= true;
986 else if (!m_remoteDevice
.isEmpty())
992 m_d
->queueCmd(DCinfolinemain
, DebuggerDriver::QMnormal
);
994 if (!m_statusMessage
.isEmpty())
995 emit
updateStatusMessage();
997 QString msg
= m_d
->driverName() + ": " + m_statusMessage
;
998 KMessageBox::sorry(parentWidget(), msg
);
1000 m_corefile
= ""; /* don't process core file */
1001 m_haveExecutable
= false;
1005 // in any event we have an executable at this point
1006 m_haveExecutable
= true;
1007 if (m_d
->parseCoreFile(output
)) {
1008 // loading a core is like stopping at a breakpoint
1009 m_programActive
= true;
1010 handleRunCommands(output
);
1011 // do not reset m_corefile
1014 QString msg
= m_d
->driverName() + ": " + QString(output
);
1015 KMessageBox::sorry(parentWidget(), msg
);
1017 // if core file was loaded from command line, revert to info line main
1018 if (!cmd
->m_byUser
) {
1019 m_d
->queueCmd(DCinfolinemain
, DebuggerDriver::QMnormal
);
1021 m_corefile
= QString(); /* core file not available any more */
1024 case DCinfolinemain
:
1025 // ignore the output, marked file info follows
1026 m_haveExecutable
= true;
1029 // parse local variables
1030 if (output
[0] != '\0') {
1031 handleLocals(output
);
1034 case DCinforegisters
:
1035 handleRegisters(output
);
1038 handleMemoryDump(output
);
1041 handleInfoLine(cmd
, output
);
1044 handleDisassemble(cmd
, output
);
1047 handleFrameChange(output
);
1051 handleBacktrace(output
);
1055 handlePrint(cmd
, output
);
1058 handlePrintDeref(cmd
, output
);
1061 m_haveExecutable
= true;
1072 handleRunCommands(output
);
1075 m_programRunning
= m_programActive
= false;
1077 emit
updatePC(QString(), -1, DbgAddr(), 0);
1085 newBreakpoint(cmd
, output
);
1090 // these commands need immediate response
1091 m_d
->queueCmd(DCinfobreak
, DebuggerDriver::QMoverrideMoreEqual
);
1094 // note: this handler must not enqueue a command, since
1095 // DCinfobreak is used at various different places.
1096 updateBreakList(output
);
1099 handleFindType(cmd
, output
);
1102 case DCprintQStringStruct
:
1104 handlePrintStruct(cmd
, output
);
1106 case DCinfosharedlib
:
1107 handleSharedLibs(output
);
1111 // we are not interested in the output
1114 handleThreadList(output
);
1117 handleSetPC(output
);
1120 handleSetVariable(cmd
, output
);
1125 void KDebugger::backgroundUpdate()
1128 * If there are still expressions that need to be updated, then do so.
1130 if (m_programActive
)
1134 void KDebugger::handleRunCommands(const char* output
)
1136 uint flags
= m_d
->parseProgramStopped(output
, m_statusMessage
);
1137 emit
updateStatusMessage();
1139 m_programActive
= flags
& DebuggerDriver::SFprogramActive
;
1141 // refresh files if necessary
1142 if (flags
& DebuggerDriver::SFrefreshSource
) {
1143 TRACE("re-reading files");
1144 emit
executableUpdated();
1148 * Try to set any orphaned breakpoints now.
1150 for (int i
= m_brkpts
.size()-1; i
>= 0; i
--) {
1151 if (m_brkpts
[i
]->isOrphaned()) {
1152 TRACE("re-trying brkpt loc: "+m_brkpts
[i
]->location
+
1153 " file: "+m_brkpts
[i
]->fileName
+
1154 QString().sprintf(" line: %d", m_brkpts
[i
]->lineNo
));
1155 setBreakpoint(m_brkpts
[i
], true);
1156 flags
|= DebuggerDriver::SFrefreshBreak
;
1161 * If we stopped at a breakpoint, we must update the breakpoint list
1162 * because the hit count changes. Also, if the breakpoint was temporary
1163 * it would go away now.
1165 if ((flags
& (DebuggerDriver::SFrefreshBreak
|DebuggerDriver::SFrefreshSource
)) ||
1166 stopMayChangeBreakList())
1168 m_d
->queueCmd(DCinfobreak
, DebuggerDriver::QMoverride
);
1172 * If we haven't listed the shared libraries yet, do so. We must do
1173 * this before we emit any commands that list variables, since the type
1174 * libraries depend on the shared libraries.
1176 if (!m_sharedLibsListed
) {
1177 // must be a high-priority command!
1178 m_d
->executeCmd(DCinfosharedlib
);
1181 // get the backtrace if the program is running
1182 if (m_programActive
) {
1183 m_d
->queueCmd(DCbt
, DebuggerDriver::QMoverride
);
1185 // program finished: erase PC
1186 emit
updatePC(QString(), -1, DbgAddr(), 0);
1187 // dequeue any commands in the queues
1188 m_d
->flushCommands();
1191 /* Update threads list */
1192 if (m_programActive
&& (flags
& DebuggerDriver::SFrefreshThreads
)) {
1193 m_d
->queueCmd(DCinfothreads
, DebuggerDriver::QMoverride
);
1196 m_programRunning
= false;
1197 emit
programStopped();
1200 void KDebugger::slotInferiorRunning()
1202 m_programRunning
= true;
1205 void KDebugger::updateAllExprs()
1207 if (!m_programActive
)
1210 // retrieve local variables
1211 m_d
->queueCmd(DCinfolocals
, DebuggerDriver::QMoverride
);
1213 // retrieve registers
1214 m_d
->queueCmd(DCinforegisters
, DebuggerDriver::QMoverride
);
1216 // get new memory dump
1217 if (!m_memoryExpression
.isEmpty()) {
1218 queueMemoryDump(false);
1221 // update watch expressions
1222 VarTree
* item
= m_watchVariables
.firstChild();
1223 for (; item
!= 0; item
= item
->nextSibling()) {
1224 m_watchEvalExpr
.push_back(item
->getText());
1228 void KDebugger::updateProgEnvironment(const QString
& args
, const QString
& wd
,
1229 const QDict
<EnvVar
>& newVars
,
1230 const QStringList
& newOptions
)
1232 m_programArgs
= args
;
1233 m_d
->executeCmd(DCsetargs
, m_programArgs
);
1234 TRACE("new pgm args: " + m_programArgs
+ "\n");
1236 m_programWD
= wd
.stripWhiteSpace();
1237 if (!m_programWD
.isEmpty()) {
1238 m_d
->executeCmd(DCcd
, m_programWD
);
1239 TRACE("new wd: " + m_programWD
+ "\n");
1242 // update environment variables
1243 QDictIterator
<EnvVar
> it
= newVars
;
1245 for (; (val
= it
) != 0; ++it
) {
1246 QString var
= it
.currentKey();
1247 switch (val
->status
) {
1249 m_envVars
.insert(var
, val
);
1251 case EnvVar::EVdirty
:
1252 // the value must be in our list
1253 ASSERT(m_envVars
[var
] == val
);
1255 m_d
->executeCmd(DCsetenv
, var
, val
->value
);
1257 case EnvVar::EVdeleted
:
1258 // must be in our list
1259 ASSERT(m_envVars
[var
] == val
);
1261 m_d
->executeCmd(DCunsetenv
, var
);
1262 m_envVars
.remove(var
);
1266 case EnvVar::EVclean
:
1267 // variable not changed
1273 QStringList::ConstIterator oi
;
1274 for (oi
= newOptions
.begin(); oi
!= newOptions
.end(); ++oi
)
1276 if (m_boolOptions
.findIndex(*oi
) < 0) {
1277 // the options is currently not set, so set it
1278 m_d
->executeCmd(DCsetoption
, *oi
, 1);
1280 // option is set, no action required, but move it to the end
1281 m_boolOptions
.remove(*oi
);
1283 m_boolOptions
.append(*oi
);
1286 * Now all options that should be set are at the end of m_boolOptions.
1287 * If some options need to be unset, they are at the front of the list.
1288 * Here we unset and remove them.
1290 while (m_boolOptions
.count() > newOptions
.count()) {
1291 m_d
->executeCmd(DCsetoption
, m_boolOptions
.first(), 0);
1292 m_boolOptions
.remove(m_boolOptions
.begin());
1296 void KDebugger::handleLocals(const char* output
)
1298 // retrieve old list of local variables
1300 m_localVariables
.exprList(oldVars
);
1303 * Get local variables.
1305 QList
<ExprValue
> newVars
;
1306 parseLocals(output
, newVars
);
1309 * Clear any old VarTree item pointers, so that later we don't access
1310 * dangling pointers.
1312 m_localVariables
.clearPendingUpdates();
1315 * Match old variables against new ones.
1317 for (const char* n
= oldVars
.first(); n
!= 0; n
= oldVars
.next()) {
1318 // lookup this variable in the list of new variables
1319 ExprValue
* v
= newVars
.first();
1320 while (v
!= 0 && v
->m_name
!= n
) {
1324 // old variable not in the new variables
1325 TRACE(QString("old var deleted: ") + n
);
1326 VarTree
* v
= m_localVariables
.topLevelExprByName(n
);
1328 m_localVariables
.removeExpr(v
);
1331 // variable in both old and new lists: update
1332 TRACE(QString("update var: ") + n
);
1333 m_localVariables
.updateExpr(newVars
.current(), *m_typeTable
);
1334 // remove the new variable from the list
1339 // insert all remaining new variables
1340 while (!newVars
.isEmpty())
1342 ExprValue
* v
= newVars
.take(0);
1343 TRACE("new var: " + v
->m_name
);
1344 m_localVariables
.insertExpr(v
, *m_typeTable
);
1349 void KDebugger::parseLocals(const char* output
, QList
<ExprValue
>& newVars
)
1351 QList
<ExprValue
> vars
;
1352 m_d
->parseLocals(output
, vars
);
1354 QString origName
; /* used in renaming variables */
1355 while (vars
.count() > 0)
1357 ExprValue
* variable
= vars
.take(0);
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
->m_name
;
1369 for (ExprValue
* v
= newVars
.first(); v
!= 0; v
= newVars
.next()) {
1370 if (variable
->m_name
== v
->m_name
) {
1371 // we found a duplicate, change name
1373 QString newName
= origName
+ " (" + QString().setNum(block
) + ")";
1374 variable
->m_name
= newName
;
1377 newVars
.append(variable
);
1381 bool KDebugger::handlePrint(CmdQueueItem
* cmd
, const char* output
)
1383 ASSERT(cmd
->m_expr
!= 0);
1385 ExprValue
* variable
= m_d
->parsePrintExpr(output
, true);
1389 // set expression "name"
1390 variable
->m_name
= cmd
->m_expr
->getText();
1393 TRACE("update expr: " + cmd
->m_expr
->getText());
1394 cmd
->m_exprWnd
->updateExpr(cmd
->m_expr
, variable
, *m_typeTable
);
1398 evalExpressions(); /* enqueue dereferenced pointers */
1403 bool KDebugger::handlePrintDeref(CmdQueueItem
* cmd
, const char* output
)
1405 ASSERT(cmd
->m_expr
!= 0);
1407 ExprValue
* variable
= m_d
->parsePrintExpr(output
, true);
1411 // set expression "name"
1412 variable
->m_name
= cmd
->m_expr
->getText();
1416 * We must insert a dummy parent, because otherwise variable's value
1417 * would overwrite cmd->m_expr's value.
1419 ExprValue
* dummyParent
= new ExprValue(variable
->m_name
, VarTree::NKplain
);
1420 dummyParent
->m_varKind
= VarTree::VKdummy
;
1421 // the name of the parsed variable is the address of the pointer
1422 QString addr
= "*" + cmd
->m_expr
->value();
1423 variable
->m_name
= addr
;
1424 variable
->m_nameKind
= VarTree::NKaddress
;
1426 dummyParent
->m_child
= variable
;
1427 // expand the first level for convenience
1428 variable
->m_initiallyExpanded
= true;
1429 TRACE("update ptr: " + cmd
->m_expr
->getText());
1430 cmd
->m_exprWnd
->updateExpr(cmd
->m_expr
, dummyParent
, *m_typeTable
);
1434 evalExpressions(); /* enqueue dereferenced pointers */
1439 // parse the output of bt
1440 void KDebugger::handleBacktrace(const char* output
)
1443 m_btWindow
.setAutoUpdate(false);
1447 QList
<StackFrame
> stack
;
1448 m_d
->parseBackTrace(output
, stack
);
1450 if (stack
.count() > 0) {
1451 StackFrame
* frm
= stack
.take(0);
1452 // first frame must set PC
1453 // note: frm->lineNo is zero-based
1454 emit
updatePC(frm
->fileName
, frm
->lineNo
, frm
->address
, frm
->frameNo
);
1459 func
= frm
->var
->m_name
;
1461 func
= frm
->fileName
+ ":" + QString().setNum(frm
->lineNo
+1);
1462 m_btWindow
.insertItem(func
);
1463 TRACE("frame " + func
+ " (" + frm
->fileName
+ ":" +
1464 QString().setNum(frm
->lineNo
+1) + ")");
1467 while ((frm
= stack
.take()) != 0);
1470 m_btWindow
.setAutoUpdate(true);
1471 m_btWindow
.repaint();
1474 void KDebugger::gotoFrame(int frame
)
1476 m_d
->executeCmd(DCframe
, frame
);
1479 void KDebugger::handleFrameChange(const char* output
)
1485 if (m_d
->parseFrameChange(output
, frameNo
, fileName
, lineNo
, address
)) {
1486 /* lineNo can be negative here if we can't find a file name */
1487 emit
updatePC(fileName
, lineNo
, address
, frameNo
);
1489 emit
updatePC(fileName
, -1, address
, frameNo
);
1493 void KDebugger::evalExpressions()
1495 // evaluate expressions in the following order:
1496 // watch expressions
1497 // pointers in local variables
1498 // pointers in watch expressions
1499 // types in local variables
1500 // types in watch expressions
1501 // struct members in local variables
1502 // struct members in watch expressions
1503 VarTree
* exprItem
= 0;
1504 if (!m_watchEvalExpr
.empty())
1506 QString expr
= m_watchEvalExpr
.front();
1507 m_watchEvalExpr
.pop_front();
1508 exprItem
= m_watchVariables
.topLevelExprByName(expr
);
1510 if (exprItem
!= 0) {
1511 CmdQueueItem
* cmd
= m_d
->queueCmd(DCprint
, exprItem
->getText(), DebuggerDriver::QMoverride
);
1512 // remember which expr this was
1513 cmd
->m_expr
= exprItem
;
1514 cmd
->m_exprWnd
= &m_watchVariables
;
1517 #define POINTER(widget) \
1519 exprItem = widget.nextUpdatePtr(); \
1520 if (exprItem != 0) goto pointer
1521 #define STRUCT(widget) \
1523 exprItem = widget.nextUpdateStruct(); \
1524 if (exprItem != 0) goto ustruct
1525 #define TYPE(widget) \
1527 exprItem = widget.nextUpdateType(); \
1528 if (exprItem != 0) goto type
1530 POINTER(m_localVariables
);
1531 POINTER(m_watchVariables
);
1532 STRUCT(m_localVariables
);
1533 STRUCT(m_watchVariables
);
1534 TYPE(m_localVariables
);
1535 TYPE(m_watchVariables
);
1542 // we have an expression to send
1543 dereferencePointer(wnd
, exprItem
, false);
1548 if (exprItem
->m_type
== 0 || exprItem
->m_type
== TypeInfo::unknownType())
1550 evalInitialStructExpression(exprItem
, wnd
, false);
1555 * Sometimes a VarTree gets registered twice for a type update. So
1556 * it may happen that it has already been updated. Hence, we ignore
1557 * it here and go on to the next task.
1559 if (exprItem
->m_type
!= 0)
1561 determineType(wnd
, exprItem
);
1565 void KDebugger::dereferencePointer(ExprWnd
* wnd
, VarTree
* exprItem
,
1568 ASSERT(exprItem
->m_varKind
== VarTree::VKpointer
);
1570 QString expr
= exprItem
->computeExpr();
1571 TRACE("dereferencing pointer: " + expr
);
1574 cmd
= m_d
->queueCmd(DCprintDeref
, expr
, DebuggerDriver::QMoverrideMoreEqual
);
1576 cmd
= m_d
->queueCmd(DCprintDeref
, expr
, DebuggerDriver::QMoverride
);
1578 // remember which expr this was
1579 cmd
->m_expr
= exprItem
;
1580 cmd
->m_exprWnd
= wnd
;
1583 void KDebugger::determineType(ExprWnd
* wnd
, VarTree
* exprItem
)
1585 ASSERT(exprItem
->m_varKind
== VarTree::VKstruct
);
1587 QString expr
= exprItem
->computeExpr();
1588 TRACE("get type of: " + expr
);
1590 cmd
= m_d
->queueCmd(DCfindType
, expr
, DebuggerDriver::QMoverride
);
1592 // remember which expr this was
1593 cmd
->m_expr
= exprItem
;
1594 cmd
->m_exprWnd
= wnd
;
1597 void KDebugger::handleFindType(CmdQueueItem
* cmd
, const char* output
)
1600 if (m_d
->parseFindType(output
, type
))
1602 ASSERT(cmd
!= 0 && cmd
->m_expr
!= 0);
1604 TypeInfo
* info
= m_typeTable
->lookup(type
);
1608 * We've asked gdb for the type of the expression in
1609 * cmd->m_expr, but it returned a name we don't know. The base
1610 * class (and member) types have been checked already (at the
1611 * time when we parsed that particular expression). Now it's
1612 * time to derive the type from the base classes as a last
1615 info
= cmd
->m_expr
->inferTypeFromBaseClass();
1616 // if we found a type through this method, register an alias
1618 TRACE("infered alias: " + type
);
1619 m_typeTable
->registerAlias(type
, info
);
1623 TRACE("unknown type "+type
);
1624 cmd
->m_expr
->m_type
= TypeInfo::unknownType();
1626 cmd
->m_expr
->m_type
= info
;
1627 /* since this node has a new type, we get its value immediately */
1628 evalInitialStructExpression(cmd
->m_expr
, cmd
->m_exprWnd
, false);
1633 evalExpressions(); /* queue more of them */
1636 void KDebugger::handlePrintStruct(CmdQueueItem
* cmd
, const char* output
)
1638 VarTree
* var
= cmd
->m_expr
;
1640 ASSERT(var
->m_varKind
== VarTree::VKstruct
);
1642 ExprValue
* partExpr
;
1643 if (cmd
->m_cmd
== DCprintQStringStruct
) {
1644 partExpr
= m_d
->parseQCharArray(output
, false, m_typeTable
->qCharIsShort());
1645 } else if (cmd
->m_cmd
== DCprintWChar
) {
1646 partExpr
= m_d
->parseQCharArray(output
, false, true);
1648 partExpr
= m_d
->parsePrintExpr(output
, false);
1652 /* we only allow simple values at the moment */
1653 partExpr
->m_child
!= 0;
1658 partValue
= "?""?""?"; // 2 question marks in a row would be a trigraph
1660 partValue
= partExpr
->m_value
;
1666 * Updating a struct value works like this: var->m_partialValue holds
1667 * the value that we have gathered so far (it's been initialized with
1668 * var->m_type->m_displayString[0] earlier). Each time we arrive here,
1669 * we append the printed result followed by the next
1670 * var->m_type->m_displayString to var->m_partialValue.
1672 * If the expression we just evaluated was a guard expression, and it
1673 * resulted in an error, we must not evaluate the real expression, but
1674 * go on to the next index. (We must still add the question marks to
1677 * Next, if this was the length expression, we still have not seen the
1678 * real expression, but the length of a QString.
1680 ASSERT(var
->m_exprIndex
>= 0 && var
->m_exprIndex
<= typeInfoMaxExpr
);
1682 if (errorValue
|| !var
->m_exprIndexUseGuard
)
1684 // add current partValue (which might be the question marks)
1685 var
->m_partialValue
+= partValue
;
1686 var
->m_exprIndex
++; /* next part */
1687 var
->m_exprIndexUseGuard
= true;
1688 var
->m_partialValue
+= var
->m_type
->m_displayString
[var
->m_exprIndex
];
1692 // this was a guard expression that succeeded
1693 // go for the real expression
1694 var
->m_exprIndexUseGuard
= false;
1697 /* go for more sub-expressions if needed */
1698 if (var
->m_exprIndex
< var
->m_type
->m_numExprs
) {
1699 /* queue a new print command with quite high priority */
1700 evalStructExpression(var
, cmd
->m_exprWnd
, true);
1704 cmd
->m_exprWnd
->updateStructValue(var
);
1706 evalExpressions(); /* enqueue dereferenced pointers */
1709 /* queues the first printStruct command for a struct */
1710 void KDebugger::evalInitialStructExpression(VarTree
* var
, ExprWnd
* wnd
, bool immediate
)
1712 var
->m_exprIndex
= 0;
1713 if (var
->m_type
!= TypeInfo::wchartType())
1715 var
->m_exprIndexUseGuard
= true;
1716 var
->m_partialValue
= var
->m_type
->m_displayString
[0];
1717 evalStructExpression(var
, wnd
, immediate
);
1721 var
->m_exprIndexUseGuard
= false;
1722 QString expr
= var
->computeExpr();
1723 CmdQueueItem
* cmd
= m_d
->queueCmd(DCprintWChar
, expr
,
1724 immediate
? DebuggerDriver::QMoverrideMoreEqual
1725 : DebuggerDriver::QMoverride
);
1726 // remember which expression this was
1728 cmd
->m_exprWnd
= wnd
;
1732 /** queues a printStruct command; var must have been initialized correctly */
1733 void KDebugger::evalStructExpression(VarTree
* var
, ExprWnd
* wnd
, bool immediate
)
1735 QString base
= var
->computeExpr();
1737 if (var
->m_exprIndexUseGuard
) {
1738 exprFmt
= var
->m_type
->m_guardStrings
[var
->m_exprIndex
];
1739 if (exprFmt
.isEmpty()) {
1740 // no guard, omit it and go to expression
1741 var
->m_exprIndexUseGuard
= false;
1744 if (!var
->m_exprIndexUseGuard
) {
1745 exprFmt
= var
->m_type
->m_exprStrings
[var
->m_exprIndex
];
1749 expr
.sprintf(exprFmt
, base
.data());
1751 DbgCommand dbgCmd
= DCprintStruct
;
1752 // check if this is a QString::Data
1753 if (strncmp(expr
, "/QString::Data ", 15) == 0)
1755 if (m_typeTable
->parseQt2QStrings())
1757 expr
= expr
.mid(15, expr
.length()); /* strip off /QString::Data */
1758 dbgCmd
= DCprintQStringStruct
;
1761 * This should not happen: the type libraries should be set up
1762 * in a way that this can't happen. If this happens
1763 * nevertheless it means that, eg., kdecore was loaded but qt2
1764 * was not (only qt2 enables the QString feature).
1766 // TODO: remove this "print"; queue the next printStruct instead
1772 TRACE("evalStruct: " + expr
+ (var
->m_exprIndexUseGuard
? " // guard" : " // real"));
1773 CmdQueueItem
* cmd
= m_d
->queueCmd(dbgCmd
, expr
,
1774 immediate
? DebuggerDriver::QMoverrideMoreEqual
1775 : DebuggerDriver::QMnormal
);
1777 // remember which expression this was
1779 cmd
->m_exprWnd
= wnd
;
1782 void KDebugger::handleSharedLibs(const char* output
)
1784 // delete all known libraries
1785 m_sharedLibs
.clear();
1787 // parse the table of shared libraries
1788 m_d
->parseSharedLibs(output
, m_sharedLibs
);
1789 m_sharedLibsListed
= true;
1791 // get type libraries
1792 m_typeTable
->loadLibTypes(m_sharedLibs
);
1794 // hand over the QString data cmd
1795 m_d
->setPrintQStringDataCmd(m_typeTable
->printQStringDataCmd());
1798 CmdQueueItem
* KDebugger::loadCoreFile()
1800 return m_d
->queueCmd(DCcorefile
, m_corefile
, DebuggerDriver::QMoverride
);
1803 void KDebugger::slotExpanding(QListViewItem
* item
)
1805 VarTree
* exprItem
= static_cast<VarTree
*>(item
);
1806 if (exprItem
->m_varKind
!= VarTree::VKpointer
) {
1809 ExprWnd
* wnd
= static_cast<ExprWnd
*>(item
->listView());
1810 dereferencePointer(wnd
, exprItem
, true);
1813 // add the expression in the edit field to the watch expressions
1814 void KDebugger::addWatch(const QString
& t
)
1816 QString expr
= t
.stripWhiteSpace();
1817 // don't add a watched expression again
1818 if (expr
.isEmpty() || m_watchVariables
.topLevelExprByName(expr
) != 0)
1820 ExprValue
e(expr
, VarTree::NKplain
);
1821 m_watchVariables
.insertExpr(&e
, *m_typeTable
);
1823 // if we are boring ourselves, send down the command
1824 if (m_programActive
) {
1825 m_watchEvalExpr
.push_back(expr
);
1826 if (m_d
->isIdle()) {
1832 // delete a toplevel watch expression
1833 void KDebugger::slotDeleteWatch()
1835 // delete only allowed while debugger is idle; or else we might delete
1836 // the very expression the debugger is currently working on...
1837 if (m_d
== 0 || !m_d
->isIdle())
1840 VarTree
* item
= m_watchVariables
.currentItem();
1841 if (item
== 0 || !item
->isToplevelExpr())
1844 // remove the variable from the list to evaluate
1845 QStringList::iterator i
= m_watchEvalExpr
.find(item
->getText());
1846 if (i
!= m_watchEvalExpr
.end()) {
1847 m_watchEvalExpr
.erase(i
);
1849 m_watchVariables
.removeExpr(item
);
1850 // item is invalid at this point!
1853 void KDebugger::handleRegisters(const char* output
)
1855 QList
<RegisterInfo
> regs
;
1856 m_d
->parseRegisters(output
, regs
);
1858 emit
registersChanged(regs
);
1861 regs
.setAutoDelete(true);
1865 * The output of the DCbreak* commands has more accurate information about
1866 * the file and the line number.
1868 * All newly set breakpoints are inserted in the m_brkpts, even those that
1869 * were not set sucessfully. The unsuccessful breakpoints ("orphaned
1870 * breakpoints") are assigned negative ids, and they are tried to set later
1871 * when the program stops again at a breakpoint.
1873 void KDebugger::newBreakpoint(CmdQueueItem
* cmd
, const char* output
)
1875 Breakpoint
* bp
= cmd
->m_brkpt
;
1880 // if this is a new breakpoint, put it in the list
1881 bool isNew
= !m_brkpts
.contains(bp
);
1883 assert(bp
->id
== 0);
1884 int n
= m_brkpts
.size();
1885 m_brkpts
.resize(n
+1);
1886 m_brkpts
.insert(n
, bp
);
1889 // parse the output to determine success or failure
1894 if (!m_d
->parseBreakpoint(output
, id
, file
, lineNo
, address
))
1897 * Failure, the breakpoint could not be set. If this is a new
1898 * breakpoint, assign it a negative id. We look for the minimal id
1899 * of all breakpoints (that are already in the list) to get the new
1904 assert(bp
->id
== 0);
1905 for (int i
= m_brkpts
.size()-2; i
>= 0; i
--) {
1906 if (m_brkpts
[i
]->id
< bp
->id
) {
1907 bp
->id
= m_brkpts
[i
]->id
;
1916 // The breakpoint was successfully set.
1919 // this is a new or orphaned breakpoint:
1920 // set the remaining properties
1921 if (!cmd
->m_brkpt
->enabled
) {
1922 m_d
->executeCmd(DCdisable
, id
);
1924 if (!cmd
->m_brkpt
->condition
.isEmpty()) {
1925 m_d
->executeCmd(DCcondition
, cmd
->m_brkpt
->condition
, id
);
1930 bp
->fileName
= file
;
1931 bp
->lineNo
= lineNo
;
1932 if (!address
.isEmpty())
1933 bp
->address
= address
;
1936 void KDebugger::updateBreakList(const char* output
)
1939 QList
<Breakpoint
> brks
;
1940 brks
.setAutoDelete(false);
1941 m_d
->parseBreakList(output
, brks
);
1943 // merge new information into existing breakpoints
1945 for (int i
= m_brkpts
.size()-1; i
>= 0; i
--) // decrement!
1947 // skip orphaned breakpoints
1948 if (m_brkpts
[i
]->id
< 0)
1951 for (Breakpoint
* bp
= brks
.first(); bp
!= 0; bp
= brks
.next())
1953 if (bp
->id
== m_brkpts
[i
]->id
) {
1954 // keep accurate location
1955 // except that xsldbg doesn't have a location in
1956 // the old breakpoint if it's just been set
1957 bp
->text
= m_brkpts
[i
]->text
;
1958 if (!m_brkpts
[i
]->fileName
.isEmpty()) {
1959 bp
->fileName
= m_brkpts
[i
]->fileName
;
1960 bp
->lineNo
= m_brkpts
[i
]->lineNo
;
1962 m_brkpts
.insert(i
, bp
); // old object is deleted
1967 * If we get here, this breakpoint is no longer present.
1969 * To delete the breakpoint at i, we place the last breakpoint in
1970 * the list into the slot i. This will delete the old object at i.
1971 * Then we shorten the list by one.
1973 m_brkpts
.insert(i
, m_brkpts
.take(m_brkpts
.size()-1));
1974 m_brkpts
.resize(m_brkpts
.size()-1);
1975 TRACE(QString().sprintf("deleted brkpt %d, have now %d brkpts", i
, m_brkpts
.size()));
1980 // brks may contain new breakpoints not already in m_brkpts
1981 for (const Breakpoint
* bp
= brks
.first(); bp
!= 0; bp
= brks
.next())
1984 for (uint i
= 0; i
< m_brkpts
.size(); i
++) {
1985 if (bp
->id
== m_brkpts
[i
]->id
) {
1991 int n
= m_brkpts
.size();
1992 m_brkpts
.resize(n
+1);
1993 m_brkpts
.insert(n
, bp
);
1997 emit
breakpointsChanged();
2000 // look if there is at least one temporary breakpoint
2002 bool KDebugger::stopMayChangeBreakList() const
2004 for (int i
= m_brkpts
.size()-1; i
>= 0; i
--) {
2005 Breakpoint
* bp
= m_brkpts
[i
];
2006 if (bp
->temporary
|| bp
->type
== Breakpoint::watchpoint
)
2012 Breakpoint
* KDebugger::breakpointByFilePos(QString file
, int lineNo
,
2013 const DbgAddr
& address
)
2015 // look for exact file name match
2017 for (i
= m_brkpts
.size()-1; i
>= 0; i
--) {
2018 if (m_brkpts
[i
]->lineNo
== lineNo
&&
2019 m_brkpts
[i
]->fileName
== file
&&
2020 (address
.isEmpty() || m_brkpts
[i
]->address
== address
))
2025 // not found, so try basename
2026 // strip off directory part of file name
2027 int offset
= file
.findRev("/");
2028 file
.remove(0, offset
+1);
2030 for (i
= m_brkpts
.size()-1; i
>= 0; i
--) {
2031 // get base name of breakpoint's file
2032 QString basename
= m_brkpts
[i
]->fileName
;
2033 int offset
= basename
.findRev("/");
2035 basename
.remove(0, offset
+1);
2038 if (m_brkpts
[i
]->lineNo
== lineNo
&&
2040 (address
.isEmpty() || m_brkpts
[i
]->address
== address
))
2050 Breakpoint
* KDebugger::breakpointById(int id
)
2052 for (int i
= m_brkpts
.size()-1; i
>= 0; i
--)
2054 if (m_brkpts
[i
]->id
== id
) {
2062 void KDebugger::slotValuePopup(const QString
& expr
)
2064 // search the local variables for a match
2065 VarTree
* v
= m_localVariables
.topLevelExprByName(expr
);
2067 // not found, check watch expressions
2068 v
= m_watchVariables
.topLevelExprByName(expr
);
2070 // try a member of 'this'
2071 v
= m_localVariables
.topLevelExprByName("this");
2073 v
= ExprWnd::ptrMemberByName(v
, expr
);
2075 // nothing found; do nothing
2081 // construct the tip
2082 QString tip
= v
->getText() + " = ";
2083 if (!v
->value().isEmpty())
2089 // no value: we use some hint
2090 switch (v
->m_varKind
) {
2091 case VarTree::VKstruct
:
2094 case VarTree::VKarray
:
2098 tip
+= "?""?""?"; // 2 question marks in a row would be a trigraph
2102 emit
valuePopup(tip
);
2105 void KDebugger::slotDisassemble(const QString
& fileName
, int lineNo
)
2107 if (m_haveExecutable
) {
2108 CmdQueueItem
* cmd
= m_d
->queueCmd(DCinfoline
, fileName
, lineNo
,
2109 DebuggerDriver::QMoverrideMoreEqual
);
2110 cmd
->m_fileName
= fileName
;
2111 cmd
->m_lineNo
= lineNo
;
2115 void KDebugger::handleInfoLine(CmdQueueItem
* cmd
, const char* output
)
2117 QString addrFrom
, addrTo
;
2118 if (cmd
->m_lineNo
>= 0) {
2120 if (m_d
->parseInfoLine(output
, addrFrom
, addrTo
)) {
2121 // got the address range, now get the real code
2122 CmdQueueItem
* c
= m_d
->queueCmd(DCdisassemble
, addrFrom
, addrTo
,
2123 DebuggerDriver::QMoverrideMoreEqual
);
2124 c
->m_fileName
= cmd
->m_fileName
;
2125 c
->m_lineNo
= cmd
->m_lineNo
;
2128 QList
<DisassembledCode
> empty
;
2129 emit
disassembled(cmd
->m_fileName
, cmd
->m_lineNo
, empty
);
2132 // set program counter
2133 if (m_d
->parseInfoLine(output
, addrFrom
, addrTo
)) {
2134 // move the program counter to the start address
2135 m_d
->executeCmd(DCsetpc
, addrFrom
);
2140 void KDebugger::handleDisassemble(CmdQueueItem
* cmd
, const char* output
)
2142 QList
<DisassembledCode
> code
;
2143 code
.setAutoDelete(true);
2144 m_d
->parseDisassemble(output
, code
);
2145 emit
disassembled(cmd
->m_fileName
, cmd
->m_lineNo
, code
);
2148 void KDebugger::handleThreadList(const char* output
)
2150 QList
<ThreadInfo
> threads
;
2151 threads
.setAutoDelete(true);
2152 m_d
->parseThreadList(output
, threads
);
2153 emit
threadsChanged(threads
);
2156 void KDebugger::setThread(int id
)
2158 m_d
->queueCmd(DCthread
, id
, DebuggerDriver::QMoverrideMoreEqual
);
2161 void KDebugger::setMemoryExpression(const QString
& memexpr
)
2163 m_memoryExpression
= memexpr
;
2165 // queue the new expression
2166 if (!m_memoryExpression
.isEmpty() &&
2167 isProgramActive() &&
2168 !isProgramRunning())
2170 queueMemoryDump(true);
2174 void KDebugger::queueMemoryDump(bool immediate
)
2176 m_d
->queueCmd(DCexamine
, m_memoryExpression
, m_memoryFormat
,
2177 immediate
? DebuggerDriver::QMoverrideMoreEqual
:
2178 DebuggerDriver::QMoverride
);
2181 void KDebugger::handleMemoryDump(const char* output
)
2183 QList
<MemoryDump
> memdump
;
2184 memdump
.setAutoDelete(true);
2185 QString msg
= m_d
->parseMemoryDump(output
, memdump
);
2186 emit
memoryDumpChanged(msg
, memdump
);
2189 void KDebugger::setProgramCounter(const QString
& file
, int line
, const DbgAddr
& addr
)
2191 if (addr
.isEmpty()) {
2192 // find address of the specified line
2193 CmdQueueItem
* cmd
= m_d
->executeCmd(DCinfoline
, file
, line
);
2194 cmd
->m_lineNo
= -1; /* indicates "Set PC" UI command */
2196 // move the program counter to that address
2197 m_d
->executeCmd(DCsetpc
, addr
.asString());
2201 void KDebugger::handleSetPC(const char* /*output*/)
2203 // TODO: handle errors
2205 // now go to the top-most frame
2206 // this also modifies the program counter indicator in the UI
2210 void KDebugger::slotValueEdited(VarTree
* expr
, const QString
& text
)
2212 if (text
.simplifyWhiteSpace().isEmpty())
2213 return; /* no text entered: ignore request */
2215 ExprWnd
* wnd
= static_cast<ExprWnd
*>(expr
->listView());
2216 TRACE(QString().sprintf("Changing %s to ",
2217 wnd
->name()) + text
);
2219 // determine the lvalue to edit
2220 QString lvalue
= expr
->computeExpr();
2221 CmdQueueItem
* cmd
= m_d
->executeCmd(DCsetvariable
, lvalue
, text
);
2223 cmd
->m_exprWnd
= wnd
;
2226 void KDebugger::handleSetVariable(CmdQueueItem
* cmd
, const char* output
)
2228 QString msg
= m_d
->parseSetVariable(output
);
2231 // there was an error; display it in the status bar
2232 m_statusMessage
= msg
;
2233 emit
updateStatusMessage();
2237 // get the new value
2238 QString expr
= cmd
->m_expr
->computeExpr();
2239 CmdQueueItem
* printCmd
=
2240 m_d
->queueCmd(DCprint
, expr
, DebuggerDriver::QMoverrideMoreEqual
);
2241 printCmd
->m_expr
= cmd
->m_expr
;
2242 printCmd
->m_exprWnd
= cmd
->m_exprWnd
;
2246 #include "debugger.moc"