Debugger: Introduce engine capability flags to enable actions correctly.

Reviewed-by: hjk
This commit is contained in:
Friedemann Kleint
2010-02-05 10:23:55 +01:00
parent 5c2738d6ee
commit b6c7c597c2
12 changed files with 66 additions and 17 deletions

View File

@@ -1499,6 +1499,11 @@ void CdbDebugEngine::syncDebuggerPaths()
} }
} }
unsigned CdbDebugEngine::debuggerCapabilities() const
{
return DisassemblerCapability | RegisterCapability | ShowMemoryCapability;
}
// Accessed by DebuggerManager // Accessed by DebuggerManager
IDebuggerEngine *createWinEngine(DebuggerManager *parent, IDebuggerEngine *createWinEngine(DebuggerManager *parent,
bool cmdLineEnabled, bool cmdLineEnabled,

View File

@@ -67,6 +67,7 @@ public:
virtual void exitDebugger(); virtual void exitDebugger();
virtual void detachDebugger(); virtual void detachDebugger();
virtual void updateWatchData(const WatchData &data); virtual void updateWatchData(const WatchData &data);
virtual unsigned debuggerCapabilities() const;
virtual void stepExec(); virtual void stepExec();
virtual void stepOutExec(); virtual void stepOutExec();

View File

@@ -109,6 +109,19 @@ enum DebuggerStartMode
StartRemote // Start and attach to a remote process 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 enum LogChannel
{ {
LogInput, // Used for user input LogInput, // Used for user input

View File

@@ -1051,6 +1051,10 @@ void DebuggerManager::startNewDebugger(const DebuggerStartParametersPtr &sp)
setState(EngineStarting); setState(EngineStarting);
connect(d->m_engine, SIGNAL(startFailed()), this, SLOT(startFailed())); connect(d->m_engine, SIGNAL(startFailed()), this, SLOT(startFailed()));
d->m_engine->startDebugger(d->m_startParameters); 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() void DebuggerManager::startFailed()
@@ -1717,10 +1721,12 @@ void DebuggerManager::setState(DebuggerState state, bool forced)
if (stopped) if (stopped)
QApplication::alert(mainWindow(), 3000); QApplication::alert(mainWindow(), 3000);
const bool actionsEnabled = debuggerActionsEnabled();
const unsigned engineCapabilities = debuggerCapabilities();
d->m_actions.watchAction1->setEnabled(true); d->m_actions.watchAction1->setEnabled(true);
d->m_actions.watchAction2->setEnabled(true); d->m_actions.watchAction2->setEnabled(true);
d->m_actions.breakAction->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; bool interruptIsExit = !running;
if (interruptIsExit) { if (interruptIsExit) {
@@ -1740,12 +1746,13 @@ void DebuggerManager::setState(DebuggerState state, bool forced)
d->m_actions.stepOutAction->setEnabled(stopped); d->m_actions.stepOutAction->setEnabled(stopped);
d->m_actions.runToLineAction->setEnabled(stopped); d->m_actions.runToLineAction->setEnabled(stopped);
d->m_actions.runToFunctionAction->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); d->m_actions.nextAction->setEnabled(stopped);
const bool actionsEnabled = debuggerActionsEnabled();
theDebuggerAction(RecheckDebuggingHelpers)->setEnabled(actionsEnabled); theDebuggerAction(RecheckDebuggingHelpers)->setEnabled(actionsEnabled);
theDebuggerAction(AutoDerefPointers)->setEnabled(actionsEnabled && d->m_engine->isGdbEngine()); theDebuggerAction(AutoDerefPointers)->setEnabled(actionsEnabled &&
(engineCapabilities & AutoDerefPointersCapability));
theDebuggerAction(ExpandStack)->setEnabled(actionsEnabled); theDebuggerAction(ExpandStack)->setEnabled(actionsEnabled);
theDebuggerAction(ExecuteCommand)->setEnabled(d->m_state != DebuggerNotReady); theDebuggerAction(ExecuteCommand)->setEnabled(d->m_state != DebuggerNotReady);
@@ -1787,6 +1794,11 @@ bool DebuggerManager::debuggerActionsEnabled() const
return false; return false;
} }
unsigned DebuggerManager::debuggerCapabilities() const
{
return d->m_engine ? d->m_engine->debuggerCapabilities() : 0;
}
bool DebuggerManager::checkDebugConfiguration(int toolChain, bool DebuggerManager::checkDebugConfiguration(int toolChain,
QString *errorMessage, QString *errorMessage,
QString *settingsCategory /* = 0 */, QString *settingsCategory /* = 0 */,

View File

@@ -188,6 +188,7 @@ public:
int buttons = 0); int buttons = 0);
bool debuggerActionsEnabled() const; bool debuggerActionsEnabled() const;
unsigned debuggerCapabilities() const;
bool checkDebugConfiguration(int toolChain, bool checkDebugConfiguration(int toolChain,
QString *errorMessage, QString *errorMessage,

View File

@@ -1696,6 +1696,13 @@ void GdbEngine::startDebugger(const DebuggerStartParametersPtr &sp)
m_gdbAdapter->startAdapter(); m_gdbAdapter->startAdapter();
} }
unsigned GdbEngine::debuggerCapabilities() const
{
return ReverseSteppingCapability | SnapshotCapability | AutoDerefPointersCapability
| DisassemblerCapability | RegisterCapability | ShowMemoryCapability
| JumpToLineCapability | ReloadModuleCapability | ReloadModuleSymbolsCapability;
}
void GdbEngine::continueInferiorInternal() void GdbEngine::continueInferiorInternal()
{ {
QTC_ASSERT(state() == InferiorStopped || state() == InferiorStarting, QTC_ASSERT(state() == InferiorStopped || state() == InferiorStarting,

View File

@@ -103,10 +103,8 @@ private: ////////// General Interface //////////
virtual void addOptionPages(QList<Core::IOptionsPage*> *opts) const; virtual void addOptionPages(QList<Core::IOptionsPage*> *opts) const;
virtual bool checkConfiguration(int toolChain, QString *errorMessage, QString *settingsPage= 0) 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 void startDebugger(const DebuggerStartParametersPtr &sp);
virtual unsigned debuggerCapabilities() const;
virtual void exitDebugger(); virtual void exitDebugger();
virtual void detachDebugger(); virtual void detachDebugger();
virtual void shutdown(); virtual void shutdown();

View File

@@ -118,7 +118,7 @@ public:
{ Q_UNUSED(regnr); Q_UNUSED(value); } { Q_UNUSED(regnr); Q_UNUSED(value); }
virtual void addOptionPages(QList<Core::IOptionsPage*> *) const {} 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 checkConfiguration(int /* toolChain */, QString * /* errorMessage */, QString * /* settingsPage */ = 0) const { return true; }
virtual bool isSynchroneous() const { return false; } virtual bool isSynchroneous() const { return false; }

View File

@@ -108,27 +108,29 @@ void ModulesWindow::contextMenuEvent(QContextMenuEvent *ev)
QMenu menu; QMenu menu;
const bool enabled = Debugger::DebuggerManager::instance()->debuggerActionsEnabled(); const bool enabled = Debugger::DebuggerManager::instance()->debuggerActionsEnabled();
const unsigned capabilities = Debugger::DebuggerManager::instance()->debuggerCapabilities();
QAction *act0 = new QAction(tr("Update module list"), &menu); 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); 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); QAction *act4 = new QAction(tr("Load symbols for all modules"), &menu);
act4->setEnabled(enabled); act4->setEnabled(enabled && (capabilities & ReloadModuleSymbolsCapability));
QAction *act5 = 0; QAction *act5 = 0;
QAction *act6 = 0; QAction *act6 = 0;
QAction *act7 = 0; QAction *act7 = 0;
if (name.isEmpty()) { if (name.isEmpty()) {
act5 = new QAction(tr("Load symbols for module"), &menu); act5 = new QAction(tr("Load symbols for module"), &menu);
act5->setEnabled(false);
act6 = new QAction(tr("Edit file"), &menu); act6 = new QAction(tr("Edit file"), &menu);
act6->setEnabled(false);
act7 = new QAction(tr("Show symbols"), &menu); act7 = new QAction(tr("Show symbols"), &menu);
act7->setEnabled(false);
} else { } else {
act5 = new QAction(tr("Load symbols for module \"%1\"").arg(name), &menu); 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); act6 = new QAction(tr("Edit file \"%1\"").arg(name), &menu);
act7 = new QAction(tr("Show symbols in 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(act0);
menu.addAction(act4); menu.addAction(act4);

View File

@@ -165,7 +165,12 @@ void RegisterWindow::contextMenuEvent(QContextMenuEvent *ev)
{ {
QMenu menu; QMenu menu;
const unsigned engineCapabilities = m_manager->debuggerCapabilities();
const bool actionsEnabled = m_manager->debuggerActionsEnabled();
QAction *actReload = menu.addAction(tr("Reload register listing")); QAction *actReload = menu.addAction(tr("Reload register listing"));
actReload->setEnabled(engineCapabilities & RegisterCapability);
menu.addSeparator(); menu.addSeparator();
QModelIndex idx = indexAt(ev->pos()); QModelIndex idx = indexAt(ev->pos());
@@ -176,8 +181,8 @@ void RegisterWindow::contextMenuEvent(QContextMenuEvent *ev)
actShowMemory->setEnabled(false); actShowMemory->setEnabled(false);
} else { } else {
actShowMemory->setText(tr("Open memory editor at %1").arg(address)); actShowMemory->setText(tr("Open memory editor at %1").arg(address));
actShowMemory->setEnabled(actionsEnabled & (engineCapabilities & ShowMemoryCapability));
} }
actShowMemory->setEnabled(m_manager->debuggerActionsEnabled());
menu.addSeparator(); menu.addSeparator();
int base = model()->data(QModelIndex(), RegisterNumberBaseRole).toInt(); int base = model()->data(QModelIndex(), RegisterNumberBaseRole).toInt();

View File

@@ -96,6 +96,7 @@ void StackWindow::contextMenuEvent(QContextMenuEvent *ev)
QMenu menu; QMenu menu;
const unsigned engineCapabilities = m_manager->debuggerCapabilities();
menu.addAction(theDebuggerAction(ExpandStack)); menu.addAction(theDebuggerAction(ExpandStack));
QAction *actCopyContents = menu.addAction(tr("Copy contents to clipboard")); QAction *actCopyContents = menu.addAction(tr("Copy contents to clipboard"));
@@ -107,6 +108,7 @@ void StackWindow::contextMenuEvent(QContextMenuEvent *ev)
actShowMemory->setEnabled(false); actShowMemory->setEnabled(false);
} else { } else {
actShowMemory->setText(tr("Open memory editor at %1").arg(address)); actShowMemory->setText(tr("Open memory editor at %1").arg(address));
actShowMemory->setEnabled(engineCapabilities & ShowMemoryCapability);
} }
QAction *actShowDisassembler = menu.addAction(QString()); QAction *actShowDisassembler = menu.addAction(QString());
@@ -115,6 +117,7 @@ void StackWindow::contextMenuEvent(QContextMenuEvent *ev)
actShowDisassembler->setEnabled(false); actShowDisassembler->setEnabled(false);
} else { } else {
actShowDisassembler->setText(tr("Open disassembler at %1").arg(address)); actShowDisassembler->setText(tr("Open disassembler at %1").arg(address));
actShowDisassembler->setEnabled(engineCapabilities & DisassemblerCapability);
} }
menu.addSeparator(); menu.addSeparator();

View File

@@ -261,12 +261,14 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
QAction *actSelectWidgetToWatch = menu.addAction(tr("Select widget to watch")); QAction *actSelectWidgetToWatch = menu.addAction(tr("Select widget to watch"));
const bool actionsEnabled = m_manager->debuggerActionsEnabled(); const bool actionsEnabled = m_manager->debuggerActionsEnabled();
const unsigned engineCapabilities = m_manager->debuggerCapabilities();
const QString address = model()->data(mi0, AddressRole).toString(); const QString address = model()->data(mi0, AddressRole).toString();
QAction *actWatchKnownMemory = 0; QAction *actWatchKnownMemory = 0;
QAction *actWatchUnknownMemory = new QAction(tr("Open memory editor..."), &menu); 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); actWatchKnownMemory = new QAction(tr("Open memory editor at %1").arg(address), &menu);
menu.addSeparator(); menu.addSeparator();