diff --git a/src/plugins/debugger/cdb/cdbdebugengine.cpp b/src/plugins/debugger/cdb/cdbdebugengine.cpp index e7c7dc49299cb7aaf2f94ddec28d68700d4f7965..f844a2379b33dcce11054064a8cbcc41a5b1d7e3 100644 --- a/src/plugins/debugger/cdb/cdbdebugengine.cpp +++ b/src/plugins/debugger/cdb/cdbdebugengine.cpp @@ -1499,6 +1499,11 @@ void CdbDebugEngine::syncDebuggerPaths() } } +unsigned CdbDebugEngine::debuggerCapabilities() const +{ + return DisassemblerCapability | RegisterCapability | ShowMemoryCapability; +} + // Accessed by DebuggerManager IDebuggerEngine *createWinEngine(DebuggerManager *parent, bool cmdLineEnabled, diff --git a/src/plugins/debugger/cdb/cdbdebugengine.h b/src/plugins/debugger/cdb/cdbdebugengine.h index 1085a71de75dd17e19e0e2d36d133f42560168a2..9265ce757f2ae205915e3880bf9cd5402d1c3898 100644 --- a/src/plugins/debugger/cdb/cdbdebugengine.h +++ b/src/plugins/debugger/cdb/cdbdebugengine.h @@ -67,6 +67,7 @@ public: virtual void exitDebugger(); virtual void detachDebugger(); virtual void updateWatchData(const WatchData &data); + virtual unsigned debuggerCapabilities() const; virtual void stepExec(); virtual void stepOutExec(); diff --git a/src/plugins/debugger/debuggerconstants.h b/src/plugins/debugger/debuggerconstants.h index 381ea9cf9539f3af6d4ae56c10f7aafcf5b41747..2f9b2554434eeaf8e9162047f159202d58c0e6b5 100644 --- a/src/plugins/debugger/debuggerconstants.h +++ b/src/plugins/debugger/debuggerconstants.h @@ -109,6 +109,19 @@ enum DebuggerStartMode StartRemote // Start and attach to a remote process }; +enum DebuggerCapabilities +{ + ReverseSteppingCapability = 0x1, + SnapshotCapability = 0x2, + AutoDerefPointersCapability = 0x4, + DisassemblerCapability = 0x80, + RegisterCapability = 0x10, + ShowMemoryCapability = 0x20, + JumpToLineCapability = 0x40, + ReloadModuleCapability = 0x80, + ReloadModuleSymbolsCapability = 0x100, +}; + enum LogChannel { LogInput, // Used for user input diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index 1586e00b8480fd2da01f91faae02b22fb4761735..4e88a793225a5d3f7e21d5c5f365a291f26679c6 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -1051,6 +1051,10 @@ void DebuggerManager::startNewDebugger(const DebuggerStartParametersPtr &sp) setState(EngineStarting); connect(d->m_engine, SIGNAL(startFailed()), this, SLOT(startFailed())); d->m_engine->startDebugger(d->m_startParameters); + + const unsigned engineCapabilities = d->m_engine->debuggerCapabilities(); + theDebuggerAction(OperateByInstruction)->setEnabled(engineCapabilities & DisassemblerCapability); + d->m_actions.reverseDirectionAction->setEnabled(engineCapabilities & ReverseSteppingCapability); } void DebuggerManager::startFailed() @@ -1717,10 +1721,12 @@ void DebuggerManager::setState(DebuggerState state, bool forced) if (stopped) QApplication::alert(mainWindow(), 3000); + const bool actionsEnabled = debuggerActionsEnabled(); + const unsigned engineCapabilities = debuggerCapabilities(); d->m_actions.watchAction1->setEnabled(true); d->m_actions.watchAction2->setEnabled(true); d->m_actions.breakAction->setEnabled(true); - d->m_actions.snapshotAction->setEnabled(stopped); + d->m_actions.snapshotAction->setEnabled(stopped && (engineCapabilities & SnapshotCapability)); bool interruptIsExit = !running; if (interruptIsExit) { @@ -1740,12 +1746,13 @@ void DebuggerManager::setState(DebuggerState state, bool forced) d->m_actions.stepOutAction->setEnabled(stopped); d->m_actions.runToLineAction->setEnabled(stopped); d->m_actions.runToFunctionAction->setEnabled(stopped); - d->m_actions.jumpToLineAction->setEnabled(stopped); + d->m_actions.jumpToLineAction->setEnabled(stopped && + (engineCapabilities & JumpToLineCapability)); d->m_actions.nextAction->setEnabled(stopped); - const bool actionsEnabled = debuggerActionsEnabled(); theDebuggerAction(RecheckDebuggingHelpers)->setEnabled(actionsEnabled); - theDebuggerAction(AutoDerefPointers)->setEnabled(actionsEnabled && d->m_engine->isGdbEngine()); + theDebuggerAction(AutoDerefPointers)->setEnabled(actionsEnabled && + (engineCapabilities & AutoDerefPointersCapability)); theDebuggerAction(ExpandStack)->setEnabled(actionsEnabled); theDebuggerAction(ExecuteCommand)->setEnabled(d->m_state != DebuggerNotReady); @@ -1787,6 +1794,11 @@ bool DebuggerManager::debuggerActionsEnabled() const return false; } +unsigned DebuggerManager::debuggerCapabilities() const +{ + return d->m_engine ? d->m_engine->debuggerCapabilities() : 0; +} + bool DebuggerManager::checkDebugConfiguration(int toolChain, QString *errorMessage, QString *settingsCategory /* = 0 */, diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h index 35b5b9841d4e44b64632a9aed29c8319f52ffa5e..c8275db6f5a3ee3b065b34b6754b2e61d64cfa2f 100644 --- a/src/plugins/debugger/debuggermanager.h +++ b/src/plugins/debugger/debuggermanager.h @@ -188,6 +188,7 @@ public: int buttons = 0); bool debuggerActionsEnabled() const; + unsigned debuggerCapabilities() const; bool checkDebugConfiguration(int toolChain, QString *errorMessage, diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index a616072b318f58040573ca2fdccb1a72fb87966e..b74130e61bccbe4a70c19773c8b89649edc84467 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -1696,6 +1696,13 @@ void GdbEngine::startDebugger(const DebuggerStartParametersPtr &sp) m_gdbAdapter->startAdapter(); } +unsigned GdbEngine::debuggerCapabilities() const +{ + return ReverseSteppingCapability | SnapshotCapability | AutoDerefPointersCapability + | DisassemblerCapability | RegisterCapability | ShowMemoryCapability + | JumpToLineCapability | ReloadModuleCapability | ReloadModuleSymbolsCapability; +} + void GdbEngine::continueInferiorInternal() { QTC_ASSERT(state() == InferiorStopped || state() == InferiorStarting, diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index 73560d55fa1b90dbb2b42a1442ed8dbe1624c5d7..7afddca9d991be427f131a0df4b78669569b3d5d 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -103,10 +103,8 @@ private: ////////// General Interface ////////// virtual void addOptionPages(QList<Core::IOptionsPage*> *opts) const; virtual bool checkConfiguration(int toolChain, QString *errorMessage, QString *settingsPage= 0) const; - - virtual bool isGdbEngine() const { return true; } - virtual void startDebugger(const DebuggerStartParametersPtr &sp); + virtual unsigned debuggerCapabilities() const; virtual void exitDebugger(); virtual void detachDebugger(); virtual void shutdown(); diff --git a/src/plugins/debugger/idebuggerengine.h b/src/plugins/debugger/idebuggerengine.h index cc0a91af282b216780e4d393a5b98e669f974f16..b60e8c7fb340cdf2cbcbee8389424893e3bb076a 100644 --- a/src/plugins/debugger/idebuggerengine.h +++ b/src/plugins/debugger/idebuggerengine.h @@ -118,7 +118,7 @@ public: { Q_UNUSED(regnr); Q_UNUSED(value); } virtual void addOptionPages(QList<Core::IOptionsPage*> *) const {} - virtual bool isGdbEngine() const { return false; } + virtual unsigned debuggerCapabilities() const { return 0; } virtual bool checkConfiguration(int /* toolChain */, QString * /* errorMessage */, QString * /* settingsPage */ = 0) const { return true; } virtual bool isSynchroneous() const { return false; } diff --git a/src/plugins/debugger/moduleswindow.cpp b/src/plugins/debugger/moduleswindow.cpp index 95229f10bb5501c9eb8d7cac67e8412227f60326..224319b6ac9c3c6937ed06b33bb5a41a87399739 100644 --- a/src/plugins/debugger/moduleswindow.cpp +++ b/src/plugins/debugger/moduleswindow.cpp @@ -108,27 +108,29 @@ void ModulesWindow::contextMenuEvent(QContextMenuEvent *ev) QMenu menu; const bool enabled = Debugger::DebuggerManager::instance()->debuggerActionsEnabled(); + const unsigned capabilities = Debugger::DebuggerManager::instance()->debuggerCapabilities(); QAction *act0 = new QAction(tr("Update module list"), &menu); - act0->setEnabled(enabled); + act0->setEnabled(enabled && (capabilities & ReloadModuleCapability)); QAction *act3 = new QAction(tr("Show source files for module \"%1\"").arg(name), &menu); - act3->setEnabled(enabled); + act3->setEnabled(enabled && (capabilities & ReloadModuleCapability)); QAction *act4 = new QAction(tr("Load symbols for all modules"), &menu); - act4->setEnabled(enabled); + act4->setEnabled(enabled && (capabilities & ReloadModuleSymbolsCapability)); QAction *act5 = 0; QAction *act6 = 0; QAction *act7 = 0; if (name.isEmpty()) { act5 = new QAction(tr("Load symbols for module"), &menu); + act5->setEnabled(false); act6 = new QAction(tr("Edit file"), &menu); + act6->setEnabled(false); act7 = new QAction(tr("Show symbols"), &menu); + act7->setEnabled(false); } else { act5 = new QAction(tr("Load symbols for module \"%1\"").arg(name), &menu); + act5->setEnabled(capabilities & ReloadModuleSymbolsCapability); act6 = new QAction(tr("Edit file \"%1\"").arg(name), &menu); act7 = new QAction(tr("Show symbols in file \"%1\"").arg(name), &menu); } - act5->setDisabled(name.isEmpty()); - act6->setDisabled(name.isEmpty()); - act7->setDisabled(name.isEmpty()); menu.addAction(act0); menu.addAction(act4); diff --git a/src/plugins/debugger/registerwindow.cpp b/src/plugins/debugger/registerwindow.cpp index 092efb445e2e7191543e1cafef84d855206bb28c..6103d9e984dbcb3db9c6490fbe83e745b1e3a284 100644 --- a/src/plugins/debugger/registerwindow.cpp +++ b/src/plugins/debugger/registerwindow.cpp @@ -165,7 +165,12 @@ void RegisterWindow::contextMenuEvent(QContextMenuEvent *ev) { QMenu menu; + const unsigned engineCapabilities = m_manager->debuggerCapabilities(); + const bool actionsEnabled = m_manager->debuggerActionsEnabled(); + QAction *actReload = menu.addAction(tr("Reload register listing")); + actReload->setEnabled(engineCapabilities & RegisterCapability); + menu.addSeparator(); QModelIndex idx = indexAt(ev->pos()); @@ -176,8 +181,8 @@ void RegisterWindow::contextMenuEvent(QContextMenuEvent *ev) actShowMemory->setEnabled(false); } else { actShowMemory->setText(tr("Open memory editor at %1").arg(address)); + actShowMemory->setEnabled(actionsEnabled & (engineCapabilities & ShowMemoryCapability)); } - actShowMemory->setEnabled(m_manager->debuggerActionsEnabled()); menu.addSeparator(); int base = model()->data(QModelIndex(), RegisterNumberBaseRole).toInt(); diff --git a/src/plugins/debugger/stackwindow.cpp b/src/plugins/debugger/stackwindow.cpp index d39172f1ea97f685cc51a32814c36bcfad2caeba..53595cc384502ad1dbfd442efc66ad81775bb80e 100644 --- a/src/plugins/debugger/stackwindow.cpp +++ b/src/plugins/debugger/stackwindow.cpp @@ -96,6 +96,7 @@ void StackWindow::contextMenuEvent(QContextMenuEvent *ev) QMenu menu; + const unsigned engineCapabilities = m_manager->debuggerCapabilities(); menu.addAction(theDebuggerAction(ExpandStack)); QAction *actCopyContents = menu.addAction(tr("Copy contents to clipboard")); @@ -107,6 +108,7 @@ void StackWindow::contextMenuEvent(QContextMenuEvent *ev) actShowMemory->setEnabled(false); } else { actShowMemory->setText(tr("Open memory editor at %1").arg(address)); + actShowMemory->setEnabled(engineCapabilities & ShowMemoryCapability); } QAction *actShowDisassembler = menu.addAction(QString()); @@ -115,6 +117,7 @@ void StackWindow::contextMenuEvent(QContextMenuEvent *ev) actShowDisassembler->setEnabled(false); } else { actShowDisassembler->setText(tr("Open disassembler at %1").arg(address)); + actShowDisassembler->setEnabled(engineCapabilities & DisassemblerCapability); } menu.addSeparator(); diff --git a/src/plugins/debugger/watchwindow.cpp b/src/plugins/debugger/watchwindow.cpp index b259c4c22e954a869291c3d53263c820e017a51e..c23eef459b3f815b02a408fb25efc11f37bc9d43 100644 --- a/src/plugins/debugger/watchwindow.cpp +++ b/src/plugins/debugger/watchwindow.cpp @@ -261,12 +261,14 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev) QAction *actSelectWidgetToWatch = menu.addAction(tr("Select widget to watch")); const bool actionsEnabled = m_manager->debuggerActionsEnabled(); + const unsigned engineCapabilities = m_manager->debuggerCapabilities(); const QString address = model()->data(mi0, AddressRole).toString(); QAction *actWatchKnownMemory = 0; QAction *actWatchUnknownMemory = new QAction(tr("Open memory editor..."), &menu); - actWatchUnknownMemory->setEnabled(actionsEnabled); + const bool canShowMemory = engineCapabilities & ShowMemoryCapability; + actWatchUnknownMemory->setEnabled(actionsEnabled && canShowMemory); - if (!address.isEmpty()) + if (canShowMemory && !address.isEmpty()) actWatchKnownMemory = new QAction(tr("Open memory editor at %1").arg(address), &menu); menu.addSeparator();