KDevelop API Documentation

languages/java/debugger/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 RMB 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 RMB displays " 00082 "a popupmenu 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(fileName, lineNum-1); 00491 } 00492 00493 00494 void JavaDebuggerPart::slotGotoSource(const QString &fileName, int lineNum) 00495 { 00496 partController()->editDocument(fileName, lineNum); 00497 } 00498 00499 } 00500 00501 #include "javadebuggerpart.moc"
KDE Logo
This file is part of the documentation for KDevelop Version 3.0.4.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Oct 19 08:01:43 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003