00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
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
00117 connect( variableTree, SIGNAL(selectFrame(
int)),
00118 framestackWidget, SLOT(slotSelectFrame(
int)));
00119
00120
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
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
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
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
00257 connect(
framestackWidget, SIGNAL(selectFrame(
int)),
00258
controller, SLOT(slotSelectFrame(
int)));
00259
00260
00261 connect(
breakpointWidget, SIGNAL(clearAllBreakpoints()),
00262
controller, SLOT(slotClearAllBreakpoints()));
00263
00264
00265 connect(
disassembleWidget,SIGNAL(disassemble(
const QString&,
const QString&)),
00266
controller, SLOT(slotDisassemble(
const QString&,
const QString&)));
00267
00268
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
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
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
00293
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
00326
00327
00328
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
00382
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
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->
isEnabled(), BP->
isPending() );
00459 }
00460
00461
00462 void JavaDebuggerPart::slotStatus(
const QString &msg,
int state)
00463 {
00464
QString stateIndicator(
"P");
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
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
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"