KDevelop API Documentation

gdbcontroller.cpp

Go to the documentation of this file.
00001 // *************************************************************************
00002 //                          gdbcontroller.cpp  -  description
00003 //                             -------------------
00004 //    begin                : Sun Aug 8 1999
00005 //    copyright            : (C) 1999 by John Birch
00006 //    email                : jbb@kdevelop.org
00007 // **************************************************************************
00008 //
00009 // **************************************************************************
00010 // *                                                                        *
00011 // *   This program is free software; you can redistribute it and/or modify *
00012 // *   it under the terms of the GNU General Public License as published by *
00013 // *   the Free Software Foundation; either version 2 of the License, or    *
00014 // *   (at your option) any later version.                                  *
00015 // *                                                                        *
00016 // **************************************************************************
00017 
00018 #include "gdbcontroller.h"
00019 
00020 #include "breakpoint.h"
00021 #include "framestackwidget.h"
00022 #include "gdbcommand.h"
00023 #include "stty.h"
00024 #include "variablewidget.h"
00025 #include "domutil.h"
00026 
00027 #include <kapplication.h>
00028 #include <kconfig.h>
00029 #include <kdebug.h>
00030 #include <kglobal.h>
00031 #include <klocale.h>
00032 #include <kmessagebox.h>
00033 #include <kprocess.h>
00034 
00035 #include <qdatetime.h>
00036 #include <qfileinfo.h>
00037 #include <qregexp.h>
00038 #include <qstring.h>
00039 
00040 #include <iostream>
00041 #include <ctype.h>
00042 #include <stdlib.h>
00043 using namespace std;
00044 
00045 // **************************************************************************
00046 //
00047 // Does all the communication between gdb and the kdevelop's debugger code.
00048 // Significatant classes being used here are
00049 //
00050 // GDBParser  - parses the "variable" data using the vartree and varitems
00051 // VarTree    - where the variable data will end up
00052 // FrameStack - tracks the program frames and allows the user to switch between
00053 //              and therefore view the calling funtions and their data
00054 // Breakpoint - Where and what to do with breakpoints.
00055 // STTY       - the tty that the _application_ will run on.
00056 //
00057 // Significant variables
00058 // state_     - be very careful setting this. The controller is totally
00059 //              dependent on this reflecting the correct state. For instance,
00060 //              if the app is busy but we don't think so, then we lose control
00061 //              of the app. The only way to get out of these situations is to
00062 //              delete (stop) the controller.
00063 // currentFrame_
00064 //            - Holds the frame number where and locals/variable information will
00065 //              go to
00066 //
00067 // Certain commands need to be "wrapped", so that the output gdb produces is
00068 // of the form "\032data_id gdb output \032data_id"
00069 // Then a very simple parse can extract this gdb output and hand it off
00070 // to its' respective parser.
00071 // To do this we set the prompt to be \032data_id before the command and then
00072 // reset to \032i to indicate the "idle".
00073 //
00074 // Note that the following does not work because in certain situations
00075 // gdb can get an error in performing the command and therefore will not
00076 // output the final echo. Hence the data will be thrown away.
00077 // (certain "info locals" will generate this error.
00078 //
00079 //  queueCmd(new GDBCommand(QString().sprintf("define printlocal\n"
00080 //                                            "echo \32%c\ninfo locals\necho \32%c\n"
00081 //                                            "end",
00082 //                                            LOCALS, LOCALS)));
00083 // (although replacing echo with "set prompt" appropriately could work Hmmmm.)
00084 //
00085 // Shared libraries and breakpoints
00086 // ================================
00087 // Shared libraries and breakpoints have a problem that has a reasonable solution.
00088 // The problem is that gdb will not accept breakpoints in source that is in a
00089 // shared library that has _not_ _yet_ been opened but will be opened via a
00090 // dlopen.
00091 //
00092 // The solution is to get gdb to tell us when a shared library has been opened.
00093 // This means that when the user sets a breakpoint, we flag this breakpoint as
00094 // pending, try to set the breakpoint and if gdb says it succeeded then flag it
00095 // as active. If gdb is not successful then we leave the breakpoint as pending.
00096 //
00097 // This is known as "lazy breakpoints"
00098 //
00099 // If the user has selected a file that is really outside the program and tried to
00100 // set a breakpoint then this breakpoint will always be pending. I can't do
00101 // anything about that, because it _might_ be in a shared library. If not they
00102 // are either fools or just misguided...
00103 //
00104 // Now that the breakpoint is pending, we need gdb to tell us when a shared
00105 // library has been loaded. We use "set stop-on 1". This breaks on _any_
00106 // library event, and we just try to set the pending breakpoints. Once we're
00107 // done, we then "continue"
00108 //
00109 // Now here's the problem with all this. If the user "step"s over code that
00110 // contains a library dlopen then it'll just keep running, because we receive a
00111 // break and hence end up doing a continue. In this situation, I do _not_
00112 // do a continue but leave it stopped with the status line reflecting the
00113 // stopped state. The frame stack is in the dl routine that caused the stop.
00114 //
00115 // There isn't any way around this, but I could allievate the problem somewhat
00116 // by only doing a "set stop-on 1" when we have pending breakpoints.
00117 //
00118 // **************************************************************************
00119 
00120 namespace GDBDebugger
00121 {
00122 
00123 // This is here so we can check for startup /shutdown problems
00124 int debug_controllerExists = false;
00125 
00126 
00127 GDBController::GDBController(VariableTree *varTree, FramestackWidget *frameStack, QDomDocument &projectDom)
00128         : DbgController(),
00129         frameStack_(frameStack),
00130         varTree_(varTree),
00131         currentFrame_(0),
00132         viewedThread_(-1),
00133         gdbOutputLen_(0),
00134         gdbOutput_(new char[2048]),
00135         holdingZone_(),
00136         currentCmd_(0),
00137         tty_(0),
00138         badCore_(QString()),
00139         state_(s_dbgNotStarted|s_appNotStarted|s_silent),
00140         programHasExited_(false),
00141         backtraceDueToProgramStop_(false),
00142         dom(projectDom),
00143         config_breakOnLoadingLibrary_(true),
00144         config_forceBPSet_(true),
00145         config_displayStaticMembers_(false),
00146         config_asmDemangle_(true),
00147         config_dbgTerminal_(false),
00148         config_gdbPath_(),
00149         config_outputRadix_(10)
00150 {
00151     gdbSizeofBuf_ = sizeof(gdbOutput_);
00152 
00153     configure();
00154     cmdList_.setAutoDelete(true);
00155 
00156     Q_ASSERT(! debug_controllerExists);
00157     debug_controllerExists = true;
00158 }
00159 
00160 // **************************************************************************
00161 
00162 // Deleting the controller involves shutting down gdb nicely.
00163 // When were attached to a process, we must first detach so that the process
00164 // can continue running as it was before being attached. gdb is quite slow to
00165 // detach from a process, so we must process events within here to get a "clean"
00166 // shutdown.
00167 GDBController::~GDBController()
00168 {
00169     delete[] gdbOutput_;
00170     debug_controllerExists = false;
00171 }
00172 
00173 // **************************************************************************
00174 
00175 void GDBController::configure()
00176 {
00177     // A a configure.gdb script will prevent these from uncontrolled growth...
00178     config_configGdbScript_       = DomUtil::readEntry(dom, "/kdevdebugger/general/configGdbScript").latin1();
00179     config_runShellScript_        = DomUtil::readEntry(dom, "/kdevdebugger/general/runShellScript").latin1();
00180     config_runGdbScript_          = DomUtil::readEntry(dom, "/kdevdebugger/general/runGdbScript").latin1();
00181 
00182 //  add macros for reading QStrings? or in configGdbScript?
00183     config_forceBPSet_            = DomUtil::readBoolEntry(dom, "/kdevdebugger/general/allowforcedbpset", true);
00184     config_dbgTerminal_           = DomUtil::readBoolEntry(dom, "/kdevdebugger/general/separatetty", false);
00185     config_gdbPath_               = DomUtil::readEntry(dom, "/kdevdebugger/general/gdbpath");
00186 
00187     bool old_displayStatic        = config_displayStaticMembers_;
00188     config_displayStaticMembers_  = DomUtil::readBoolEntry(dom, "/kdevdebugger/display/staticmembers",false);
00189 
00190     bool old_asmDemangle  = config_asmDemangle_;
00191     config_asmDemangle_   = DomUtil::readBoolEntry(dom, "/kdevdebugger/display/demanglenames",true);
00192 
00193     bool old_breakOnLoadingLibrary_ = config_breakOnLoadingLibrary_;
00194     config_breakOnLoadingLibrary_ = DomUtil::readBoolEntry(dom, "/kdevdebugger/general/breakonloadinglibs",true);
00195 
00196     int old_outputRadix  = config_outputRadix_;
00197     config_outputRadix_   = DomUtil::readIntEntry(dom, "/kdevdebugger/display/outputradix", 10);
00198     varTree_->setRadix(config_outputRadix_);
00199     
00200 
00201     if (( old_displayStatic             != config_displayStaticMembers_   ||
00202             old_asmDemangle             != config_asmDemangle_            ||
00203             old_breakOnLoadingLibrary_  != config_breakOnLoadingLibrary_  ||
00204             old_outputRadix             != config_outputRadix_)           &&
00205             dbgProcess_)
00206     {
00207         bool restart = false;
00208         if (stateIsOn(s_appBusy))
00209         {
00210             setStateOn(s_silent);
00211             pauseApp();
00212             restart = true;
00213         }
00214 
00215         if (old_displayStatic != config_displayStaticMembers_)
00216         {
00217             if (config_displayStaticMembers_)
00218                 queueCmd(new GDBCommand("set print static-members on", NOTRUNCMD,
00219                                         NOTINFOCMD));
00220             else
00221                 queueCmd(new GDBCommand("set print static-members off", NOTRUNCMD,
00222                                         NOTINFOCMD));
00223         }
00224         if (old_asmDemangle != config_asmDemangle_)
00225         {
00226             if (config_asmDemangle_)
00227                 queueCmd(new GDBCommand("set print asm-demangle on", NOTRUNCMD,
00228                                         NOTINFOCMD));
00229             else
00230                 queueCmd(new GDBCommand("set print asm-demangle off", NOTRUNCMD,
00231                                         NOTINFOCMD));
00232         }
00233 
00234         if (old_breakOnLoadingLibrary_ != config_breakOnLoadingLibrary_)
00235         {
00236             if (config_breakOnLoadingLibrary_)
00237                 queueCmd(new GDBCommand("set stop-on 1", NOTRUNCMD, NOTINFOCMD));
00238             else
00239                 queueCmd(new GDBCommand("set stop-on 0", NOTRUNCMD, NOTINFOCMD));
00240         }
00241 
00242         if (old_outputRadix != config_outputRadix_)
00243         {
00244             queueCmd(new GDBCommand(QCString().sprintf("set output-radix %d",
00245                                 config_outputRadix_), NOTRUNCMD, NOTINFOCMD));
00246 
00247             //rgruber: after changing the output radix, the watch- and the
00248             //local-variables need to be refreshed
00249             varTree_->findWatch()->requestWatchVars();
00250             queueCmd(new GDBCommand("info args", NOTRUNCMD, INFOCMD, ARGS));
00251             queueCmd(new GDBCommand("info local", NOTRUNCMD, INFOCMD, LOCALS));
00252         }
00253         
00254         if (!config_configGdbScript_.isEmpty())
00255           queueCmd(new GDBCommand("source " + config_configGdbScript_, NOTRUNCMD, NOTINFOCMD, 0));
00256 
00257         if (restart)
00258             queueCmd(new GDBCommand("continue", RUNCMD, NOTINFOCMD, 0));
00259     }
00260 }
00261 
00262 // **************************************************************************
00263 
00264 // Fairly obvious that we'll add whatever command you give me to a queue
00265 // If you tell me to, I'll put it at the head of the queue so it'll run ASAP
00266 // Not quite so obvious though is that if we are going to run again. then any
00267 // information requests become redundent and must be removed.
00268 // We also try and run whatever command happens to be at the head of
00269 // the queue.
00270 void GDBController::queueCmd(DbgCommand *cmd, bool executeNext)
00271 {
00272     // We remove any info command or _run_ command if we are about to
00273     // add a run command.
00274     if (cmd->isARunCmd())
00275         removeInfoRequests();
00276 
00277     if (executeNext)
00278         cmdList_.insert(0, cmd);
00279     else
00280         cmdList_.append (cmd);
00281 
00282     executeCmd();
00283 }
00284 
00285 // **************************************************************************
00286 
00287 // If the appliction can accept a command and we've got one waiting
00288 // then send it.
00289 // Commands can be just request for data (or change gdbs state in someway)
00290 // or they can be "run" commands. If a command is sent to gdb our internal
00291 // state will get updated.
00292 void GDBController::executeCmd()
00293 {
00294     if (stateIsOn(s_dbgNotStarted|s_waitForWrite|s_appBusy|s_shuttingDown) || !dbgProcess_)
00295         return;
00296 
00297     if (!currentCmd_)
00298     {
00299         if (cmdList_.isEmpty())
00300             return;
00301 
00302         currentCmd_ = cmdList_.take(0);
00303     }
00304 
00305     if (!currentCmd_->moreToSend())
00306     {
00307         if (currentCmd_->expectReply())
00308             return;
00309 
00310         delete currentCmd_;
00311         if (cmdList_.isEmpty())
00312         {
00313             currentCmd_ = 0;
00314             return;
00315         }
00316 
00317         currentCmd_ = cmdList_.take(0);
00318     }
00319 
00320     Q_ASSERT(currentCmd_ && currentCmd_->moreToSend());
00321 
00322     dbgProcess_->writeStdin(currentCmd_->cmdToSend().data(),
00323                                         currentCmd_->cmdLength());
00324     setStateOn(s_waitForWrite);
00325 
00326     if (currentCmd_->isARunCmd())
00327     {
00328         setStateOn(s_appBusy);
00329         kdDebug(9012) << "App is busy" << endl;
00330         setStateOff(s_appNotStarted|s_programExited|s_silent);
00331     }
00332 
00333     QString prettyCmd = currentCmd_->cmdToSend();
00334     prettyCmd.replace( QRegExp("set prompt \032.\n"), "" );
00335     prettyCmd = "(gdb) " + prettyCmd;
00336     emit gdbStdout( prettyCmd.latin1() );
00337 
00338     if (!stateIsOn(s_silent))
00339         emit dbgStatus ("", state_);
00340 }
00341 
00342 // **************************************************************************
00343 
00344 void GDBController::destroyCmds()
00345 {
00346     if (currentCmd_)
00347     {
00348         delete currentCmd_;
00349         currentCmd_ = 0;
00350     }
00351 
00352     while (!cmdList_.isEmpty())
00353         delete cmdList_.take(0);
00354 }
00355 
00356 // **********************************************************************
00357 
00358 void GDBController::removeInfoRequests()
00359 {
00360     int i = cmdList_.count();
00361     while (i)
00362     {
00363         i--;
00364         DbgCommand *cmd = cmdList_.at(i);
00365         if (cmd->isAnInfoCmd() || cmd->isARunCmd())
00366             delete cmdList_.take(i);
00367     }
00368 }
00369 
00370 // **********************************************************************
00371 
00372 // Pausing an app removes any pending run commands so that the app doesn't
00373 // start again. If we want to be silent then we remove any pending info
00374 // commands as well.
00375 void GDBController::pauseApp()
00376 {
00377     int i = cmdList_.count();
00378     while (i)
00379     {
00380         i--;
00381         DbgCommand *cmd = cmdList_.at(i);
00382         if ((stateIsOn(s_silent) && cmd->isAnInfoCmd()) || cmd->isARunCmd())
00383             delete cmdList_.take(i);
00384     }
00385 
00386     if (dbgProcess_ && stateIsOn(s_appBusy))
00387         dbgProcess_->kill(SIGINT);
00388 }
00389 
00390 // **********************************************************************
00391 
00392 // Whenever the program pauses we need to refresh the data visible to
00393 // the user. The reason we've stooped may be passed in  to be emitted.
00394 void GDBController::actOnProgramPause(const QString &msg)
00395 {
00396     // We're only stopping if we were running, of course.
00397     if (stateIsOn(s_appBusy))
00398     {
00399         kdDebug(9012) << "App is paused" << endl;
00400         setStateOff(s_appBusy);
00401         if (stateIsOn(s_silent))
00402             return;
00403 
00404         emit dbgStatus (msg, state_);
00405 
00406         // We're always at frame zero when the program stops
00407         // and we must reset the active flag
00408         viewedThread_ = -1;
00409         currentFrame_ = 0;
00410         varTree_->setActiveFlag();
00411         backtraceDueToProgramStop_ = true;
00412 
00413         // These two need to be actioned immediately. The order _is_ important
00414         if (stateIsOn(s_viewThreads))
00415             queueCmd(new GDBCommand("info thread", NOTRUNCMD, INFOCMD, INFOTHREAD), true);
00416 
00417         queueCmd(new GDBCommand("backtrace", NOTRUNCMD, INFOCMD, BACKTRACE), true);
00418         if (stateIsOn(s_viewLocals))
00419         {
00420             queueCmd(new GDBCommand("info args", NOTRUNCMD, INFOCMD, ARGS));
00421             queueCmd(new GDBCommand("info local", NOTRUNCMD, INFOCMD, LOCALS));
00422         }
00423 
00424         varTree_->findWatch()->requestWatchVars();
00425         varTree_->findWatch()->setActive();
00426         emit acceptPendingBPs();
00427     }
00428 }
00429 
00430 // **************************************************************************
00431 
00432 // There is no app anymore. This can be caused by program exiting
00433 // an invalid program specified or ...
00434 // gdb is still running though, but only the run command (may) make sense
00435 // all other commands are disabled.
00436 void GDBController::programNoApp(const QString &msg, bool msgBox)
00437 {
00438     state_ = (s_appNotStarted|s_programExited|(state_&(s_viewLocals|s_shuttingDown)));
00439     destroyCmds();
00440 
00441     // We're always at frame zero when the program stops
00442     // and we must reset the active flag
00443     viewedThread_ = -1;
00444     currentFrame_ = 0;
00445     varTree_->setActiveFlag();
00446 
00447     // Now wipe the tree out
00448     varTree_->viewport()->setUpdatesEnabled(false);
00449     varTree_->trim();
00450     varTree_->viewport()->setUpdatesEnabled(true);
00451     varTree_->repaint();
00452 
00453     frameStack_->clear();
00454 
00455     if (msgBox)
00456         KMessageBox::error(0, i18n("gdb message:\n")+msg);
00457 
00458     emit dbgStatus (msg, state_);
00459 }
00460 
00461 // **************************************************************************
00462 
00463 // Any data that isn't "wrapped", arrives here.
00464 void GDBController::parseLine(char* buf)
00465 {
00466     Q_ASSERT(*buf != (char)BLOCK_START);
00467 
00468     // Don't process blank lines
00469     if (!*buf)
00470         return;
00471 
00472     if (strncmp(buf, "The program no longer exists", 28) == 0)
00473     {
00474         programNoApp(QString(buf), false);
00475         programHasExited_ = true;   
00476         return;
00477     }
00478 
00479     if (strncmp(buf, "Prog", 4) == 0)
00480     {
00481         if ((strncmp(buf, "Program exited", 14) == 0))
00482         {
00483             kdDebug(9012) << "Parsed (exit) <" << QString(buf) << ">" << endl;
00484             programNoApp(QString(buf), false);
00485             programHasExited_ = true;   
00486             return;
00487         }
00488 
00489         if (strncmp(buf, "Program terminated", 18) == 0)
00490         {
00491             if (stateIsOn(s_core))
00492             {
00493                 KMessageBox::information(0, QString(buf));
00494                 //destroyCmds();
00495                 actOnProgramPause(QString(buf));
00496             }
00497             else
00498             {
00499                 programNoApp(QString(buf), false);
00500             }
00501 
00502             programHasExited_ = true;   
00503             return;
00504         }
00505 
00506         if (strncmp(buf, "Program received signal", 23) == 0)
00507         {
00508             // SIGINT is a "break into running program".
00509             // We do this when the user set/mod/clears a breakpoint but the
00510             // application is running.
00511             // And the user does this to stop the program also.
00512             if (strstr(buf+23, "SIGINT") && stateIsOn(s_silent))
00513                 return;
00514 
00515             // Whenever we have a signal raised then tell the user, but don't
00516             // end the program as we want to allow the user to look at why the
00517             // program has a signal that's caused the prog to stop.
00518             // Continuing from SIG FPE/SEGV will cause a "Cannot ..." and
00519             // that'll end the program.
00520             KMessageBox::information(0, QString(buf));
00521             actOnProgramPause(QString(buf));
00522             return;
00523         }
00524 
00525         // All "Program" strings cause a refresh of the program state
00526 //        kdDebug(9012) << "Unparsed (START_Prog)<" << QString(buf) << ">" << endl;
00527         actOnProgramPause(QString(buf));
00528         return;
00529     }
00530 
00531     if (strncmp(buf, "Cann", 4) == 0)
00532     {
00533         // If you end the app and then restart when you have breakpoints set
00534         // in a dynamically loaded library, gdb will halt because the set
00535         // breakpoint is trying to access memory no longer used. The breakpoint
00536         // must first be deleted, however, we want to retain the breakpoint for
00537         // when the library gets loaded again.
00540         if ( strncmp(buf, "Cannot insert breakpoint", 24)==0)
00541         {
00542             if (programHasExited_)
00543             {
00544                 setStateOn(s_silent);
00545                 actOnProgramPause(QString());
00546                 int BPNo = atoi(buf+25);
00547                 if (BPNo)
00548                 {
00549                     emit unableToSetBPNow(BPNo);
00550                     queueCmd(new GDBCommand(
00551                                         QCString().sprintf("delete %d", BPNo),
00552                                         NOTRUNCMD, NOTINFOCMD));
00553                     queueCmd(new GDBCommand("info breakpoints", NOTRUNCMD,
00554                                             NOTINFOCMD, BPLIST));
00555                     queueCmd(new GDBCommand("continue", RUNCMD, NOTINFOCMD, 0));
00556                 }
00557 //                kdDebug(9012) << "Parsed (START_cann)<" << buf << ">" << endl;
00558                 return;
00559             }
00560 
00561 //            kdDebug(9012) << "Ignore (START_cann)<" << buf << ">" << endl;
00562             //        actOnProgramPause(QString());
00563             return;
00564         }
00565 
00566         // When the program Seg faults (SEGV, FPE etc) and is then continued
00567         // we get this for threaded programs. The program is now dead.
00568         if ( strncmp(buf, "Cannot find user-level thread for LWP", 37)==0)
00569         {
00570             programNoApp(QString(buf), false);
00571             programHasExited_ = true;   
00572             return;
00573         }
00574 
00575 //        kdDebug(9012) << "Unparsed (START_cann)<" << buf << ">" << endl;
00576         actOnProgramPause(QString(buf));
00577         return;
00578     }
00579 
00580     if ( strncmp(buf, "[New Thread", 11)==0)
00581     {
00582         if (!stateIsOn(s_viewThreads))
00583         {
00584             setStateOn(s_viewThreads);
00585             queueCmd(new GDBCommand("info thread", NOTRUNCMD, INFOCMD, INFOTHREAD),
00586                                         true);
00587         }
00588         return;
00589     }
00590 
00591     // When the watchpoint variable goes out of scope the program stops
00592     // and tells you. (sometimes)
00593     if (strncmp(buf, "Watc", 4) == 0)
00594     {
00595         if ((strncmp(buf, "Watchpoint", 10)==0) &&
00596             (strstr(buf, "deleted because the program has left the block")))
00597         {
00598             int BPNo = atoi(buf+11);
00599             if (BPNo)
00600             {
00601                 queueCmd(new GDBCommand(QCString().sprintf("delete %d",BPNo),
00602                                                 NOTRUNCMD, NOTINFOCMD));
00603             }
00604             actOnProgramPause(QString(buf));
00605         }
00606 
00607         queueCmd(new GDBCommand("info breakpoints",
00608                                         NOTRUNCMD, NOTINFOCMD, BPLIST));
00609 
00610 //        kdDebug(9012) << "Parsed (START_Watc)<" << buf << ">" << endl;
00611         return;
00612     }
00613 
00614     if (strncmp(buf, "Brea", 4) == 0 ||
00615         strncmp(buf, "Hard", 4) == 0)
00616     {
00617         // Starts with "Brea" so assume "Breakpoint" and just get a full
00618         // breakpoint list. Note that the state is unchanged.
00619         // Much later: I forget why I did it like this :-o
00620         queueCmd(new GDBCommand("info breakpoints",
00621                                         NOTRUNCMD, NOTINFOCMD, BPLIST));
00622 
00623 //        kdDebug(9012) << "Parsed (BP) <" << buf << ">" << endl;
00624         return;
00625     }
00626 
00627     if (strncmp(buf, "Temp", 4) == 0)
00628     {
00629         if (strncmp(buf, "Temporarily disabling shared library breakpoints:", 49) == 0)
00630         {
00631             kdDebug(9012) << "Parsed (START_Temp)<" << buf << ">" << endl;
00632             return;
00633         }
00634 
00635         actOnProgramPause(QString(buf));
00636         kdDebug(9012) << "Unparsed (START_Temp)<" << buf << ">" << endl;
00637         return;
00638     }
00639 
00640     if (strncmp(buf, "Stop", 4) == 0)
00641     {
00642         if (strncmp(buf, "Stopped due to shared library event", 35) == 0)
00643         {
00644             // When it's a library event, we try and set any pending
00645             // breakpoints, and that done, just continue onwards.
00646             // HOWEVER, this only applies when we did a "run" or a
00647             // "continue" otherwise the program will just keep going
00648             // on a "step" type command, in this situation and that's
00649             // REALLY wrong.
00650             kdDebug(9012) << "Parsed (sh.lib) <" << buf << ">" << endl;
00651             if (currentCmd_ && (currentCmd_->rawDbgCommand() == "run" ||
00652                                 currentCmd_->rawDbgCommand() == "continue"))
00653             {
00654                 setStateOn(s_silent);     // be quiet, children!!
00655                 setStateOff(s_appBusy);   // and stop that fiddling.
00656                 kdDebug(9012) << "App is paused (quietly)" << endl;
00657                 emit acceptPendingBPs();  // now go clean your rooms!
00658                 queueCmd(new GDBCommand("continue", RUNCMD, NOTINFOCMD, 0));
00659             }
00660             else
00661                 actOnProgramPause(QString(buf));
00662 
00663             return;
00664         }
00665 
00666         // A stop line means we've stopped. We're not really expecting one
00667         // of these unless it's a library event so just call actOnPause
00668         actOnProgramPause(QString(buf));
00669         kdDebug(9012) << "Unparsed (START_Stop)<" << buf << ">" << endl;
00670         return;
00671     }
00672 
00673     if (strncmp(buf, "warn", 4) == 0)
00674     {
00675         if (strncmp(buf, "warning: core file may not match", 32) == 0 ||
00676                 strncmp(buf, "warning: exec file is newer", 27) == 0)
00677         {
00678             badCore_ = QString(buf);
00679         }
00680         actOnProgramPause(QString());
00681         return;
00682     }
00683 
00684     if (strncmp(buf, "Core", 4) == 0)
00685     {
00686         kdDebug(9012) << "Parsed (Core)<" << buf << ">" << endl;
00687         actOnProgramPause(buf);
00688         if (!badCore_.isEmpty() &&
00689                         strncmp(buf, "Core was generated by", 21) == 0)
00690             KMessageBox::error( 0,
00691                                 i18n("gdb message:\n")+badCore_ + "\n" +
00692                                 QString(buf)+"\n\n"+
00693                                 i18n("The symbols gdb resolves may be suspect"),
00694                                 i18n("Mismatched Core File"));
00695 
00696         return;
00697     }
00698 
00699     if (strncmp(buf, "No symbol", 9) == 0 ||                    // watch point failed
00700             strncmp(buf, "Single", 6) == 0 ||                   // Single stepping
00701             strncmp(buf, "No source file named", 20) == 0      ||   // breakpoint not set
00702             strncmp(buf, "[Switching to Thread", 20) == 0      ||    //
00703             strncmp(buf, "[Thread debugging using", 23) == 0   ||
00704             strncmp(buf, "Current language:", 17) == 0         ||
00705             strncmp(buf, "Error while mapping shared library sections:", 44) == 0  ||
00706             strncmp(buf, "Error while reading shared library symbols:", 43) == 0 ||
00707             *buf == ':' )
00708     {
00709         // We don't change state, because this falls out when a run command
00710         // starts rather than when a run command stops.
00711         // Or.... it falls out with other messages that _are_ handled.
00712         return;
00713     }
00714 
00715     // The first "step into" into a source file that is missing
00716     // prints on stderr with a message that there's no source. Subsequent
00717     // "step into"s just print line number at filename. Both start with a
00718     // numeric char.
00719     // Also a 0x message arrives everytime the program stops
00720     // In the case where there is no source available and you were
00721     // then this message should appear. Otherwise a program location
00722     // message will arrive immediately after this and overwrite it.
00723     if (isdigit(*buf))
00724     {
00725 //        kdDebug(9012) << "Parsed (digit)<" << buf << ">" << endl;
00726         parseProgramLocation(buf);
00727         //    actOnProgramPause(QString(buf));
00728         return;
00729     }
00730 
00731     
00733     if (
00734         strstr(buf, "not in executable format:")                ||
00735         strstr(buf, "No such file or directory.")               ||      // does this fall out?
00736         strstr(buf, i18n("No such file or directory.").local8Bit())||   // from system via gdb
00737         strstr(buf, "is not a core dump:")                      ||
00738         strncmp(buf, "ptrace: No such process.", 24)==0         ||
00739         strncmp(buf, "ptrace: Operation not permitted.", 32)==0 ||
00740         strncmp(buf, "No executable file specified.", 29)==0)
00741     {
00742         programNoApp(QString(buf), true);
00743         kdDebug(9012) << "Bad file <"  << buf << ">" << endl;
00744         return;
00745     }
00746 
00747     // Any other line that falls out when we are busy is a stop. We
00748     // might blank a previous message or display this message
00749     if (stateIsOn(s_appBusy))
00750     {
00751         if ((strncmp(buf, "No ", 3)==0) && strstr(buf, "not meaningful"))
00752         {
00753             kdDebug(9012) << "Parsed (not meaningful)<" << buf <<  ">" << endl;
00754             actOnProgramPause(QString(buf));
00755             return;
00756         }
00757 
00758         kdDebug(9012) << "Unparsed (default - busy)<" << buf << ">" << endl;
00759         actOnProgramPause(QString());
00760         return;
00761     }
00762 
00763     // All other lines are ignored
00764     kdDebug(9012) << "Unparsed (default - not busy)<" << buf << ">" << endl;
00765     return;
00766 }
00767 
00768 // **************************************************************************
00769 
00770 // The program location falls out of gdb, preceeded by \032\032. We treat
00771 // it as a wrapped command (even though it doesn't have a trailing \032\032.
00772 // The data gets parsed here and emitted in its component parts.
00773 void GDBController::parseProgramLocation(char *buf)
00774 {
00775     if (stateIsOn(s_silent))
00776     {
00777         // It's a silent stop. This means that the queue will have a "continue"
00778         // in it somewhere. The only action needed is to reset the state so
00779         // that queue'd items can be sent to gdb
00780         kdDebug(9012) << "App is paused <" << buf << ">" << endl;
00781         setStateOff(s_appBusy);
00782         return;
00783     }
00784 
00785     //  "/opt/qt/src/widgets/qlistview.cpp:1558:42771:beg:0x401b22f2"
00786     QRegExp regExp1("(.*):(\\d+):\\d+:[a-z]+:(0x[abcdef0-9]+)$");
00787     regExp1.setMinimal(true);
00788     if ( regExp1.search(buf, 0) >= 0 )
00789     {
00790         actOnProgramPause(QString());
00791         emit showStepInSource( regExp1.cap(1),
00792                                regExp1.cap(2).toInt(),
00793                                regExp1.cap(3) );
00794         return;
00795     }
00796 
00797     if (stateIsOn(s_appBusy))
00798         actOnProgramPause(i18n("No source: %1").arg(QString(buf)));
00799     else
00800         emit dbgStatus (i18n("No source: %1").arg(QString(buf)), state_);
00801 
00802     // This extracts the address the program has stopped at as
00803     // that is the only piece of info in this line we might use.
00804     QRegExp regExp3("^(0x[abcdef0-9]+)");
00805     if (regExp3.search(buf, 0) >= 0)
00806         emit showStepInSource(QString(),
00807                               -1,
00808                               regExp3.cap(1));
00809     else
00810         emit showStepInSource("", -1, "");
00811 
00812 }
00813 
00814 // **************************************************************************
00815 
00816 // parsing the backtrace list will cause the vartree to be refreshed
00817 void GDBController::parseBacktraceList(char *buf)
00818 {
00819     frameStack_->parseGDBBacktraceList(buf);
00820     if (backtraceDueToProgramStop_)
00821     {
00822         varTree_->trimExcessFrames();
00823         VarFrameRoot *frame = varTree_->findFrame(currentFrame_, viewedThread_);
00824         if (frame)
00825             frame->setFrameName(
00826                 frameStack_->getFrameName(currentFrame_, viewedThread_));
00827         backtraceDueToProgramStop_ = false;
00828     }
00829 }
00830 
00831 // **************************************************************************
00832 
00833 void GDBController::parseThreadList(char *buf)
00834 {
00835     frameStack_->parseGDBThreadList(buf);
00836     viewedThread_ = frameStack_->viewedThread();
00837     varTree_->setCurrentThread(viewedThread_);
00838 }
00839 
00840 // **************************************************************************
00841 
00842 // When a breakpoint has been set, gdb responds with some data about the
00843 // new breakpoint. We just inform the breakpoint system about this.
00844 void GDBController::parseBreakpointSet(char *buf)
00845 {
00846     if (GDBSetBreakpointCommand *BPCmd = dynamic_cast<GDBSetBreakpointCommand*>(currentCmd_))
00847     {
00848         // ... except in this case :-) A -1 key tells us that this is
00849         // a special internal breakpoint, and we shouldn't do anything
00850         // with it. Currently there are _no_ internal breakpoints.
00851         if (BPCmd->getKey() != -1)
00852             emit rawGDBBreakpointSet(buf, BPCmd->getKey());
00853     }
00854 }
00855 
00856 // **************************************************************************
00857 
00858 // Extra data needed by an item was requested. Here's the result.
00859 void GDBController::parseRequestedData(char *buf)
00860 {
00861     if (GDBItemCommand *gdbItemCommand = dynamic_cast<GDBItemCommand*> (currentCmd_))
00862     {
00863         // Fish out the item from the command and let it deal with the data
00864         VarItem *item = gdbItemCommand->getItem();
00865         varTree_->viewport()->setUpdatesEnabled(false);
00866         item->updateValue(buf);
00867         item->trim();
00868         varTree_->viewport()->setUpdatesEnabled(true);
00869         varTree_->repaint();
00870     }
00871 }
00872 
00873 // **************************************************************************
00874 
00875 // jw
00876 void GDBController::parseWhatis(char *buf)
00877 {
00878     if (GDBItemCommand *gdbItemCommand = dynamic_cast<GDBItemCommand*> (currentCmd_))
00879     {
00880         // Fish out the item from the command and let it deal with the data
00881         VarItem *item = gdbItemCommand->getItem();
00882         varTree_->viewport()->setUpdatesEnabled(false);
00883 
00884         item->updateType(buf);
00885 //        item->trim();
00886 
00887         varTree_->viewport()->setUpdatesEnabled(true);
00888         varTree_->repaint();
00889     }
00890 }
00891 
00892 // **************************************************************************
00893 
00894 // If the user gives us a bad program, catch that here.
00895 //void GDBController::parseFileStart(char *buf)
00896 //{
00897 //  if (strstr(buf, "not in executable format:") ||
00898 //      strstr(buf, "No such file or directory."))
00899 //  {
00900 //    programNoApp(QString(buf), true);
00901 //    kdDebug(9012) << "Bad file start <" << buf << ">" << endl;
00902 //  }
00903 //}
00904 
00905 // **************************************************************************
00906 
00907 // Select a different frame to view. We need to get and (maybe) display
00908 // where we are in the program source.
00909 void GDBController::parseFrameSelected(char *buf)
00910 {
00911     char lookup[3] = {BLOCK_START, SRC_POSITION, 0};
00912     if (char *start = strstr(buf, lookup))
00913     {
00914         if (char *end = strchr(start, '\n'))
00915             *end = 0;      // clobber the new line
00916         parseProgramLocation(start+2);
00917         return;
00918     }
00919 
00920     if (!stateIsOn(s_silent))
00921     {
00922         emit showStepInSource("", -1, "");
00923         emit dbgStatus (i18n("No source: %1").arg(QString(buf)), state_);
00924     }
00925 }
00926 
00927 // **************************************************************************
00928 
00929 // This is called twice per program stop. First to process the arguments
00930 // to a fn  and then again to process the locals.
00931 // Once the locals have been process we trim the tree of items that are
00932 // inactive.
00933 void GDBController::parseLocals(char type, char *buf)
00934 {
00935     varTree_->viewport()->setUpdatesEnabled(false);
00936 
00937     // The locals are always attached to the currentFrame
00938     VarFrameRoot *frame = varTree_->findFrame(currentFrame_, viewedThread_);
00939     if (!frame)
00940     {
00941         frame = new VarFrameRoot(varTree_, currentFrame_, viewedThread_);
00942         frame->setFrameName(
00943                 frameStack_->getFrameName(currentFrame_, viewedThread_));
00944     }
00945 
00946     Q_ASSERT(frame);
00947 
00948     if (type == (char) ARGS)
00949     {
00950         frame->setParams(buf);
00951     }
00952     else
00953     {
00954         frame->setLocals(buf);
00955         // Trim the whole tree when we're on the top most
00956         // frame so that they always see only "frame 0" on a program stop.
00957         // User selects frame 1, will show both frame 0 and frame 1.
00958         // Reselecting a frame 0 regenerates the data and therefore trims
00959         // the whole tree _but_ all the items in every frame will be active
00960         // so nothing will be deleted.
00961         if (currentFrame_ == 0 || viewedThread_ == -1)
00962             varTree_->trim();
00963         else
00964             frame->trim();
00965     }
00966 
00967     varTree_->viewport()->setUpdatesEnabled(true);
00968     varTree_->repaint();
00969 }
00970 
00971 // **************************************************************************
00972 
00973 // We are given a block of data that starts with \032. We now try to find a
00974 // matching end block and if we can we shoot the data of to the appropriate
00975 // parser for that type of data.
00976 char *GDBController::parseCmdBlock(char *buf)
00977 {
00978     Q_ASSERT(*buf == (char)BLOCK_START);
00979 //    kdDebug(9012) << "parseCmdBlock=<" << buf << ">" << endl;
00980 
00981     char *end = 0;
00982     switch (*(buf+1))
00983     {
00984     case IDLE:
00985         // remove the idle tag because they often don't come in pairs
00986         return buf+1;
00987 
00988     case SRC_POSITION:
00989         // file and line number info that gdb just drops out starts with a
00990         // \32 but ends with a \n. Could treat this as a line rather than
00991         // a block. Ah well!
00992         if((end = strchr(buf, '\n')))
00993             *end = 0;      // Make a null terminated c-string
00994         break;
00995 
00996     default:
00997         {
00998             // match the start block with the end block if we can.
00999             char lookup[3] = {BLOCK_START, *(buf+1), 0};
01000             if ((end = strstr(buf+2, lookup)))
01001             {
01002                 *end = 0;         // Make a null terminated c-string
01003                 end++;            // The real end!
01004             }
01005             break;
01006         }
01007     }
01008 
01009     if (end)
01010     {
01011         char cmdType = *(buf+1);
01012         buf +=2;
01013         switch (cmdType)
01014         {
01015         case FRAME:
01016             parseFrameSelected        (buf);
01017             break;
01018         case SET_BREAKPT:
01019             parseBreakpointSet        (buf);
01020             break;
01021         case SRC_POSITION:
01022             parseProgramLocation      (buf);
01023             break;
01024         case ARGS:
01025         case LOCALS:
01026             parseLocals               (cmdType, buf);
01027             break;
01028         case DATAREQUEST:
01029             parseRequestedData        (buf);
01030             break;
01031         case WHATIS:
01032             parseWhatis               (buf);
01033             break;
01034         case BPLIST:
01035             emit rawGDBBreakpointList (buf);
01036             break;
01037         case BACKTRACE:
01038             parseBacktraceList        (buf);
01039             break;
01040         case INFOTHREAD:
01041             parseThreadList           (buf);
01042             break;
01043         case DISASSEMBLE:
01044             emit rawGDBDisassemble    (buf);
01045             break;
01046         case MEMDUMP:
01047             emit rawGDBMemoryDump     (buf);
01048             break;
01049         case REGISTERS:
01050             emit rawGDBRegisters      (buf);
01051             break;
01052         case LIBRARIES:
01053             emit rawGDBLibraries      (buf);
01054             break;
01055 //         case DETACH:
01056 //             setStateOff(s_attached);
01057 //             break;
01058 //         case FILE_START:
01059 //             parseFileStart            (buf);
01060 //             break;
01061         default:
01062             break;
01063         }
01064 
01065         // Once we've dealt with the data, we can remove the current command if
01066         // it is a match for this data.
01067         if (currentCmd_ && currentCmd_->typeMatch(cmdType))
01068         {
01069             delete currentCmd_;
01070             currentCmd_ = 0;
01071         }
01072     }
01073 
01074     return end;
01075 }
01076 
01077 // **************************************************************************
01078 
01079 // Deals with data that just falls out of gdb. Basically waits for a line
01080 // terminator to arrive and then gives it to the line parser.
01081 char *GDBController::parseOther(char *buf)
01082 {
01083     // Could be the start of a block that isn't terminated yet
01084     Q_ASSERT (*buf != (char)BLOCK_START);
01085 //    kdDebug(9012) << "parseOther=<" << buf << ">" << endl;
01086 
01087     char *end = buf;
01088     while (*end)
01089     {
01090         if (*end=='(')
01091         {   // quick test before a big test
01092             // This falls out of gdb without a \n terminator. Sometimes
01093             // a "Stopped due" message will fall out imediately behind this
01094             // creating a "line". Soemtimes it doesn'y. So we need to check
01095             // for and remove them first then continue as if it wasn't there.
01096             // And there can be more that one in a row!!!!!
01097             // Isn't this bloody awful...
01098             if (strncmp(end, "(no debugging symbols found)...", 31) == 0)
01099             {
01100                 //                emit dbgStatus (QCString(end, 32), state_);
01101                 return end+30;    // The last char parsed
01102             }
01103         }
01104 
01105         if (*end=='\n')
01106         {
01107             // Join continuation lines together by removing the '\n'
01108             if ((end-buf > 2) && (*(end-1) == ' ' && *(end-2) == ',') || (*(end-1) == ':'))
01109                 *end = ' ';
01110             else
01111             {
01112                 *end = 0;        // make a null terminated c-string
01113                 parseLine(buf);
01114                 return end;
01115             }
01116         }
01117 
01118         // Remove stuff like "junk\32i".
01119         // This only removes "junk" and leaves "\32i"
01120         if (*end == (char)BLOCK_START)
01121             return end-1;
01122 
01123         end++;
01124     }
01125 
01126     return 0;
01127 }
01128 
01129 // **************************************************************************
01130 
01131 char *GDBController::parse(char *buf)
01132 {
01133     char *unparsed = buf;
01134     while (*unparsed)
01135     {
01136         char *parsed;
01137         if (*unparsed == (char)BLOCK_START)
01138             parsed = parseCmdBlock(unparsed);
01139         else
01140             parsed = parseOther(unparsed);
01141 
01142         if (!parsed)
01143             break;
01144 
01145         // Move one beyond the end of the parsed data
01146         unparsed = parsed+1;
01147     }
01148 
01149     return (unparsed==buf) ? 0 : unparsed;
01150 }
01151 
01152 // **************************************************************************
01153 
01154 void GDBController::setBreakpoint(const QCString &BPSetCmd, int key)
01155 {
01156     queueCmd(new GDBSetBreakpointCommand(BPSetCmd, key));
01157 }
01158 
01159 // **************************************************************************
01160 
01161 void GDBController::clearBreakpoint(const QCString &BPClearCmd)
01162 {
01163     queueCmd(new GDBCommand(BPClearCmd, NOTRUNCMD, NOTINFOCMD));
01164     // Note: this is NOT an info command, because gdb doesn't explictly tell
01165     // us that the breakpoint has been deleted, so if we don't have it the
01166     // BP list doesn't get updated.
01167     queueCmd(new GDBCommand("info breakpoints", NOTRUNCMD, NOTINFOCMD, BPLIST));
01168 }
01169 
01170 // **************************************************************************
01171 
01172 void GDBController::modifyBreakpoint( const Breakpoint& BP )
01173 {
01174     Q_ASSERT(BP.isActionModify());
01175     if (BP.dbgId()>0)
01176     {
01177         if (BP.changedCondition())
01178             queueCmd(new GDBCommand(QCString().sprintf("condition %d %s",
01179                             BP.dbgId(), BP.conditional().latin1()),
01180                             NOTRUNCMD, NOTINFOCMD));
01181 
01182         if (BP.changedIgnoreCount())
01183             queueCmd(new GDBCommand(QCString().sprintf("ignore %d %d",
01184                             BP.dbgId(), BP.ignoreCount()),
01185                             NOTRUNCMD, NOTINFOCMD));
01186 
01187         if (BP.changedEnable())
01188             queueCmd(new GDBCommand(QCString().sprintf("%s %d",
01189                             BP.isEnabled() ? "enable" : "disable",
01190                             BP.dbgId()), NOTRUNCMD, NOTINFOCMD));
01191 
01192         //        BP.setDbgProcessing(true);
01193         // Note: this is NOT an info command, because gdb doesn't explictly tell
01194         // us that the breakpoint has been deleted, so if we don't have it the
01195         // BP list doesn't get updated.
01196         queueCmd(new GDBCommand("info breakpoints", NOTRUNCMD, NOTINFOCMD,
01197                                 BPLIST));
01198     }
01199 }
01200 
01201 // **************************************************************************
01202 //                                SLOTS
01203 //                                *****
01204 // For most of these slots data can only be sent to gdb when it
01205 // isn't busy and it is running.
01206 
01207 // **************************************************************************
01208 
01209 void GDBController::slotStart(const QString& shell, const DomUtil::PairList& run_envvars, const QString& run_directory, const QString &application, const QString& run_arguments)
01210 {
01211     badCore_ = QString();
01212 
01213     Q_ASSERT (!dbgProcess_ && !tty_);
01214 
01215     tty_ = new STTY(config_dbgTerminal_, "konsole");
01216     if (!config_dbgTerminal_)
01217     {
01218         connect( tty_, SIGNAL(OutOutput(const char*)), SIGNAL(ttyStdout(const char*)) );
01219         connect( tty_, SIGNAL(ErrOutput(const char*)), SIGNAL(ttyStderr(const char*)) );
01220     }
01221 
01222     QString tty(tty_->getSlave());
01223     if (tty.isEmpty())
01224     {
01225         KMessageBox::error(0, i18n("GDB cannot use the tty* or pty* devices.\n"
01226                                    "Check the settings on /dev/tty* and /dev/pty*\n"
01227                                    "As root you may need to \"chmod ug+rw\" tty* and pty* devices "
01228                                    "and/or add the user to the tty group using "
01229                                    "\"usermod -G tty username\"."));
01230 
01231         delete tty_;
01232         tty_ = 0;
01233         return;
01234     }
01235 
01236     dbgProcess_ = new KProcess;
01237 
01238     connect( dbgProcess_, SIGNAL(receivedStdout(KProcess *, char *, int)),
01239              this,        SLOT(slotDbgStdout(KProcess *, char *, int)) );
01240 
01241     connect( dbgProcess_, SIGNAL(receivedStderr(KProcess *, char *, int)),
01242              this,        SLOT(slotDbgStderr(KProcess *, char *, int)) );
01243 
01244     connect( dbgProcess_, SIGNAL(wroteStdin(KProcess *)),
01245              this,        SLOT(slotDbgWroteStdin(KProcess *)) );
01246 
01247     connect( dbgProcess_, SIGNAL(processExited(KProcess*)),
01248              this,        SLOT(slotDbgProcessExited(KProcess*)) );
01249 
01250     application_ = application;
01251     if (!shell.isEmpty())
01252     {
01253         *dbgProcess_ << "/bin/sh" << "-c" << shell + " " +config_gdbPath_
01254                       + "gdb " + application + " -fullname -nx -quiet";
01255         emit gdbStdout(QString( "/bin/sh -c " + shell + " " +config_gdbPath_
01256                       + "gdb " + application + " -fullname -nx -quiet" ).latin1());
01257     }
01258     else
01259     {
01260         *dbgProcess_ << config_gdbPath_ + "gdb" << application
01261                         << "-fullname" << "-nx" << "-quiet";
01262         emit gdbStdout(QString( config_gdbPath_ + "gdb " + application +
01263                         " -fullname -nx -quiet" ).latin1());
01264     }
01265 
01266     dbgProcess_->start( KProcess::NotifyOnExit,
01267                         KProcess::Communication(KProcess::All));
01268 
01269     setStateOff(s_dbgNotStarted);
01270     emit dbgStatus ("", state_);
01271 
01272     // Initialise gdb. At this stage gdb is sitting wondering what to do,
01273     // and to whom. Organise a few things, then set up the tty for the application,
01274     // and the application itself
01275 
01276     queueCmd(new GDBCommand("set edit off", NOTRUNCMD, NOTINFOCMD, 0));
01277     queueCmd(new GDBCommand("set confirm off", NOTRUNCMD, NOTINFOCMD));
01278 
01279     if (config_displayStaticMembers_)
01280         queueCmd(new GDBCommand("set print static-members on", NOTRUNCMD,
01281                                     NOTINFOCMD));
01282     else
01283         queueCmd(new GDBCommand("set print static-members off", NOTRUNCMD, NOTINFOCMD));
01284 
01285     queueCmd(new GDBCommand(QCString("tty ")+tty.latin1(), NOTRUNCMD, NOTINFOCMD));
01286 
01287     // This makes gdb pump a variable out on one line.
01288     queueCmd(new GDBCommand("set width 0", NOTRUNCMD, NOTINFOCMD));
01289     queueCmd(new GDBCommand("set height 0", NOTRUNCMD, NOTINFOCMD));
01290 
01291     // Get gdb to notify us of shared library events. This allows us to
01292     // set breakpoints in shared libraries, that the user has set previously.
01293     // The 1 doesn't mean anything specific, just any non-zero value to
01294     // satisfy gdb!
01295     // An alternative to this would be catch load, catch unload, but they don't work!
01296     if (config_breakOnLoadingLibrary_)
01297         queueCmd(new GDBCommand("set stop-on 1", NOTRUNCMD, NOTINFOCMD));
01298     else
01299         queueCmd(new GDBCommand("set stop-on 0", NOTRUNCMD, NOTINFOCMD));
01300 
01301     queueCmd(new GDBCommand("handle SIG32 pass nostop noprint", NOTRUNCMD,
01302                             NOTINFOCMD));
01303     queueCmd(new GDBCommand("handle SIG43 pass nostop noprint", NOTRUNCMD,
01304                             NOTINFOCMD));
01305 
01306     // Print some nicer names in disassembly output. Although for an assembler
01307     // person this may actually be wrong and the mangled name could be better.
01308     if (config_asmDemangle_)
01309         queueCmd(new GDBCommand("set print asm-demangle on", NOTRUNCMD, NOTINFOCMD));
01310     else
01311         queueCmd(new GDBCommand("set print asm-demangle off", NOTRUNCMD, NOTINFOCMD));
01312 
01313     // make sure output radix is always set to users view.
01314     queueCmd(new GDBCommand(QCString().sprintf("set output-radix %d",  config_outputRadix_), NOTRUNCMD, NOTINFOCMD));
01315        
01316     // Change the "Working directory" to the correct one
01317     QCString tmp( "cd " + QFile::encodeName( run_directory ));
01318     queueCmd(new GDBCommand(tmp, NOTRUNCMD, NOTINFOCMD));
01319 
01320     // Set the run arguments
01321     if (!run_arguments.isEmpty())
01322         queueCmd(new GDBCommand(QCString("set args ") + run_arguments.latin1(), NOTRUNCMD, NOTINFOCMD));
01323 
01324     // Get the run environment variables pairs into the environstr string
01325     // in the form of: "ENV_VARIABLE=ENV_VALUE" and send to gdb using the
01326     // "set enviroment" command
01327     // Note that we quote the variable value due to the possibility of
01328     // embedded spaces
01329     QString environstr;
01330     DomUtil::PairList::ConstIterator it;
01331     for (it = run_envvars.begin(); it != run_envvars.end(); ++it)
01332     {
01333         environstr = "set environment ";
01334         environstr += (*it).first;
01335         environstr += "=";
01336         environstr += (*it).second;
01337         queueCmd(new GDBCommand(environstr.latin1(), NOTRUNCMD, NOTINFOCMD));
01338     }
01339 
01340     // Organise any breakpoints.
01341     emit acceptPendingBPs();
01342 
01343     // Now gdb has been started and the application has been loaded,
01344     // BUT the app hasn't been started yet! A run command is about to be issued
01345     // by whoever is controlling us. Or we might be asked to load a core, or
01346     // attach to a running process.
01347 }
01348 
01349 // **************************************************************************
01350 
01351 void GDBController::slotStopDebugger()
01352 {
01353     kdDebug(9012) << "GDBController::slotStopDebugger() called" << endl;
01354     if (stateIsOn(s_shuttingDown) || !dbgProcess_)
01355         return;
01356 
01357     setStateOn(s_shuttingDown|s_silent);
01358     kdDebug(9012) << "GDBController::slotStopDebugger() executing" << endl;
01359     destroyCmds();
01360 
01361     QTime start;
01362     QTime now;
01363 
01364     // Get gdb's attention if it's busy. We need gdb to be at the
01365     // command line so we can stop it.
01366     if (stateIsOn(s_appBusy))
01367     {
01368         kdDebug(9012) << "gdb busy on shutdown - stopping gdb (SIGINT)" << endl;
01369         dbgProcess_->kill(SIGINT);
01370         start = QTime::currentTime();
01371         while (-1)
01372         {
01373             kapp->processEvents(20);
01374             now = QTime::currentTime();
01375             if (!stateIsOn(s_appBusy) || start.msecsTo( now ) > 2000)
01376                 break;
01377         }
01378     }
01379 
01380     // If the app is attached then we release it here. This doesn't stop
01381     // the app running.
01382     if (stateIsOn(s_attached))
01383     {
01384         kdDebug(9012) << "App is busy" << endl;
01385         setStateOn(s_appBusy);
01386         const char *detach="detach\n";
01387         if (!dbgProcess_->writeStdin(detach, strlen(detach)))
01388             kdDebug(9012) << "failed to write 'detach' to gdb" << endl;
01389         emit gdbStdout("(gdb) detach");
01390         start = QTime::currentTime();
01391         while (-1)
01392         {
01393              kapp->processEvents(20);
01394              now = QTime::currentTime();
01395              if (!stateIsOn(s_attached) || start.msecsTo( now ) > 2000)
01396                  break;
01397         }
01398     }
01399 
01400     // Now try to stop gdb running.
01401     kdDebug(9012) << "App is busy" << endl;
01402     setStateOn(s_appBusy);
01403     const char *quit="quit\n";
01404     if (!dbgProcess_->writeStdin(quit, strlen(quit)))
01405         kdDebug(9012) << "failed to write 'quit' to gdb" << endl;
01406 
01407     emit gdbStdout("(gdb) quit");
01408     start = QTime::currentTime();
01409     while (-1)
01410     {
01411          kapp->processEvents(20);
01412          now = QTime::currentTime();
01413          if (stateIsOn(s_programExited) || start.msecsTo( now ) > 2000)
01414              break;
01415     }
01416 
01417     // We cannot wait forever.
01418     if (!stateIsOn(s_programExited))
01419     {
01420         kdDebug(9012) << "gdb not shutdown - killing" << endl;
01421         dbgProcess_->kill(SIGKILL);
01422     }
01423 
01424     delete dbgProcess_;    dbgProcess_ = 0;
01425     delete tty_;           tty_ = 0;
01426 
01427     state_ = s_dbgNotStarted | s_appNotStarted | s_silent;
01428     emit dbgStatus (i18n("Debugger stopped"), state_);
01429 }
01430 
01431 // **************************************************************************
01432 
01433 void GDBController::slotCoreFile(const QString &coreFile)
01434 {
01435     setStateOff(s_silent);
01436     setStateOn(s_core);
01437 
01438     queueCmd(new GDBCommand(QCString("core ") + coreFile.latin1(), NOTRUNCMD,
01439                                 NOTINFOCMD, 0));
01440 
01441     // We don't know at this point whether this executable is a threaded
01442     // program. Maybe the backtrace command will force gdb to tell us by
01443     // sending us "[New Thread" lines. At that point we issue the "info thread"
01444     // command
01445     queueCmd(new GDBCommand("backtrace", NOTRUNCMD, INFOCMD, BACKTRACE));
01446 
01447     if (stateIsOn(s_viewLocals))
01448     {
01449         queueCmd(new GDBCommand("info args", NOTRUNCMD, INFOCMD, ARGS));
01450         queueCmd(new GDBCommand("info local", NOTRUNCMD, INFOCMD, LOCALS));
01451     }
01452 }
01453 
01454 // **************************************************************************
01455 
01456 void GDBController::slotAttachTo(int pid)
01457 {
01458     setStateOff(s_appNotStarted|s_programExited|s_silent);
01459     setStateOn(s_attached);
01460     queueCmd(new GDBCommand(
01461         QCString().sprintf("attach %d", pid), NOTRUNCMD, NOTINFOCMD, 0));
01462 
01463     // We don't know at this point whether this executable is a threaded
01464     // program. Msybe the backtrace command will force gdb to tell us by
01465     // sending us "[New Thread" lines. At that point we issue the "info thread"
01466     // command
01467     queueCmd(new GDBCommand("backtrace", NOTRUNCMD, INFOCMD, BACKTRACE));
01468 
01469     if (stateIsOn(s_viewLocals))
01470     {
01471         queueCmd(new GDBCommand("info args", NOTRUNCMD, INFOCMD, ARGS));
01472         queueCmd(new GDBCommand("info local", NOTRUNCMD, INFOCMD, LOCALS));
01473     }
01474 }
01475 
01476 // **************************************************************************
01477 
01478 void GDBController::slotRun()
01479 {
01480     if (stateIsOn(s_appBusy|s_dbgNotStarted|s_shuttingDown))
01481         return;
01482 
01483     if (stateIsOn(s_appNotStarted)) {
01484 
01485         if (!config_runShellScript_.isEmpty()) {
01486             // Special for remote debug...
01487             QCString tty(tty_->getSlave().latin1());
01488             QCString options = QCString(" 2>&1 >") + tty + QCString(" <") + tty;
01489 
01490             KProcess *proc = new KProcess;
01491 
01492             *proc << "sh" << "-c";
01493             *proc << config_runShellScript_ +
01494                 " " + application_.latin1() + options;
01495             proc->start(KProcess::DontCare);
01496         }
01497 
01498         if (!config_runGdbScript_.isEmpty()) {// gdb script at run is requested
01499 
01500             // Race notice: wait for the remote gdbserver/executable
01501             // - but that might be an issue for this script to handle...
01502 
01503             // Future: the shell script should be able to pass info (like pid)
01504             // to the gdb script...
01505 
01506             queueCmd(new GDBCommand("source " + config_runGdbScript_,
01507                                     RUNCMD, NOTINFOCMD, 0));
01508 
01509             // Note: script could contain "run" or "continue"
01510         }
01511         else {
01512             queueCmd(new GDBCommand("run", RUNCMD, NOTINFOCMD, 0));
01513         }
01514     }
01515     else {
01516         queueCmd(new GDBCommand("continue", RUNCMD, NOTINFOCMD, 0));
01517     }
01518 }
01519 
01520 // **************************************************************************
01521 
01522 void GDBController::slotRunUntil(const QString &fileName, int lineNum)
01523 {
01524     if (stateIsOn(s_appBusy|s_dbgNotStarted|s_shuttingDown))
01525         return;
01526 
01527     if (fileName.isEmpty())
01528         queueCmd(new GDBCommand( QCString().sprintf("until %d", lineNum),
01529                                 RUNCMD, NOTINFOCMD, 0));
01530     else
01531         queueCmd(new GDBCommand(
01532                 QCString().sprintf("until %s:%d", fileName.latin1(), lineNum),
01533                                 RUNCMD, NOTINFOCMD, 0));
01534 }
01535 
01536 // **************************************************************************
01537 
01538 void GDBController::slotStepInto()
01539 {
01540     if (stateIsOn(s_appBusy|s_appNotStarted|s_shuttingDown))
01541         return;
01542 
01543     queueCmd(new GDBCommand("step", RUNCMD, NOTINFOCMD, 0));
01544 }
01545 
01546 // **************************************************************************
01547 
01548 void GDBController::slotStepIntoIns()
01549 {
01550     if (stateIsOn(s_appBusy|s_appNotStarted|s_shuttingDown))
01551         return;
01552 
01553     queueCmd(new GDBCommand("stepi", RUNCMD, NOTINFOCMD, 0));
01554 }
01555 
01556 // **************************************************************************
01557 
01558 void GDBController::slotStepOver()
01559 {
01560     if (stateIsOn(s_appBusy|s_appNotStarted|s_shuttingDown))
01561         return;
01562 
01563     queueCmd(new GDBCommand("next", RUNCMD, NOTINFOCMD, 0));
01564 }
01565 
01566 // **************************************************************************
01567 
01568 void GDBController::slotStepOverIns()
01569 {
01570     if (stateIsOn(s_appBusy|s_appNotStarted|s_shuttingDown))
01571         return;
01572 
01573     queueCmd(new GDBCommand("nexti", RUNCMD, NOTINFOCMD, 0));
01574 }
01575 
01576 // **************************************************************************
01577 
01578 void GDBController::slotStepOutOff()
01579 {
01580     if (stateIsOn(s_appBusy|s_appNotStarted|s_shuttingDown))
01581         return;
01582 
01583     queueCmd(new GDBCommand("finish", RUNCMD, NOTINFOCMD, 0));
01584 }
01585 
01586 // **************************************************************************
01587 
01588 // Only interrupt a running program.
01589 void GDBController::slotBreakInto()
01590 {
01591     pauseApp();
01592 }
01593 
01594 // **************************************************************************
01595 
01596 // See what, if anything needs doing to this breakpoint.
01597 void GDBController::slotBPState( const Breakpoint& BP )
01598 {
01599     // Are we in a position to do anything to this breakpoint?
01600     if (stateIsOn(s_dbgNotStarted|s_shuttingDown) || !BP.isPending() ||
01601             BP.isActionDie())
01602         return;
01603 
01604     // We need this flag so that we can continue execution. I did use
01605     // the s_silent state flag but it can be set prior to this method being
01606     // called, hence is invalid.
01607     bool restart = false;
01608     if (stateIsOn(s_appBusy))
01609     {
01610         if (!config_forceBPSet_)
01611             return;
01612 
01613         // When forcing breakpoints to be set/unset, interrupt a running app
01614         // and change the state.
01615         setStateOn(s_silent);
01616         pauseApp();
01617         restart = true;
01618     }
01619 
01620     if (BP.isActionAdd())
01621     {
01622         setBreakpoint(BP.dbgSetCommand().latin1(), BP.key());
01623         //        BP.setDbgProcessing(true);
01624     }
01625     else
01626     {
01627         if (BP.isActionClear())
01628         {
01629             clearBreakpoint(BP.dbgRemoveCommand().latin1());
01630             //            BP.setDbgProcessing(true);
01631         }
01632         else
01633         {
01634             if (BP.isActionModify())
01635             {
01636                 modifyBreakpoint(BP); // Note: DbgProcessing gets set in modify fn
01637             }
01638         }
01639     }
01640 
01641     if (restart)
01642         queueCmd(new GDBCommand("continue", RUNCMD, NOTINFOCMD, 0));
01643 }
01644 
01645 // **************************************************************************
01646 
01647 void GDBController::slotClearAllBreakpoints()
01648 {
01649     // Are we in a position to do anything to this breakpoint?
01650     if (stateIsOn(s_dbgNotStarted|s_shuttingDown))
01651         return;
01652 
01653     bool restart = false;
01654     if (stateIsOn(s_appBusy))
01655     {
01656         if (!config_forceBPSet_)
01657             return;
01658 
01659         // When forcing breakpoints to be set/unset, interrupt a running app
01660         // and change the state.
01661         setStateOn(s_silent);
01662         pauseApp();
01663         restart = true;
01664     }
01665 
01666     queueCmd(new GDBCommand("delete", NOTRUNCMD, NOTINFOCMD));
01667     // Note: this is NOT an info command, because gdb doesn't explictly tell
01668     // us that the breakpoint has been deleted, so if we don't have it the
01669     // BP list doesn't get updated.
01670     queueCmd(new GDBCommand("info breakpoints", NOTRUNCMD, NOTINFOCMD, BPLIST));
01671 
01672     if (restart)
01673         queueCmd(new GDBCommand("continue", RUNCMD, NOTINFOCMD, 0));
01674 }
01675 
01676 // **************************************************************************
01677 
01678 void GDBController::slotDisassemble(const QString &start, const QString &end)
01679 {
01680     if (stateIsOn(s_appBusy|s_dbgNotStarted|s_shuttingDown))
01681         return;
01682 
01683     QCString cmd = QCString().sprintf("disassemble %s %s", start.latin1(), end.latin1());
01684     queueCmd(new GDBCommand(cmd, NOTRUNCMD, INFOCMD, DISASSEMBLE));
01685 }
01686 
01687 // **************************************************************************
01688 
01689 void GDBController::slotMemoryDump(const QString &address, const QString &amount)
01690 {
01691     if (stateIsOn(s_appBusy|s_dbgNotStarted|s_shuttingDown))
01692         return;
01693 
01694     QCString cmd = QCString().sprintf("x/%sb %s", amount.latin1(),
01695                                                   address.latin1());
01696     queueCmd(new GDBCommand(cmd, NOTRUNCMD, INFOCMD, MEMDUMP));
01697 }
01698 
01699 // **************************************************************************
01700 
01701 void GDBController::slotRegisters()
01702 {
01703     if (stateIsOn(s_appBusy|s_dbgNotStarted|s_shuttingDown))
01704         return;
01705 
01706     queueCmd(new GDBCommand("info all-registers", NOTRUNCMD, INFOCMD, REGISTERS));
01707 }
01708 
01709 // **************************************************************************
01710 
01711 void GDBController::slotLibraries()
01712 {
01713     if (stateIsOn(s_appBusy|s_dbgNotStarted|s_shuttingDown))
01714         return;
01715 
01716     queueCmd(new GDBCommand("info sharedlibrary", NOTRUNCMD, INFOCMD, LIBRARIES));
01717 }
01718 
01719 // **************************************************************************
01720 
01721 void GDBController::slotSelectFrame(int frameNo, int threadNo, bool needFrames)
01722 {
01723     if (stateIsOn(s_appBusy|s_dbgNotStarted|s_shuttingDown))
01724         return;
01725 
01726     // Get gdb to switch the frame stack on a frame change.
01727     // This is an info command because _any_ run command will set the system
01728     // back to frame 0 regardless, so being removed with a run command is the
01729     //  best thing that could happen here.
01730     // _Always_ switch frames (even if we're the same frame so that a program
01731     // position will be generated by gdb
01732     if (threadNo != -1)
01733     {
01734         // We don't switch threads if we on this thread. The -1 check is
01735         // because the first time after a stop we're actually on this thread
01736         // but the thread number had been reset to -1.
01737         if (viewedThread_ != -1)
01738         {
01739             if (viewedThread_ != threadNo)
01740                 queueCmd(new GDBCommand(QCString().sprintf("thread %d",
01741                                 threadNo), NOTRUNCMD, INFOCMD, SWITCHTHREAD));
01742         }
01743     }
01744 
01745     queueCmd(new GDBCommand(QCString().sprintf("frame %d",
01746                                 frameNo), NOTRUNCMD, INFOCMD, FRAME));
01747 
01748     if (needFrames)
01749         queueCmd(new GDBCommand("backtrace", NOTRUNCMD, INFOCMD,
01750                                         BACKTRACE));
01751 
01752     // Hold on to  this thread/frame so that we know where to put the local
01753     // variables if generated.
01754     viewedThread_ = threadNo;
01755     currentFrame_ = frameNo;
01756 
01757     // Find or add the frame details. hold onto whether it existed because
01758     // we're about to create one if it didn't.
01759     VarFrameRoot *frame = varTree_->findFrame(frameNo, viewedThread_);
01760     if (!frame)
01761     {
01762         frame = new VarFrameRoot(varTree_, currentFrame_, viewedThread_);
01763         frame->setFrameName(
01764                 frameStack_->getFrameName(currentFrame_, viewedThread_));
01765     }
01766 
01767     Q_ASSERT(frame);
01768     if (stateIsOn(s_viewLocals))
01769     {
01770         // Have we already got these details?
01771         if (frame->needLocals())
01772         {
01773             // Add the frame params to the variable list
01774             // and ask for the locals
01775             queueCmd(new GDBCommand("info args", NOTRUNCMD, INFOCMD, ARGS));
01776             queueCmd(new GDBCommand("info local", NOTRUNCMD, INFOCMD, LOCALS));
01777         }
01778     }
01779 }
01780 
01781 // **************************************************************************
01782 
01783 void GDBController::slotVarItemConstructed(VarItem *item)
01784 {
01785     if (stateIsOn(s_appBusy|s_dbgNotStarted|s_shuttingDown))
01786         return;
01787 
01788     // jw - name and value come from "info local", for the type we
01789     // send a "whatis <varName>" here.
01790     //rgr: remove any format modifier
01791     QString strName = item->fullName();
01792     strName.remove( QRegExp("/[xd] ", FALSE) );
01793     queueCmd(new GDBItemCommand(item, QCString("whatis ") + strName.latin1(),
01794                                 false, WHATIS));
01795 }
01796 
01797 // **************************************************************************
01798 
01799 // This is called when the user desires to see the details of an item, by
01800 // clicking open an varItem on the varTree.
01801 void GDBController::slotExpandItem(TrimmableItem *genericItem)
01802 {
01803     if (stateIsOn(s_appBusy|s_dbgNotStarted|s_shuttingDown))
01804         return;
01805 
01806     VarItem *varItem;
01807     if ((varItem = dynamic_cast<VarItem*>(genericItem)))
01808     {
01809         switch (varItem->getDataType())
01810         {
01811         case typePointer:
01812             queueCmd(new GDBPointerCommand(varItem));
01813             break;
01814 
01815         default:
01816              //rgr: we need to do this in order to move the output modifier
01817              //     from the middle to the beginning
01818              QString strCmd = varItem->fullName();
01819              int iFound = strCmd.find( QRegExp("./[xd] ", FALSE) );
01820              if (iFound != -1) {
01821                strCmd.prepend( strCmd.mid(iFound+1, 3) );
01822                strCmd.replace( QRegExp("./[xd] "), "." );
01823              }
01824              queueCmd(new GDBItemCommand(varItem, QCString("print ") + strCmd.latin1()));            break;
01825         }
01826         return;
01827     }
01828 
01829 /*
01830     VarFrameRoot *frameRoot;
01831     if ((frameRoot = dynamic_cast<VarFrameRoot*>(genericItem)))
01832     {
01833         kdDebug(9012) << " ### GDBController::slotExpandItem: varframeroot expanded." << endl;
01834         if (frameRoot->requestedValueTypes())
01835         {
01836             kdDebug(9012) << " ### GDBController::slotExpandItem: requestedValueTypes == true" << endl;
01837             // this was already done.
01838             return;
01839         }
01840         // iterate over children (i.e. the variables)
01841         QListViewItem *item = frameRoot->firstChild();
01842 
01843         kdDebug(9012) << " ### GDBController::slotExpandItem: firstChild = " << (void*)item;
01844 
01845         while (item)
01846         {
01847             varItem = dynamic_cast<VarItem*>(item);
01848             if (varItem)
01849             {
01850                 // for each variable, send a "whatis" command to gdb
01851                 queueCmd(new GDBItemCommand(varItem, QCString("whatis ") + varItem->fullName().latin1()));
01852             }
01853             item = item->nextSibling();
01854         }
01855     }
01856 */
01857 }
01858 
01859 // **************************************************************************
01860 
01861 // This is called when an item needs special processing to show a value.
01862 // Example = QStrings. We want to display the QString string against the var name
01863 // so the user doesn't have to open the qstring to find it. Here's where that happens
01864 void GDBController::slotExpandUserItem(VarItem *item, const QCString &userRequest)
01865 {
01866     if (stateIsOn(s_appBusy|s_dbgNotStarted|s_shuttingDown))
01867         return;
01868 
01869     Q_ASSERT(item);
01870 
01871     // Bad user data!!
01872     if (userRequest.isEmpty())
01873         return;
01874 
01875     queueCmd(new GDBItemCommand(item, QCString("print ")+userRequest.data(),
01876                                         false, DATAREQUEST));
01877 }
01878 
01879 // **************************************************************************
01880 
01881 // The user will only get locals if one of the branches to the local tree
01882 // is open. This speeds up stepping through code a great deal.
01883 void GDBController::slotSetLocalViewState(bool onOff)
01884 {
01885     if (onOff)
01886         setStateOn(s_viewLocals);
01887     else
01888         setStateOff(s_viewLocals);
01889 
01890     kdDebug(9012) << (onOff ? "<Locals ON>": "<Locals OFF>") << endl;
01891 }
01892 
01893 // **************************************************************************
01894 
01895 // Data from gdb gets processed here.
01896 void GDBController::slotDbgStdout(KProcess *, char *buf, int buflen)
01897 {
01898     static bool parsing = false;
01899 
01900     QCString msg(buf, buflen+1);
01901 //    kdDebug(9012) << "msg=<" << msg << ">" << endl;
01902     msg.replace( QRegExp("\032."), "" );
01903     emit gdbStdout(msg);
01904 
01905     // Copy the data out of the KProcess buffer before it gets overwritten
01906     // Append to the back of the holding zone.
01907     holdingZone_ +=  QCString(buf, buflen+1);
01908 
01909     // Already parsing? then get out quick.
01910     if (parsing)
01911     {
01912         kdDebug(9012) << "Already parsing" << endl;
01913         return;
01914     }
01915 
01916     while (true)
01917     {
01918         // Allocate some buffer space, if adding to this buffer will exceed it
01919         if (gdbOutputLen_+(int)holdingZone_.length()+1 > gdbSizeofBuf_)
01920         {
01921             gdbSizeofBuf_ = gdbOutputLen_+2*(holdingZone_.length()+1);
01922             char *newBuf = new char[gdbSizeofBuf_];
01923             if (gdbOutputLen_)
01924                 memcpy(newBuf, gdbOutput_, gdbOutputLen_+1);
01925             delete[] gdbOutput_;
01926             gdbOutput_ = newBuf;
01927         }
01928 
01929         // Copy the data from the holding zone into the buffer the parsers will
01930         // process from, and make it into a c-string so we can use the string fns
01931 //        kdDebug(9012)   << "Adding holdingZone_ (" << holdingZone_.length()   << ")" << endl
01932 //                        << holdingZone_ << endl;
01933 
01934         qstrcpy(gdbOutput_+gdbOutputLen_, holdingZone_);
01935         gdbOutputLen_ += holdingZone_.length();
01936         *(gdbOutput_+gdbOutputLen_) = 0;
01937         holdingZone_ = "";
01938 
01939 //        kdDebug(9012)   << "Output to parse (" << gdbOutputLen_   << ")" << endl
01940 //                        << gdbOutput_ << endl << "*************" << endl;
01941 
01942         parsing = true;
01943         char *nowAt = parse(gdbOutput_);
01944         parsing = false;
01945 
01946         if (nowAt)
01947         {
01948 //            kdDebug(9012)   << "*** " << nowAt-gdbOutput_ << " bytes have been parsed " << endl;
01949             Q_ASSERT(nowAt <= gdbOutput_+gdbOutputLen_+1);
01950             gdbOutputLen_ = strlen(nowAt);
01951 
01952             // Bytes that wern't parsed need to be moved to the head of the buffer
01953             if (gdbOutputLen_)
01954                 memmove(gdbOutput_, nowAt, gdbOutputLen_);     // Overlapping data
01955             else
01956                 *gdbOutput_ = 0;
01957         }
01958 
01959 //        kdDebug(9012)   << "Output remaining (" << gdbOutputLen_  << ")" << endl
01960 //                        << gdbOutput_ << endl << "*************" << endl;
01961 
01962         if (!nowAt && !holdingZone_.length())
01963             break;
01964     }
01965 
01966     // check the queue for any commands to send
01967     executeCmd();
01968 }
01969 
01970 // **************************************************************************
01971 
01972 void GDBController::slotDbgStderr(KProcess *proc, char *buf, int buflen)
01973 {
01974     // At the moment, just drop a message out and redirect
01975     kdDebug(9012) << "STDERR: " << QString::fromLatin1(buf, buflen+1) << endl;
01976     slotDbgStdout(proc, buf, buflen);
01977 
01978     //  QString bufData(buf, buflen+1);
01979     //  char *found;
01980     //  if ((found = strstr(buf, "No symbol table is loaded")))
01981     //    emit dbgStatus (QString("No symbol table is loaded"), state_);
01982 
01983     // If you end the app and then restart when you have breakpoints set
01984     // in a dynamically loaded library, gdb will halt because the set
01985     // breakpoint is trying to access memory no longer used. The breakpoint
01986     // must first be deleted, however, we want to retain the breakpoint for
01987     // when the library gets loaded again.
01990     //  if (programHasExited_ && (found = strstr(bufData.data(), "Cannot insert breakpoint")))
01991     //  {
01992     //    setStateOff(s_appBusy);
01993     //    int BPNo = atoi(found+25);
01994     //    if (BPNo)
01995 
01996     //    {
01997     //      queueCmd(new GDBCommand(QString().sprintf("delete %d", BPNo), NOTRUNCMD, NOTINFOCMD));
01998     //      queueCmd(new GDBCommand("info breakpoints", NOTRUNCMD, NOTINFOCMD, BPLIST));
01999     //      queueCmd(new GDBCommand("continue", RUNCMD, NOTINFOCMD, 0));
02000     //      emit unableToSetBPNow(BPNo);
02001     //    }
02002     //    return;
02003     //  }
02004     //
02005     //  parse(bufData.data());
02006 }
02007 
02008 // **************************************************************************
02009 
02010 void GDBController::slotDbgWroteStdin(KProcess *)
02011 {
02012     setStateOff(s_waitForWrite);
02013     //  if (!stateIsOn(s_silent))
02014     //    emit dbgStatus ("", state_);
02015     executeCmd();
02016 }
02017 
02018 // **************************************************************************
02019 
02020 void GDBController::slotDbgProcessExited(KProcess*)
02021 {
02022     destroyCmds();
02023     state_ = s_appNotStarted|s_programExited|(state_&(s_viewLocals|s_shuttingDown));
02024     emit dbgStatus (i18n("Process exited"), state_);
02025 
02026     emit gdbStdout("(gdb) Process exited\n");
02027 }
02028 
02029 // **************************************************************************
02030 
02031 void GDBController::slotUserGDBCmd(const QString& cmd)
02032 {
02033     kdDebug(9012) << "Requested user cmd: " << cmd << endl;
02034     if (cmd.startsWith("step") || cmd.startsWith("c"))
02035     {
02036         queueCmd(new GDBCommand(cmd.latin1(), RUNCMD, NOTINFOCMD, 0));
02037         return;
02038     }
02039 
02040     if (cmd.startsWith("info lo"))
02041     {
02042         queueCmd(new GDBCommand("info local", NOTRUNCMD, INFOCMD, LOCALS));
02043         return;
02044     }
02045 
02046     if (cmd.startsWith("info ar"))
02047     {
02048         queueCmd(new GDBCommand("info args", NOTRUNCMD, INFOCMD, ARGS));
02049         return;
02050     }
02051 
02052     if (cmd.startsWith("info th"))
02053     {
02054         queueCmd(new GDBCommand("info thread", NOTRUNCMD, INFOCMD, INFOTHREAD), true);
02055         return;
02056     }
02057 
02058     if (cmd.startsWith("ba") || cmd.startsWith("bt"))
02059     {
02060         queueCmd(new GDBCommand("backtrace", NOTRUNCMD, INFOCMD, BACKTRACE), true);
02061         return;
02062     }
02063 
02064     QRegExp frame("^fr[ame]*\\s+(\\d+)");
02065     if ( frame.search(cmd) >= 0 )
02066     {
02067         slotSelectFrame(frame.cap(1).toInt(), viewedThread_, true);
02068         return;
02069     }
02070 
02071     QRegExp thread("^th[read]*\\s+(\\d+)");
02072     if ( thread.search(cmd) >= 0 )
02073     {
02074         int threadNo = thread.cap(1).toInt();
02075         int frameNo = currentFrame_;
02076         if (threadNo != viewedThread_)
02077             frameNo = 0;
02078 
02079         slotSelectFrame(frameNo, threadNo, true);
02080         return;
02081     }
02082 
02083     if (cmd.startsWith("qu"))
02084     {
02085         slotStopDebugger();
02086         return;
02087     }
02088 
02089     kdDebug(9012) << "Parsing directly to gdb: " << cmd << endl;
02090     queueCmd(new GDBCommand(cmd.latin1(), NOTRUNCMD, INFOCMD, USERCMD));
02091 }
02092 
02093 }
02094 
02095 // **************************************************************************
02096 // **************************************************************************
02097 // **************************************************************************
02098 #include "gdbcontroller.moc"
KDE Logo
This file is part of the documentation for KDevelop Version 3.1.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Feb 22 09:22:29 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003