KDevelop API Documentation

javadebuggerpart.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 1999-2001 by John Birch                                 *
00003  *   jbb@kdevelop.org                                                      *
00004  *   Copyright (C) 2001 by Bernd Gehrmann                                  *
00005  *   bernd@kdevelop.org                                                    *
00006  *                                                                         *
00007  *   This program is free software; you can redistribute it and/or modify  *
00008  *   it under the terms of the GNU General Public License as published by  *
00009  *   the Free Software Foundation; either version 2 of the License, or     *
00010  *   (at your option) any later version.                                   *
00011  *                                                                         *
00012  ***************************************************************************/
00013 
00014 #include "javadebuggerpart.h"
00015 
00016 #include <qdir.h>
00017 #include <qwhatsthis.h>
00018 #include <kfiledialog.h>
00019 #include <kdebug.h>
00020 #include <kiconloader.h>
00021 #include <klocale.h>
00022 #include <kaction.h>
00023 #include <kstatusbar.h>
00024 
00025 #include "kdevcore.h"
00026 #include "kdevproject.h"
00027 #include "kdevmainwindow.h"
00028 #include "kdevpartcontroller.h"
00029 #include "kdevdebugger.h"
00030 
00031 #include "variablewidget.h"
00032 #include "breakpointwidget.h"
00033 #include "framestackwidget.h"
00034 #include "disassemblewidget.h"
00035 #include "jdbcontroller.h"
00036 #include "breakpoint.h"
00037 #include "dbgpsdlg.h"
00038 #include "memviewdlg.h"
00039 
00040 
00041 namespace JAVADebugger
00042 {
00043 static const KAboutData data("kdevjavadebugger", I18N_NOOP("Debugger"), "1.0");
00044 K_EXPORT_COMPONENT_FACTORY( libkdevjavadebugger, JavaDebuggerFactory( &data ) )
00045 
00046 JavaDebuggerPart::JavaDebuggerPart(QObject *parent, const char *name, const QStringList &)
00047     : KDevPlugin("JavaDebugger", "debugger", parent, name ? name : "JavaDebuggerPart"),
00048       controller(0)
00049 {
00050     setInstance(JavaDebuggerFactory::instance());
00051 
00052     setXMLFile("kdevjavadebugger.rc");
00053 
00054     //
00055     // Setup widgets and dbgcontroller
00056     //
00057 
00058     variableWidget = new VariableWidget();
00059     variableWidget->setEnabled(false);
00060     variableWidget->setIcon(SmallIcon("math_brace"));
00061     variableWidget->setCaption(i18n("Variable Tree"));
00062     QWhatsThis::add(variableWidget, i18n("Variable tree\n\n"
00063                                          "The variable tree allows you to see "
00064                                          "the variable values as you step "
00065                                          "through your program using the internal "
00066                                          "debugger. Click the right mouse button on items in "
00067                                          "this view to get a popup menu.\n"
00068                                          "To speed up stepping through your code "
00069                                          "leave the tree items closed and add the "
00070                                          "variable(s) to the watch section.\n"
00071                                          "To change a variable value in your "
00072                                          "running app use a watch variable (&eg; a=5)."));
00073     mainWindow()->embedSelectView(variableWidget, i18n("Watch"), i18n("debugger variable-view"));
00074     mainWindow()->setViewAvailable(variableWidget, false);
00075 
00076     breakpointWidget = new BreakpointWidget();
00077     breakpointWidget->setCaption(i18n("Breakpoint List"));
00078     QWhatsThis::add(breakpointWidget, i18n("Breakpoint list\n\n"
00079                                            "Displays a list of breakpoints with "
00080                                            "their current status. Clicking on a "
00081                                            "breakpoint item with the right mouse button displays "
00082                                            "a popup menu so you may manipulate the "
00083                                            "breakpoint. Double clicking will take you "
00084                                            "to the source in the editor window."));
00085     mainWindow()->embedOutputView(breakpointWidget, i18n("&Breakpoints"), i18n("debugger breakpoints"));
00086 
00087     framestackWidget = new FramestackWidget();
00088     framestackWidget->setEnabled(false);
00089     framestackWidget->setCaption(i18n("Frame Stack"));
00090     QWhatsThis::add(framestackWidget, i18n("Frame stack\n\n"
00091                                            "Often referred to as the \"call stack\", "
00092                                            "this is a list showing what function is "
00093                                            "currently active and who called each "
00094                                            "function to get to this point in your "
00095                                            "program. By clicking on an item you "
00096                                            "can see the values in any of the "
00097                                            "previous calling functions."));
00098     mainWindow()->embedOutputView(framestackWidget, i18n("&Frame Stack"), i18n("debugger function call stack"));
00099     mainWindow()->setViewAvailable(framestackWidget, false);
00100 
00101     disassembleWidget = new DisassembleWidget();
00102     disassembleWidget->setEnabled(false);
00103     disassembleWidget->setCaption(i18n("Machine Code Display"));
00104     QWhatsThis::add(disassembleWidget, i18n("Machine code display\n\n"
00105                                             "A machine code view into your running "
00106                                             "executable with the current instruction "
00107                                             "highlighted. You can step instruction by "
00108                                             "instruction using the debuggers toolbar "
00109                                             "buttons of \"step over\" instruction and "
00110                                             "\"step into\" instruction."));
00111     mainWindow()->embedOutputView(disassembleWidget, i18n("Disassemble"), i18n("debugger disassemble"));
00112     mainWindow()->setViewAvailable(disassembleWidget, false);
00113 
00114     VariableTree *variableTree = variableWidget->varTree();
00115 
00116     // variableTree -> framestackWidget
00117     connect( variableTree,     SIGNAL(selectFrame(int)),
00118              framestackWidget, SLOT(slotSelectFrame(int)));
00119 
00120     // breakpointWidget -> this
00121     connect( breakpointWidget, SIGNAL(refreshBPState(Breakpoint*)),
00122              this,             SLOT(slotRefreshBPState(Breakpoint*)));
00123     connect( breakpointWidget, SIGNAL(publishBPState(Breakpoint*)),
00124              this,             SLOT(slotRefreshBPState(Breakpoint*)));
00125     connect( breakpointWidget, SIGNAL(gotoSourcePosition(const QString&, int)),
00126              this,             SLOT(slotGotoSource(const QString&, int)) );
00127 
00128     //
00129     // Now setup the actions
00130     //
00131 
00132     KAction *action;
00133 
00134     action = new KAction(i18n("&Start"), "1rightarrow", 0,
00135                          this, SLOT(slotRun()),
00136                          actionCollection(), "debug_run");
00137     action->setStatusText( i18n("Runs the program in the debugger") );
00138     action->setWhatsThis( i18n("Start in debugger\n\n"
00139                                "Starts the debugger with the project's main "
00140                                "executable. You may set some breakpoints "
00141                                "before this, or you can interrupt the program "
00142                                "while it is running, in order to get information "
00143                                "about variables, frame stack, and so on.") );
00144 
00145     action = new KAction(i18n("Sto&p"), "stop", 0,
00146                          this, SLOT(slotStop()),
00147                          actionCollection(), "debug_stop");
00148     action->setEnabled(false);
00149     action->setStatusText( i18n("Kills the executable and exits the debugger") );
00150 
00151     action = new KAction(i18n("Interrupt"), "player_pause", 0,
00152                          this, SLOT(slotPause()),
00153                          actionCollection(), "debug_pause");
00154     action->setEnabled(false);
00155     action->setStatusText( i18n("Interrupts the application") );
00156 
00157     action = new KAction(i18n("&Continue"), "dbgrun", 0,
00158                          this, SLOT(slotContinue()),
00159                          actionCollection(), "debug_cont");
00160     action->setEnabled(false);
00161     action->setStatusText( i18n("Continues the application execution") );
00162     action->setWhatsThis( i18n("Continue application execution\n\n"
00163                                "Continues the execution of your application in the "
00164                                "debugger. This only takes effect when the application "
00165                                "has been halted by the debugger (i.e. a breakpoint has "
00166                                "been activated or the interrupt was pressed).") );
00167 
00168     action = new KAction(i18n("Step &Over"), "dbgnext", 0,
00169                          this, SLOT(slotStepOver()),
00170                          actionCollection(), "debug_stepover");
00171     action->setEnabled(false);
00172     action->setStatusText( i18n("Steps over the next line") );
00173     action->setWhatsThis( i18n("Step over\n\n"
00174                                "Executes one line of source in the current source file. "
00175                                "If the source line is a call to a function the whole "
00176                                "function is executed and the app will stop at the line "
00177                                "following the function call.") );
00178 
00179     action = new KAction(i18n("Step &Into"), "dbgstep", 0,
00180                          this, SLOT(slotStepInto()),
00181                          actionCollection(), "debug_stepinto");
00182     action->setEnabled(false);
00183     action->setStatusText( i18n("Steps into the next statement") );
00184     action->setWhatsThis( i18n("Step into\n\n"
00185                                "Executes exactly one line of source. If the source line "
00186                                "is a call to a function then execution will stop after "
00187                                "the function has been entered.") );
00188 
00189     action = new KAction(i18n("Step into I&nstruction"), "dbgstepinst", 0,
00190                          this, SLOT(slotStepIntoInstruction()),
00191                          actionCollection(), "debug_stepintoinst");
00192     action->setEnabled(false);
00193     action->setStatusText( i18n("Steps into the next assembly instruction") );
00194 
00195     action = new KAction(i18n("Step O&ut"), "dbgstepout", 0,
00196                          this, SLOT(slotStepOut()),
00197                          actionCollection(), "debug_stepout");
00198     action->setEnabled(false);
00199     action->setStatusText( i18n("Steps out of the current function") );
00200     action->setWhatsThis( i18n("Step out of\n\n"
00201                                "Executes the application until the currently executing "
00202                                "function is completed. The debugger will then display "
00203                                "the line after the original call to that function. If "
00204                                "we are in the outermost frame (i.e. in main()), then "
00205                                "this operation has no effect.") );
00206 
00207     action = new KAction(i18n("Viewers"), "dbgmemview", 0,
00208                          this, SLOT(slotMemoryView()),
00209                          actionCollection(), "debug_memview");
00210     action->setEnabled(false);
00211     action->setStatusText( i18n("Various views into the application") );
00212 
00213     connect( core(), SIGNAL(toggledBreakpoint(const QString &, int)),
00214              breakpointWidget, SLOT(slotToggleBreakpoint(const QString &, int)) );
00215     connect( core(), SIGNAL(editedBreakpoint(const QString &, int)),
00216              breakpointWidget, SLOT(slotEditBreakpoint(const QString &, int)) );
00217     connect( core(), SIGNAL(toggledBreakpointEnabled(const QString &, int)),
00218              breakpointWidget, SLOT(slotToggleBreakpointEnabled(const QString &, int)) );
00219 }
00220 
00221 
00222 JavaDebuggerPart::~JavaDebuggerPart()
00223 {
00224     mainWindow()->removeView(variableWidget);
00225     mainWindow()->removeView(breakpointWidget);
00226     mainWindow()->removeView(framestackWidget);
00227     mainWindow()->removeView(disassembleWidget);
00228 
00229     delete variableWidget;
00230     delete breakpointWidget;
00231     delete framestackWidget;
00232     delete disassembleWidget;
00233     delete controller;
00234     //    delete floatingToolBar;
00235 }
00236 
00237 
00238 void JavaDebuggerPart::setupController()
00239 {
00240     VariableTree *variableTree = variableWidget->varTree();
00241 
00242     if (project()) {
00243         controller = new JDBController(variableTree, framestackWidget, project()->projectDirectory(), project()->mainProgram());
00244     } else {
00245         controller = new JDBController(variableTree, framestackWidget, "", "");
00246     }
00247 
00248     // variableTree -> controller
00249     connect( variableTree,     SIGNAL(expandItem(VarItem*)),
00250              controller,       SLOT(slotExpandItem(VarItem*)));
00251     connect( variableTree,     SIGNAL(expandUserItem(VarItem*, const QCString&)),
00252              controller,       SLOT(slotExpandUserItem(VarItem*, const QCString&)));
00253     connect( variableTree,     SIGNAL(setLocalViewState(bool)),
00254              controller,       SLOT(slotSetLocalViewState(bool)));
00255 
00256     // framestackWidget -> controller
00257     connect( framestackWidget, SIGNAL(selectFrame(int)),
00258              controller,       SLOT(slotSelectFrame(int)));
00259 
00260     // breakpointWidget -> controller
00261     connect( breakpointWidget, SIGNAL(clearAllBreakpoints()),
00262              controller,       SLOT(slotClearAllBreakpoints()));
00263 
00264     // disassembleWidget -> controller
00265     connect( disassembleWidget,SIGNAL(disassemble(const QString&, const QString&)),
00266              controller,       SLOT(slotDisassemble(const QString&, const QString&)));
00267 
00268     // controller -> breakpointWidget
00269     connect( controller,       SIGNAL(acceptPendingBPs()),
00270              breakpointWidget, SLOT(slotSetPendingBPs()));
00271     connect( controller,       SIGNAL(unableToSetBPNow(int)),
00272              breakpointWidget, SLOT(slotUnableToSetBPNow(int)));
00273     connect( controller,       SIGNAL(rawJDBBreakpointList (char*)),
00274              breakpointWidget, SLOT(slotParseJDBBrkptList(char*)));
00275     connect( controller,       SIGNAL(rawJDBBreakpointSet(char*, int)),
00276              breakpointWidget, SLOT(slotParseJDBBreakpointSet(char*, int)));
00277     connect( breakpointWidget, SIGNAL(publishBPState(Breakpoint*)),
00278              controller,       SLOT(slotBPState(Breakpoint*)));
00279 
00280     // controller -> disassembleWidget
00281     connect( controller,       SIGNAL(showStepInSource(const QString&, int, const QString&)),
00282              disassembleWidget,SLOT(slotShowStepInSource(const QString&, int, const QString&)));
00283     connect( controller,       SIGNAL(rawJDBDisassemble(char*)),
00284              disassembleWidget,SLOT(slotDisassemble(char*)));
00285 
00286     // controller -> this
00287     connect( controller,       SIGNAL(dbgStatus(const QString&, int)),
00288              this,             SLOT(slotStatus(const QString&, int)));
00289     connect( controller,       SIGNAL(showStepInSource(const QString&, int, const QString&)),
00290              this,             SLOT(slotShowStep(const QString&, int)));
00291 
00292     // Hmm, the application's output can be separated from the debugger's?
00293     // Didn't know that...
00294 #if 0
00295     connect( controller,       SIGNAL(ttyStdout(const char*)),
00296              this,             SLOT(slotApplReceivedStdout(const char*)));
00297     connect( controller,       SIGNAL(ttyStderr(const char*)),
00298              this,             SLOT(slotApplReceivedStderr(const char*)));
00299 #endif
00300 }
00301 
00302 
00303 void JavaDebuggerPart::startDebugger()
00304 {
00305     core()->running(this, true);
00306 
00307     KActionCollection *ac = actionCollection();
00308     ac->action("debug_stop")->setEnabled(true);
00309     ac->action("debug_pause")->setEnabled(true);
00310     ac->action("debug_cont")->setEnabled(true);
00311     ac->action("debug_stepover")->setEnabled(true);
00312     ac->action("debug_stepinto")->setEnabled(true);
00313     ac->action("debug_stepintoinst")->setEnabled(true);
00314     ac->action("debug_stepout")->setEnabled(true);
00315     ac->action("debug_memview")->setEnabled(true);
00316 
00317     variableWidget->setEnabled(true);
00318     framestackWidget->setEnabled(true);
00319     disassembleWidget->setEnabled(true);
00320 
00321     mainWindow()->setViewAvailable(variableWidget, true);
00322     mainWindow()->setViewAvailable(framestackWidget, true);
00323     mainWindow()->setViewAvailable(disassembleWidget, true);
00324 
00325     // Floatinging tool bar can wait until later :-)
00326     //    if (enableFloatingToolBar) {
00327     //        floatingToolBar = new DbgToolBar(controller, this);
00328     //        floatingToolBar->show();
00329     //    }
00330 
00331     setupController();
00332     controller->slotStart("", "", "");
00333     breakpointWidget->slotSetPendingBPs();
00334 }
00335 
00336 
00337 void JavaDebuggerPart::slotRun()
00338 {
00339     if (controller)
00340         slotStop();
00341 
00342     mainWindow()->statusBar()->message(i18n("Debugging program"));
00343 
00344     startDebugger();
00345     controller->slotRun();
00346 }
00347 
00348 
00349 
00350 void JavaDebuggerPart::slotStop()
00351 {
00352     core()->running(this, false);
00353 
00354     KActionCollection *ac = actionCollection();
00355     ac->action("debug_stop")->setEnabled(false);
00356     ac->action("debug_pause")->setEnabled(false);
00357     ac->action("debug_cont")->setEnabled(false);
00358     ac->action("debug_runtocursor")->setEnabled(false);
00359     ac->action("debug_stepover")->setEnabled(false);
00360     ac->action("debug_stepoverinst")->setEnabled(false);
00361     ac->action("debug_stepinto")->setEnabled(false);
00362     ac->action("debug_stepintoinst")->setEnabled(false);
00363     ac->action("debug_stepout")->setEnabled(false);
00364     ac->action("debug_memview")->setEnabled(false);
00365 
00366     mainWindow()->setViewAvailable(variableWidget, false);
00367     mainWindow()->setViewAvailable(framestackWidget, false);
00368     mainWindow()->setViewAvailable(disassembleWidget, false);
00369 
00370     variableWidget->setEnabled(false);
00371     framestackWidget->setEnabled(false);
00372     disassembleWidget->setEnabled(false);
00373 
00374     breakpointWidget->reset();
00375     framestackWidget->clear();
00376     variableWidget->clear();
00377     disassembleWidget->clear();
00378     disassembleWidget->slotActivate(false);
00379 
00380     debugger()->clearExecutionPoint();
00381     //    delete floatingToolBar;
00382     //    floatingToolBar = 0;
00383 
00384 }
00385 
00386 
00387 void JavaDebuggerPart::slotPause()
00388 {
00389     controller->slotBreakInto();
00390 }
00391 
00392 
00393 void JavaDebuggerPart::slotContinue()
00394 {
00395     controller->slotRun();
00396 }
00397 
00398 
00399 void JavaDebuggerPart::slotStepOver()
00400 {
00401     controller->slotStepOver();
00402 }
00403 
00404 
00405 void JavaDebuggerPart::slotStepIntoInstruction()
00406 {
00407     controller->slotStepIntoIns();
00408 }
00409 
00410 
00411 void JavaDebuggerPart::slotStepInto()
00412 {
00413     controller->slotStepInto();
00414 }
00415 
00416 
00417 void JavaDebuggerPart::slotStepOut()
00418 {
00419     controller->slotStepOutOff();
00420 }
00421 
00422 
00423 void JavaDebuggerPart::slotMemoryView()
00424 {
00425     // Hmm, couldn't this be made non-modal?
00426 
00427     MemoryViewDialog *dlg = new MemoryViewDialog();
00428     connect( dlg,        SIGNAL(disassemble(const QString&, const QString&)),
00429              controller, SLOT(slotDisassemble(const QString&, const QString&)));
00430     connect( dlg,        SIGNAL(memoryDump(const QString&, const QString&)),
00431              controller, SLOT(slotMemoryDump(const QString&, const QString&)));
00432     connect( dlg,        SIGNAL(registers()),
00433              controller, SLOT(slotRegisters()));
00434     connect( dlg,        SIGNAL(libraries()),
00435              controller, SLOT(slotLibraries()));
00436 
00437     connect( controller, SIGNAL(rawJDBMemoryDump(char*)),
00438              dlg,        SLOT(slotRawJDBMemoryView(char*)));
00439     connect( controller, SIGNAL(rawJDBDisassemble(char*)),
00440              dlg,        SLOT(slotRawJDBMemoryView(char*)));
00441     connect( controller, SIGNAL(rawJDBRegisters(char*)),
00442              dlg,        SLOT(slotRawJDBMemoryView(char*)));
00443     connect( controller, SIGNAL(rawJDBLibraries(char*)),
00444              dlg,        SLOT(slotRawJDBMemoryView(char*)));
00445 
00446     dlg->exec();
00447     delete dlg;
00448 }
00449 
00450 
00451 void JavaDebuggerPart::slotRefreshBPState(Breakpoint *BP)
00452 {
00453     if (BP->isActionDie())
00454         debugger()->setBreakpoint(BP->fileName(), BP->lineNum()-1,
00455                               -1, true, false);
00456     else
00457         debugger()->setBreakpoint(BP->fileName(), BP->lineNum()-1,
00458                               1/*BP->id()*/, BP->isEnabled(), BP->isPending() );
00459 }
00460 
00461 
00462 void JavaDebuggerPart::slotStatus(const QString &msg, int state)
00463 {
00464     QString stateIndicator("P");    // default to "paused"
00465 
00466     if (state & s_appBusy) {
00467         stateIndicator = "A";
00468        debugger()->clearExecutionPoint();
00469     }
00470 
00471     if (state & (s_dbgNotStarted|s_appNotStarted))
00472         stateIndicator = " ";
00473 
00474     if (state & s_programExited) {
00475         stateIndicator = "E";
00476         debugger()->clearExecutionPoint();
00477     }
00478 
00479     // And now? :-)
00480     kdDebug(9012) << "Debugger state: " << stateIndicator << endl;
00481 
00482     if (!msg.isEmpty())
00483         mainWindow()->statusBar()->message(msg);
00484 }
00485 
00486 
00487 void JavaDebuggerPart::slotShowStep(const QString &fileName, int lineNum)
00488 {
00489     // Debugger counts lines from 1
00490     debugger()->gotoExecutionPoint(KURL( fileName ), lineNum-1);
00491 }
00492 
00493 
00494 void JavaDebuggerPart::slotGotoSource(const QString &fileName, int lineNum)
00495 {
00496     partController()->editDocument(KURL( fileName ), lineNum);
00497 }
00498 
00499 }
00500 
00501 #include "javadebuggerpart.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 Wed Mar 23 00:03:47 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003