debugger: overhaul "state machine"

This mainly allows for more precise shutdown and tightens the set
of allowed transitions.
This commit is contained in:
hjk
2010-07-09 17:07:59 +02:00
parent 6089bc1b9e
commit e760700f0f
41 changed files with 1414 additions and 834 deletions
+39 -39
View File
@@ -232,9 +232,14 @@ void CdbEngine::setState(DebuggerState state, const char *func, int line)
DebuggerEngine::setState(state);
}
void CdbEngine::shutdown()
void CdbEngine::shutdownInferior()
{
exitDebugger();
notifyInferiorShutdownOk();
}
void CdbEngine::shutdownEngine()
{
m_d->endDebugging();
}
QString CdbEngine::editorToolTip(const QString &exp, const QString &function)
@@ -376,7 +381,7 @@ void CdbEngine::startupChecks()
void CdbEngine::setupEngine()
{
QTC_ASSERT(state() == EngineSettingUp, qDebug() << state());
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
const DebuggerStartParameters &sp = startParameters();
if (debugCDBExecution)
qDebug() << "startDebugger";
@@ -426,7 +431,7 @@ void CdbEngine::setupEngine()
void CdbEngine::setupInferior()
{
QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state());
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
notifyInferiorSetupOk();
}
@@ -499,7 +504,7 @@ bool CdbEngine::startAttachDebugger(qint64 pid, DebuggerStartMode sm, QString *e
void CdbEnginePrivate::processCreatedAttached(ULONG64 processHandle, ULONG64 initialThreadHandle)
{
m_engine->setState(InferiorRunningRequested, Q_FUNC_INFO, __LINE__);
m_engine->setState(InferiorRunRequested, Q_FUNC_INFO, __LINE__);
setDebuggeeHandles(reinterpret_cast<HANDLE>(processHandle), reinterpret_cast<HANDLE>(initialThreadHandle));
ULONG currentThreadId;
if (SUCCEEDED(interfaces().debugSystemObjects->GetThreadIdByHandle(initialThreadHandle, &currentThreadId))) {
@@ -526,7 +531,7 @@ void CdbEnginePrivate::processCreatedAttached(ULONG64 processHandle, ULONG64 ini
m_engine->warning(QString::fromLatin1("Handshake failed on event #%1: %2").arg(evtNr).arg(CdbCore::msgComFailed("SetNotifyEventHandle", hr)));
}
}
m_engine->setState(InferiorRunning, Q_FUNC_INFO, __LINE__);
m_engine->setState(InferiorRunOk, Q_FUNC_INFO, __LINE__);
if (debugCDBExecution)
qDebug() << "<processCreatedAttached";
}
@@ -534,13 +539,13 @@ void CdbEnginePrivate::processCreatedAttached(ULONG64 processHandle, ULONG64 ini
void CdbEngine::processTerminated(unsigned long exitCode)
{
showMessage(tr("The process exited with exit code %1.").arg(exitCode));
if (state() != InferiorStopping)
setState(InferiorStopping, Q_FUNC_INFO, __LINE__);
setState(InferiorStopped, Q_FUNC_INFO, __LINE__);
setState(InferiorShuttingDown, Q_FUNC_INFO, __LINE__);
if (state() != InferiorStopRequested)
setState(InferiorStopRequested, Q_FUNC_INFO, __LINE__);
setState(InferiorStopOk, Q_FUNC_INFO, __LINE__);
setState(InferiorShutdownRequested, Q_FUNC_INFO, __LINE__);
m_d->setDebuggeeHandles(0, 0);
m_d->clearForRun();
setState(InferiorShutDown, Q_FUNC_INFO, __LINE__);
setState(InferiorShutdownOk, Q_FUNC_INFO, __LINE__);
// Avoid calls from event handler.
QTimer::singleShot(0, this, SLOT(quitDebugger()));
}
@@ -548,7 +553,7 @@ void CdbEngine::processTerminated(unsigned long exitCode)
bool CdbEnginePrivate::endInferior(EndInferiorAction action, QString *errorMessage)
{
// Process must be stopped in order to terminate
m_engine->setState(InferiorShuttingDown, Q_FUNC_INFO, __LINE__); // pretend it is shutdown
m_engine->setState(InferiorShutdownRequested, Q_FUNC_INFO, __LINE__); // pretend it is shutdown
const bool wasRunning = isDebuggeeRunning();
if (wasRunning) {
interruptInterferiorProcess(errorMessage);
@@ -577,7 +582,7 @@ bool CdbEnginePrivate::endInferior(EndInferiorAction action, QString *errorMessa
// Perform cleanup even when failed..no point clinging to the process
setDebuggeeHandles(0, 0);
killWatchTimer();
m_engine->setState(success ? InferiorShutDown : InferiorShutdownFailed, Q_FUNC_INFO, __LINE__);
m_engine->setState(success ? InferiorShutdownOk : InferiorShutdownFailed, Q_FUNC_INFO, __LINE__);
return success;
}
@@ -594,7 +599,7 @@ void CdbEnginePrivate::endDebugging(EndDebuggingMode em)
return;
// Do we need to stop the process?
QString errorMessage;
if (oldState != InferiorShutDown && m_hDebuggeeProcess) {
if (oldState != InferiorShutdownOk && m_hDebuggeeProcess) {
EndInferiorAction action;
switch (em) {
case EndDebuggingAuto:
@@ -618,7 +623,7 @@ void CdbEnginePrivate::endDebugging(EndDebuggingMode em)
errorMessage.clear();
}
// Clean up resources (open files, etc.)
m_engine->setState(EngineShuttingDown, Q_FUNC_INFO, __LINE__);
m_engine->setState(EngineShutdownRequested, Q_FUNC_INFO, __LINE__);
clearForRun();
const bool endedCleanly = endSession(&errorMessage);
m_engine->setState(DebuggerNotReady, Q_FUNC_INFO, __LINE__);
@@ -628,11 +633,6 @@ void CdbEnginePrivate::endDebugging(EndDebuggingMode em)
}
}
void CdbEngine::exitDebugger()
{
m_d->endDebugging();
}
void CdbEngine::detachDebugger()
{
m_d->endDebugging(CdbEnginePrivate::EndDebuggingDetach);
@@ -712,15 +712,15 @@ bool CdbEnginePrivate::executeContinueCommand(const QString &command)
qDebug() << Q_FUNC_INFO << command;
clearForRun();
updateCodeLevel(); // Step by instruction
m_engine->setState(InferiorRunningRequested, Q_FUNC_INFO, __LINE__);
m_engine->setState(InferiorRunRequested, Q_FUNC_INFO, __LINE__);
m_engine->showMessage(CdbEngine::tr("Continuing with '%1'...").arg(command));
QString errorMessage;
const bool success = executeDebuggerCommand(command, &errorMessage);
if (success) {
m_engine->setState(InferiorRunning, Q_FUNC_INFO, __LINE__);
m_engine->setState(InferiorRunOk, Q_FUNC_INFO, __LINE__);
startWatchTimer();
} else {
m_engine->setState(InferiorStopped, Q_FUNC_INFO, __LINE__);
m_engine->setState(InferiorStopOk, Q_FUNC_INFO, __LINE__);
m_engine->warning(CdbEngine::tr("Unable to continue: %1").arg(errorMessage));
}
return success;
@@ -772,7 +772,7 @@ bool CdbEngine::step(unsigned long executionStatus)
|| threadsHandler()->threads().size() == 1;
m_d->clearForRun(); // clears thread ids
m_d->updateCodeLevel(); // Step by instruction or source line
setState(InferiorRunningRequested, Q_FUNC_INFO, __LINE__);
setState(InferiorRunRequested, Q_FUNC_INFO, __LINE__);
bool success = false;
if (sameThread && executionStatus != CdbExtendedExecutionStatusStepOut) { // Step event-triggering thread, use fast API
const HRESULT hr = m_d->interfaces().debugControl->SetExecutionStatus(executionStatus);
@@ -806,9 +806,9 @@ bool CdbEngine::step(unsigned long executionStatus)
if (executionStatus == DEBUG_STATUS_STEP_INTO || executionStatus == DEBUG_STATUS_REVERSE_STEP_INTO)
m_d->m_breakEventMode = CdbEnginePrivate::BreakEventIgnoreOnce;
m_d->startWatchTimer();
setState(InferiorRunning, Q_FUNC_INFO, __LINE__);
setState(InferiorRunOk, Q_FUNC_INFO, __LINE__);
} else {
setState(InferiorStopped, Q_FUNC_INFO, __LINE__);
setState(InferiorStopOk, Q_FUNC_INFO, __LINE__);
}
if (debugCDBExecution)
qDebug() << "<step samethread" << sameThread << "succeeded" << success;
@@ -879,7 +879,7 @@ bool CdbEnginePrivate::continueInferior(QString *errorMessage)
return true;
}
// Request continue
m_engine->setState(InferiorRunningRequested, Q_FUNC_INFO, __LINE__);
m_engine->setState(InferiorRunRequested, Q_FUNC_INFO, __LINE__);
bool success = false;
do {
clearForRun();
@@ -895,9 +895,9 @@ bool CdbEnginePrivate::continueInferior(QString *errorMessage)
success = true;
} while (false);
if (success) {
m_engine->setState(InferiorRunning, Q_FUNC_INFO, __LINE__);
m_engine->setState(InferiorRunOk, Q_FUNC_INFO, __LINE__);
} else {
m_engine->setState(InferiorStopped, Q_FUNC_INFO, __LINE__); // No RunningRequestFailed?
m_engine->setState(InferiorStopOk, Q_FUNC_INFO, __LINE__); // No RunningRequestFailed?
}
return true;
}
@@ -922,7 +922,7 @@ void CdbEnginePrivate::slotModulesLoaded()
// spawned by the debug handler and inherits the handles,
// the event handling does not work reliably (that is, the crash
// event is not delivered). In that case, force a break
if (m_mode == AttachCrashedExternal && m_engine->state() != InferiorStopped)
if (m_mode == AttachCrashedExternal && m_engine->state() != InferiorStopOk)
QTimer::singleShot(10, m_engine, SLOT(slotBreakAttachToCrashed()));
}
@@ -930,7 +930,7 @@ void CdbEngine::slotBreakAttachToCrashed()
{
// Force a break when attaching to crashed process (if Creator was not spawned
// from handler).
if (state() != InferiorStopped) {
if (state() != InferiorStopOk) {
showMessage(QLatin1String("Forcing break..."));
m_d->m_dumper->disable();
interruptInferior();
@@ -943,7 +943,7 @@ void CdbEngine::interruptInferior()
return;
QString errorMessage;
setState(InferiorStopping, Q_FUNC_INFO, __LINE__);
setState(InferiorStopRequested, Q_FUNC_INFO, __LINE__);
if (!m_d->interruptInterferiorProcess(&errorMessage)) {
setState(InferiorStopFailed, Q_FUNC_INFO, __LINE__);
warning(msgFunctionFailed(Q_FUNC_INFO, errorMessage));
@@ -1022,7 +1022,7 @@ void CdbEngine::activateFrame(int frameIndex)
if (debugCDB)
qDebug() << Q_FUNC_INFO << frameIndex;
if (state() != InferiorStopped) {
if (state() != InferiorStopOk) {
qWarning("WARNING %s: invoked while debuggee is running\n", Q_FUNC_INFO);
return;
}
@@ -1237,7 +1237,7 @@ void CdbEngine::requestModuleSymbols(const QString &moduleName)
void CdbEngine::reloadRegisters()
{
if (state() != InferiorStopped)
if (state() != InferiorStopOk)
return;
const int intBase = 10;
if (debugCDB)
@@ -1272,7 +1272,7 @@ void CdbEngine::slotConsoleStubMessage(const QString &msg, bool)
void CdbEngine::slotConsoleStubTerminated()
{
exitDebugger();
shutdownEngine();
}
void CdbEngine::warning(const QString &msg)
@@ -1331,9 +1331,9 @@ void CdbEnginePrivate::handleDebugEvent()
case BreakEventHandle: {
// If this is triggered by breakpoint/crash: Set state to stopping
// to avoid warnings as opposed to interrupt inferior
if (m_engine->state() != InferiorStopping)
m_engine->setState(InferiorStopping, Q_FUNC_INFO, __LINE__);
m_engine->setState(InferiorStopped, Q_FUNC_INFO, __LINE__);
if (m_engine->state() != InferiorStopRequested)
m_engine->setState(InferiorStopRequested, Q_FUNC_INFO, __LINE__);
m_engine->setState(InferiorStopOk, Q_FUNC_INFO, __LINE__);
// Indicate artifical thread that is created when interrupting as such,
// else use stop message with cleaned newlines and blanks.
const QString currentThreadState =
@@ -1424,7 +1424,7 @@ ULONG CdbEnginePrivate::updateThreadList(const QString &currentThreadState)
ULONG currentThreadId;
QString errorMessage;
// When interrupting, an artifical thread with a breakpoint is created.
const bool stopped = m_engine->state() == InferiorStopped;
const bool stopped = m_engine->state() == InferiorStopOk;
if (!CdbStackTraceContext::getThreads(interfaces(),
stopped,
&threads, &currentThreadId,
+2 -2
View File
@@ -55,12 +55,12 @@ public:
static DebuggerEngine *create(const DebuggerStartParameters &sp,
QString *errorMessage);
virtual void shutdown();
virtual void setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos);
virtual void setupEngine();
virtual void setupInferior();
virtual void runEngine();
virtual void exitDebugger();
virtual void shutdownInferior();
virtual void shutdownEngine();
virtual void detachDebugger();
virtual void updateWatchData(const WatchData &data);
virtual unsigned debuggerCapabilities() const;
+30 -25
View File
@@ -79,29 +79,34 @@ enum DebuggerState
{
DebuggerNotReady, // Debugger not started
EngineSettingUp, // Engine starts
EngineSetupRequested, // Engine starts
EngineSetupFailed,
EngineSetupOk,
InferiorUnrunnable, // Used in the core dump adapter
InferiorSettingUp,
InferiorSetupRequested,
InferiorSetupFailed,
InferiorSetupOk,
InferiorRunningRequested, // Debuggee requested to run
InferiorRunningRequested_Kill, // Debuggee requested to run, but want to kill it
InferiorRunning, // Debuggee running
EngineRunRequested,
EngineRunFailed,
InferiorUnrunnable, // Used in the core dump adapter
InferiorStopping, // Debuggee running, stop requested
InferiorStopping_Kill, // Debuggee running, stop requested, want to kill it
InferiorStopped, // Debuggee stopped
InferiorStopFailed, // Debuggee not stopped, will kill debugger
InferiorRunRequested, // Debuggee requested to run
InferiorRunOk, // Debuggee running
InferiorRunFailed, // Debuggee running
InferiorShuttingDown,
InferiorShutDown,
InferiorStopRequested, // Debuggee running, stop requested
InferiorStopOk, // Debuggee stopped
InferiorStopFailed, // Debuggee not stopped, will kill debugger
InferiorShutdownRequested,
InferiorShutdownOk,
InferiorShutdownFailed,
EngineShuttingDown
EngineShutdownRequested,
EngineShutdownOk,
EngineShutdownFailed,
DebuggerFinished
};
enum DebuggerStartMode
@@ -139,21 +144,21 @@ enum LogChannel
{
LogInput, // Used for user input
LogMiscInput, // Used for misc stuff in the input pane
LogOutput,
LogWarning,
LogError,
LogOutput,
LogWarning,
LogError,
LogStatus, // Used for status changed messages
LogTime, // Used for time stamp messages
LogDebug,
LogMisc,
AppOutput,
AppError,
LogDebug,
LogMisc,
AppOutput,
AppError,
AppStuff,
StatusBar // LogStatus and also put to the status bar
};
enum ModelRoles
{
};
enum ModelRoles
{
DisplaySourceRole = 32, // Qt::UserRole
EngineStateRole,
+354 -97
View File
@@ -88,6 +88,13 @@ using namespace Debugger::Internal;
using namespace ProjectExplorer;
using namespace TextEditor;
//#define DEBUG_STATE 1
#if DEBUG_STATE
# define SDEBUG(s) qDebug() << s
#else
# define SDEBUG(s)
#endif
# define XSDEBUG(s) qDebug() << s
///////////////////////////////////////////////////////////////////////
//
@@ -143,24 +150,27 @@ const char *DebuggerEngine::stateName(int s)
# define SN(x) case x: return #x;
switch (s) {
SN(DebuggerNotReady)
SN(EngineSettingUp)
SN(EngineSetupRequested)
SN(EngineSetupOk)
SN(EngineSetupFailed)
SN(InferiorSettingUp)
SN(EngineRunFailed)
SN(InferiorSetupRequested)
SN(InferiorSetupFailed)
SN(InferiorSetupOk)
SN(InferiorRunningRequested)
SN(InferiorRunningRequested_Kill)
SN(InferiorRunning)
SN(EngineRunRequested)
SN(InferiorRunRequested)
SN(InferiorRunOk)
SN(InferiorRunFailed)
SN(InferiorUnrunnable)
SN(InferiorStopping)
SN(InferiorStopping_Kill)
SN(InferiorStopped)
SN(InferiorStopRequested)
SN(InferiorStopOk)
SN(InferiorStopFailed)
SN(InferiorShuttingDown)
SN(InferiorShutDown)
SN(InferiorShutdownRequested)
SN(InferiorShutdownOk)
SN(InferiorShutdownFailed)
SN(EngineShuttingDown)
SN(EngineShutdownRequested)
SN(EngineShutdownOk)
SN(EngineShutdownFailed)
SN(DebuggerFinished)
}
return "<unknown>";
# undef SN
@@ -208,6 +218,7 @@ public:
m_runControl(0),
m_startParameters(sp),
m_state(DebuggerNotReady),
m_lastGoodState(DebuggerNotReady),
m_breakHandler(engine),
m_commandHandler(engine),
m_modulesHandler(engine),
@@ -227,16 +238,28 @@ public slots:
void doSetupInferior();
void doRunEngine();
void doShutdown();
void doShutdownEngine();
void doShutdownInferior();
void doInterruptInferior();
void doFinishDebugger();
public:
DebuggerState state() const { return m_state; }
DebuggerEngine *m_engine; // Not owned.
DebuggerRunControl *m_runControl; // Not owned.
DebuggerStartParameters m_startParameters;
// The current state.
DebuggerState m_state;
// The state we had before something unexpected happend.
DebuggerState m_lastGoodState;
// The state we are aiming for.
DebuggerState m_targetState;
qint64 m_inferiorPid;
BreakHandler m_breakHandler;
@@ -277,7 +300,7 @@ void DebuggerEnginePrivate::handleContextMenuRequest(const QVariant &parameters)
{
const QList<QVariant> list = parameters.toList();
QTC_ASSERT(list.size() == 3, return);
TextEditor::ITextEditor *editor =
TextEditor::ITextEditor *editor =
(TextEditor::ITextEditor *)(list.at(0).value<quint64>());
int lineNumber = list.at(1).toInt();
QMenu *menu = (QMenu *)(list.at(2).value<quint64>());
@@ -413,7 +436,7 @@ void DebuggerEngine::handleCommand(int role, const QVariant &value)
break;
case RequestExecExitRole:
exitDebugger();
d->doShutdownInferior();
break;
case RequestExecSnapshotRole:
@@ -451,7 +474,7 @@ void DebuggerEngine::handleCommand(int role, const QVariant &value)
QPoint point = list.at(0).value<QPoint>();
TextEditor::ITextEditor *editor = // Eeks.
(TextEditor::ITextEditor *)(list.at(1).value<quint64>());
int pos = list.at(2).toInt();
int pos = list.at(2).toInt();
setToolTipExpression(point, editor, pos);
break;
}
@@ -626,7 +649,7 @@ void DebuggerEngine::startDebugger(DebuggerRunControl *runControl)
d->m_runControl = runControl;
QTC_ASSERT(state() == DebuggerNotReady, setState(DebuggerNotReady));
QTC_ASSERT(state() == DebuggerNotReady, qDebug() << state());
d->m_inferiorPid = d->m_startParameters.attachPID > 0
? d->m_startParameters.attachPID : 0;
@@ -641,7 +664,7 @@ void DebuggerEngine::startDebugger(DebuggerRunControl *runControl)
theDebuggerAction(OperateByInstruction)
->setEnabled(engineCapabilities & DisassemblerCapability);
setState(EngineSettingUp);
setState(EngineSetupRequested);
setupEngine();
}
@@ -905,59 +928,74 @@ DebuggerState DebuggerEngine::state() const
return d->m_state;
}
static bool isAllowedTransition(int from, int to)
DebuggerState DebuggerEngine::lastGoodState() const
{
return d->m_lastGoodState;
}
DebuggerState DebuggerEngine::targetState() const
{
return d->m_targetState;
}
static bool isAllowedTransition(DebuggerState from, DebuggerState to)
{
switch (from) {
case -1:
return to == DebuggerNotReady;
case DebuggerNotReady:
return to == EngineSettingUp || to == DebuggerNotReady;
return to == EngineSetupRequested || to == DebuggerNotReady;
case EngineSettingUp:
case EngineSetupRequested:
return to == EngineSetupOk || to == EngineSetupFailed;
case EngineSetupFailed:
return to == DebuggerNotReady;
case EngineSetupOk:
return to == InferiorSettingUp || to == EngineShuttingDown;
return to == InferiorSetupRequested || to == EngineShutdownRequested;
case InferiorSettingUp:
return to == InferiorSetupOk || to == InferiorSetupFailed;
case InferiorSetupRequested:
return to == EngineRunRequested || to == InferiorSetupFailed;
case InferiorSetupFailed:
return to == EngineShuttingDown;
case InferiorSetupOk:
return to == InferiorRunningRequested || to == InferiorStopped
|| to == InferiorUnrunnable;
return to == EngineShutdownRequested;
case InferiorRunningRequested:
return to == InferiorRunning || to == InferiorStopped
|| to == InferiorRunningRequested_Kill;
case InferiorRunningRequested_Kill:
return to == InferiorRunning || to == InferiorStopped;
case InferiorRunning:
return to == InferiorStopping;
case EngineRunRequested:
return to == InferiorRunRequested || to == InferiorStopRequested
|| to == InferiorUnrunnable || to == EngineRunFailed;
case InferiorStopping:
return to == InferiorStopped || to == InferiorStopFailed
|| to == InferiorStopping_Kill;
case InferiorStopping_Kill:
return to == InferiorStopped || to == InferiorStopFailed;
case InferiorStopped:
return to == InferiorRunningRequested || to == InferiorShuttingDown;
case EngineRunFailed:
return to == InferiorShutdownRequested;
case InferiorRunRequested:
return to == InferiorRunOk || to == InferiorRunFailed;
case InferiorRunFailed:
return to == InferiorStopOk;
case InferiorRunOk:
return to == InferiorStopRequested || to == InferiorStopOk;
case InferiorStopRequested:
return to == InferiorStopOk || to == InferiorStopFailed;
case InferiorStopOk:
return to == InferiorRunRequested || to == InferiorShutdownRequested
|| to == InferiorStopOk;
case InferiorStopFailed:
return to == EngineShuttingDown;
return to == EngineShutdownRequested;
case InferiorUnrunnable:
return to == EngineShuttingDown;
case InferiorShuttingDown:
return to == InferiorShutDown || to == InferiorShutdownFailed;
case InferiorShutDown:
return to == EngineShuttingDown;
return to == InferiorShutdownRequested;
case InferiorShutdownRequested:
return to == InferiorShutdownOk || to == InferiorShutdownFailed;
case InferiorShutdownOk:
return to == EngineShutdownRequested;
case InferiorShutdownFailed:
return to == EngineShuttingDown;
return to == EngineShutdownRequested;
case EngineShuttingDown:
return to == DebuggerNotReady;
case EngineShutdownRequested:
return to == EngineShutdownOk;
case EngineShutdownOk:
return to == DebuggerFinished;
case EngineShutdownFailed:
return to == DebuggerFinished;
case DebuggerFinished:
return false;
}
qDebug() << "UNKNOWN STATE:" << from;
@@ -966,16 +1004,17 @@ static bool isAllowedTransition(int from, int to)
void DebuggerEngine::notifyEngineSetupFailed()
{
QTC_ASSERT(state() == EngineSettingUp, qDebug() << state());
SDEBUG(Q_FUNC_INFO);
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
setState(EngineSetupFailed);
d->m_runControl->debuggingFinished();
d->m_runControl->startFailed();
QTimer::singleShot(0, this, SLOT(doShutdown()));
QTimer::singleShot(0, d, SLOT(doShutdownEngine()));
}
void DebuggerEngine::notifyEngineSetupOk()
{
QTC_ASSERT(state() == EngineSettingUp, qDebug() << state());
SDEBUG(Q_FUNC_INFO);
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
setState(EngineSetupOk);
d->m_runControl->startSuccessful();
QTimer::singleShot(0, d, SLOT(doSetupInferior()));
@@ -983,88 +1022,296 @@ void DebuggerEngine::notifyEngineSetupOk()
void DebuggerEnginePrivate::doSetupInferior()
{
QTC_ASSERT(m_state == EngineSetupOk, qDebug() << m_state);
m_engine->setState(InferiorSettingUp);
SDEBUG(Q_FUNC_INFO);
QTC_ASSERT(state() == EngineSetupOk, qDebug() << state());
m_engine->setState(InferiorSetupRequested);
m_engine->setupInferior();
}
#if 0
// Default implemention, can be overridden.
void DebuggerEngine::setupInferior()
{
QTC_ASSERT(state() == EngineSetupOk, qDebug() << state());
notifyInferiorSetupOk();
}
#endif
void DebuggerEngine::notifyInferiorSetupFailed()
{
QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state());
SDEBUG(Q_FUNC_INFO);
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
setState(InferiorSetupFailed);
QTimer::singleShot(0, d, SLOT(doShutdown()));
QTimer::singleShot(0, d, SLOT(doShutdownEngine()));
}
void DebuggerEngine::notifyInferiorSetupOk()
{
QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state());
setState(InferiorSetupOk);
SDEBUG(Q_FUNC_INFO);
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
setState(EngineRunRequested);
QTimer::singleShot(0, d, SLOT(doRunEngine()));
}
void DebuggerEnginePrivate::doRunEngine()
{
QTC_ASSERT(m_state == InferiorSetupOk, qDebug() << m_state);
SDEBUG(Q_FUNC_INFO);
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
m_engine->runEngine();
}
#if 0
// Default implemention, can be overridden.
void DebuggerEngine::runEngine()
{
QTC_ASSERT(state() == InferiorSetupOk, qDebug() << state());
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
}
#endif
void DebuggerEngine::notifyInferiorUnrunnable()
{
SDEBUG(Q_FUNC_INFO);
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
setState(InferiorUnrunnable);
}
void DebuggerEngine::notifyInferiorRunning()
void DebuggerEngine::notifyEngineRunFailed()
{
QTC_ASSERT(m_state == InferiorRunningRequested, qDebug() << m_state);
setState(InferiorRunning);
SDEBUG(Q_FUNC_INFO);
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
setState(EngineRunFailed);
QTimer::singleShot(0, d, SLOT(doShutdownInferior()));
}
void DebuggerEngine::notifyInferiorStopped()
void DebuggerEngine::notifyEngineRunAndInferiorRunOk()
{
QTC_ASSERT(m_state == InferiorRunningStoppint, qDebug() << m_state);
setState(InferiorStopped);
SDEBUG(Q_FUNC_INFO);
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
setState(InferiorRunRequested);
notifyInferiorRunOk();
}
void DebuggerEngine::notifyEngineRunAndInferiorStopOk()
{
SDEBUG(Q_FUNC_INFO);
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
setState(InferiorStopRequested);
notifyInferiorStopOk();
}
void DebuggerEngine::notifyInferiorRunRequested()
{
SDEBUG(Q_FUNC_INFO);
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
setState(InferiorRunRequested);
}
void DebuggerEngine::notifyInferiorRunOk()
{
SDEBUG(Q_FUNC_INFO);
QTC_ASSERT(state() == InferiorRunRequested, qDebug() << state());
setState(InferiorRunOk);
}
/*
void DebuggerEngine::notifyInferiorSpontaneousRun()
{
SDEBUG(Q_FUNC_INFO);
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
setState(InferiorRunRequested);
setState(InferiorRunOk);
}
*/
void DebuggerEngine::notifyInferiorRunFailed()
{
XSDEBUG(Q_FUNC_INFO);
qDebug() << "NOTIFY_INFERIOR_RUN_FAILED";
QTC_ASSERT(state() == InferiorRunRequested, qDebug() << state());
setState(InferiorRunFailed);
setState(InferiorStopOk);
if (isDying()) {
QTimer::singleShot(0, d, SLOT(doShutdownInferior()));
}
}
void DebuggerEngine::notifyInferiorStopOk()
{
SDEBUG(Q_FUNC_INFO);
if (isDying()) {
showMessage(_("STOPPED WHILE DYING. CONTINUING SHUTDOWN."));
setState(InferiorStopOk);
QTimer::singleShot(0, d, SLOT(doShutdownInferior()));
} else {
QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state());
setState(InferiorStopOk);
}
}
void DebuggerEngine::notifyInferiorSpontaneousStop()
{
SDEBUG(Q_FUNC_INFO);
QTC_ASSERT(state() == InferiorRunOk, qDebug() << state());
setState(InferiorStopOk);
}
void DebuggerEngine::notifyInferiorStopFailed()
{
SDEBUG(Q_FUNC_INFO);
QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state());
setState(InferiorStopFailed);
QTimer::singleShot(0, d, SLOT(doShutdownEngine()));
}
void DebuggerEnginePrivate::doInterruptInferior()
{
QTC_ASSERT(m_state == InferiorRunning, qDebug() << m_state);
SDEBUG(Q_FUNC_INFO);
QTC_ASSERT(state() == InferiorRunOk, qDebug() << state());
m_engine->setState(InferiorStopRequested);
m_engine->interruptInferior();
}
void DebuggerEnginePrivate::doShutdown()
void DebuggerEnginePrivate::doShutdownInferior()
{
m_engine->shutdown();
SDEBUG(Q_FUNC_INFO);
qDebug() << "DO_SHUTDOWN_INFERIOR";
m_engine->resetLocation();
m_targetState = DebuggerFinished;
m_engine->setState(InferiorShutdownRequested);
m_engine->shutdownInferior();
}
void DebuggerEngine::notifyInferiorShutdownOk()
{
SDEBUG(Q_FUNC_INFO);
QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state());
showMessage(_("INFERIOR SUCCESSFULLY SHUT DOWN"));
d->m_lastGoodState = DebuggerNotReady; // A "neutral" value.
setState(InferiorShutdownOk);
QTimer::singleShot(0, d, SLOT(doShutdownEngine()));
}
void DebuggerEngine::notifyInferiorShutdownFailed()
{
SDEBUG(Q_FUNC_INFO);
QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state());
showMessage(_("INFERIOR SHUTDOWN FAILED"));
setState(InferiorShutdownFailed);
QTimer::singleShot(0, d, SLOT(doShutdownEngine()));
}
void DebuggerEngine::notifyInferiorIll()
{
SDEBUG(Q_FUNC_INFO);
// This can be issued in almost any state. The inferior could still be
// alive as some previous notifications might have been bogus.
qDebug() << "SOMETHING IS WRONG WITH THE INFERIOR";
d->m_targetState = DebuggerFinished;
d->m_lastGoodState = d->m_state;
if (state() == InferiorRunRequested) {
// We asked for running, but did not see a response.
// Assume the inferior is dead.
// FIXME: Use timeout?
setState(InferiorRunFailed);
setState(InferiorStopOk);
}
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
QTimer::singleShot(0, d, SLOT(doShutdownInferior()));
}
void DebuggerEnginePrivate::doShutdownEngine()
{
SDEBUG(Q_FUNC_INFO);
QTC_ASSERT(state() == InferiorShutdownOk
|| state() == InferiorShutdownFailed, qDebug() << state());
m_targetState = DebuggerFinished;
m_engine->setState(EngineShutdownRequested);
m_engine->shutdownEngine();
}
void DebuggerEngine::notifyEngineShutdownOk()
{
SDEBUG(Q_FUNC_INFO);
QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state());
showMessage(_("ENGINE SUCCESSFULLY SHUT DOWN"));
setState(EngineShutdownOk);
QTimer::singleShot(0, d, SLOT(doFinishDebugger()));
}
void DebuggerEngine::notifyEngineShutdownFailed()
{
SDEBUG(Q_FUNC_INFO);
showMessage(_("ENGINE SHUTDOWN FAILED"));
QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state());
setState(EngineShutdownFailed);
QTimer::singleShot(0, d, SLOT(doFinishDebugger()));
}
void DebuggerEnginePrivate::doFinishDebugger()
{
SDEBUG(Q_FUNC_INFO);
QTC_ASSERT(state() == EngineShutdownOk
|| state() == EngineShutdownFailed, qDebug() << state());
m_engine->resetLocation();
m_engine->setState(DebuggerFinished);
m_runControl->debuggingFinished();
}
void DebuggerEngine::notifyEngineIll()
{
SDEBUG(Q_FUNC_INFO);
qDebug() << "SOMETHING IS WRONG WITH THE ENGINE";
d->m_targetState = DebuggerFinished;
d->m_lastGoodState = d->m_state;
if (state() == InferiorStopOk) {
QTimer::singleShot(0, d, SLOT(doShutdownInferior()));
} else {
QTimer::singleShot(0, d, SLOT(doShutdownEngine()));
}
}
void DebuggerEngine::notifyEngineSpontaneousShutdown()
{
SDEBUG(Q_FUNC_INFO);
qDebug() << "THE ENGINE SUDDENLY DIED";
setState(EngineShutdownOk, true);
QTimer::singleShot(0, d, SLOT(doFinishDebugger()));
}
void DebuggerEngine::notifyInferiorExited()
{
XSDEBUG("NOTIFY_INFERIOR_EXIT");
resetLocation();
// This can be issued in almost any state. We assume, though,
// that at this point of time the inferior is not running anymore,
// even if stop notification were not issued or got lost.
if (state() == InferiorRunOk) {
setState(InferiorStopRequested);
setState(InferiorStopOk);
}
setState(InferiorShutdownRequested);
setState(InferiorShutdownOk);
QTimer::singleShot(0, d, SLOT(doShutdownEngine()));
}
void DebuggerEngine::setState(DebuggerState state, bool forced)
{
//qDebug() << "STATUS CHANGE: FROM " << stateName(d->m_state)
// << " TO " << stateName(state);
SDEBUG(Q_FUNC_INFO);
qDebug() << "STATUS CHANGE: FROM " << stateName(d->m_state)
<< " TO " << stateName(state);
DebuggerState oldState = d->m_state;
d->m_state = state;
QString msg = _("State changed from %1(%2) to %3(%4).")
.arg(stateName(oldState)).arg(oldState).arg(stateName(state)).arg(state);
QString msg = _("State changed%5 from %1(%2) to %3(%4).")
.arg(stateName(oldState)).arg(oldState).arg(stateName(state)).arg(state)
.arg(forced ? " BY FORCE" : "");
if (!forced && !isAllowedTransition(oldState, state))
qDebug() << "UNEXPECTED STATE TRANSITION: " << msg;
showMessage(msg, LogDebug);
plugin()->updateState(this);
if (state != oldState) {
if (state == DebuggerNotReady) {
d->m_runControl->debuggingFinished();
}
}
}
bool DebuggerEngine::debuggerActionsEnabled() const
@@ -1075,26 +1322,29 @@ bool DebuggerEngine::debuggerActionsEnabled() const
bool DebuggerEngine::debuggerActionsEnabled(DebuggerState state)
{
switch (state) {
case InferiorSettingUp:
case InferiorRunningRequested:
case InferiorRunning:
case InferiorSetupRequested:
case InferiorRunOk:
case InferiorUnrunnable:
case InferiorStopping:
case InferiorStopped:
case InferiorStopOk:
return true;
case InferiorStopRequested:
case InferiorRunRequested:
case InferiorRunFailed:
case DebuggerNotReady:
case EngineSettingUp:
case EngineSetupRequested:
case EngineSetupOk:
case EngineSetupFailed:
case InferiorSetupOk:
case EngineRunRequested:
case EngineRunFailed:
case InferiorSetupFailed:
case InferiorRunningRequested_Kill:
case InferiorStopping_Kill:
case InferiorStopFailed:
case InferiorShuttingDown:
case InferiorShutDown:
case InferiorShutdownRequested:
case InferiorShutdownOk:
case InferiorShutdownFailed:
case EngineShuttingDown:
case EngineShutdownRequested:
case EngineShutdownOk:
case EngineShutdownFailed:
case DebuggerFinished:
return false;
}
return false;
@@ -1133,6 +1383,13 @@ bool DebuggerEngine::isReverseDebugging() const
return plugin()->isReverseDebugging();
}
// called by DebuggerRunControl
void DebuggerEngine::quitDebugger()
{
qDebug() << "QUIT_DEBUGGER";
shutdownInferior();
}
} // namespace Internal
} // namespace Debugger
+32 -10
View File
@@ -121,7 +121,6 @@ public:
DebuggerEngine(const DebuggerStartParameters &sp);
virtual ~DebuggerEngine();
virtual void shutdown() {}
virtual void setToolTipExpression(const QPoint & /* mousePos */,
TextEditor::ITextEditor * /* editor */, int /* cursorPos */) { }
void initializeFromTemplate(DebuggerEngine *other);
@@ -164,8 +163,6 @@ public:
{ Q_UNUSED(expr); Q_UNUSED(value); }
protected:
virtual void setupEngine() {}
virtual void exitDebugger() {}
virtual void detachDebugger() {}
virtual void executeStep() {}
virtual void executeStepOut() {}
@@ -229,6 +226,9 @@ public:
void executeReturnX();
DebuggerState state() const;
DebuggerState lastGoodState() const;
DebuggerState targetState() const;
bool isDying() const { return targetState() == DebuggerFinished; }
// Dumper stuff (common to cdb and gdb).
bool qtDumperLibraryEnabled() const;
@@ -251,24 +251,46 @@ public:
void openFile(const QString &fileName, int lineNumber = -1);
void gotoLocation(const QString &fileName, int lineNumber, bool setMarker);
void gotoLocation(const StackFrame &frame, bool setMarker);
void raiseApplication();
virtual void quitDebugger() { exitDebugger(); } // called by DebuggerRunControl
Q_SLOT void raiseApplication();
virtual void quitDebugger(); // called by DebuggerRunControl
protected:
void notifyEngineSetupOk();
void notifyEngineSetupFailed();
void notifyEngineRunFailed();
void notifyInferiorSetupOk();
void notifyInferiorSetupFailed();
void notifyInferiorRunning();
void notifyInferiorStopped();
void notifyEngineRunAndInferiorRunOk();
void notifyEngineRunAndInferiorStopOk();
void notifyInferiorUnrunnable(); // Called by CoreAdapter.
//void notifyInferiorSpontaneousRun();
void notifyInferiorRunRequested();
void notifyInferiorRunOk();
void notifyInferiorRunFailed();
void notifyInferiorStopOk();
void notifyInferiorSpontaneousStop();
void notifyInferiorStopFailed();
void notifyInferiorExited();
void notifyInferiorShutdownOk();
void notifyInferiorShutdownFailed();
void notifyEngineSpontaneousShutdown();
void notifyEngineShutdownOk();
void notifyEngineShutdownFailed();
// Called to initiate shutdown.
void notifyInferiorIll();
void notifyEngineIll();
virtual void setupInferior();
virtual void runEngine();
virtual void setupEngine() = 0;
virtual void setupInferior() = 0;
virtual void runEngine() = 0;
virtual void shutdownInferior() = 0;
virtual void shutdownEngine() = 0;
//private: // FIXME. State transitions
void setState(DebuggerState state, bool forced = false);
+148 -85
View File
@@ -162,91 +162,148 @@
//
// Transitions marked by '---' are done in the individual engines.
// Transitions marked by '+-+' are done in the base DebuggerEngine.
// Transitions marked by '*' are done asynchronously.
// The GdbEngine->setupEngine() function is described in more detail below.
//
// DebuggerNotReady
// +
// +
// EngineSettingUp
// +
// +
// (calls *Engine->setupEngine())
// | |
// {notify- {notify-
// Engine- Engine-
// StartOk} StartFailed}
// | |
// | `---> EngineSetupFailed
// | +
// | [calls RunControl->startFailed]
// | +
// | DebuggerNotReady
// v
// EngineSetupOk
// +
// [calls RunControl->StartSuccessful]
// +
// (calls *Engine->setupInferior())
// | |
// {notify- {notify-
// Inferior- Inferior-
// SetupOk} SetupFailed}
// | |
// | ` ----> InferiorSetupFailed +-+-+-+->.
// | +
// v +
// InferiorSetupOk +
// + +
// (calls *Engine->runEngine()) +
// | +
// (core) | (attach) (term) (remote) (script) +
// .-----------------<-|->------------------. +
// | v | +
// InferiorUnrunnable | (plain) | +
// | | (trk) | +
// | | | +
// | .--> InferiorRunningRequested | +
// | | | | +
// | | InferiorRunning | +
// | | | | +
// | | InferiorStopping | +
// | | | | +
// | '------ InferiorStopped <-----------' +
// | | v
// | InferiorShuttingDown -> InferiorShutdownFailed ---->+
// | | +
// | InferiorShutDown +
// | | +
// '--------> EngineShuttingDown <-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+'
// |
// DebuggerNotReady
// DebuggerNotReady
// +
// EngineSetupRequested
// +
// (calls *Engine->setupEngine())
// | |
// {notify- {notify-
// Engine- Engine-
// SetupOk} SetupFailed}
// | |
// | `---> EngineSetupFailed
// | +
// | [calls RunControl->startFailed]
// | +
// | DebuggerNotReady
// v
// EngineSetupOk
// +
// [calls RunControl->StartSuccessful]
// +
// InferiorSetupRequested
// +
// (calls *Engine->setupInferior())
// | |
// | |
// {notify- {notify-
// Inferior- Inferior-
// SetupOk} SetupFailed}
// + +
// + ` +-+-> InferiorSetupFailed +-+-+-+-+-+->.
// + +
// + +
// EngineRunRequested +
// + +
// (calls *Engine->runEngine()) +
// / | | \ +
// / | | \ +
// | (core) | (attach) | | +
// | | | | +
// {notify- {notifyER&- {notifyER&- {notify- +
// Inferior- Inferior- Inferior- RunEngine- +
// Unrunnable} StopOk} RunOk} Failed} +
// + + + + +
// InferiorUnrunnable + InferiorRunOk + +
// + + +
// InferiorStopOk EngineRunFailed +
// + v
// `-+-+-+-+-+-+-+-+-+-+-+>-+
// +
// .--- #SpontaneousStop@InferiorRunOk# +
// | +
// | +
// | #Interupt@InferiorRunOk# +
// | + +
// | InferiorStopRequested +
// | + +
// | (calls *Engine-> +
// | interruptInferior()) +
// | | | +
// {notify- {notify- {notify- +
// Sponta.Inf. Inferior- Inferior- +
// StopOk} StopOk} StopFailed} +
// + + + +
// + + + +
// InferiorStopOk + +
// + +
// + +
// + +
// #Stop@InferiorUnrunnable# + +
// #Creator Close Event# + +
// + + +
// InferiorShutdownRequested +
// + +
// (calls *Engine->shutdownInferior()) +
// | | +
// {notify- {notify- +
// Inferior- Inferior- +
// ShutdownOk} ShutdownFailed} +
// + + +
// + + +
// #Inferior exited# + + +
// | + + +
// {notifyInferior- + + +
// Exited} + + +
// + + + +
// + + + +
// + + + +
// InferiorShutdownOk InferiorShutdownFailed +
// * * +
// EngineShutdownRequested +
// + +
// (calls *Engine->shutdownEngine()) <+-+-+-+-+-+-+-+-+-+-+-+-+-+'
// | |
// {notify- {notify-
// Inferior- Inferior-
// ShutdownOk} ShutdownFailed}
// + +
// EngineShutdownOk EngineShutdownFailed
// * *
// DebuggerFinished
//
// GdbEngine specific startup. All happens in EngineSettingUp state
//(attach) | (plain)
//(term) | (trk)
//(remote) |
//(script) |
//(pdb) |
// GdbEngine specific startup. All happens in EngineSetupRequested state
//
// Transitions marked by '---' are done in the individual adapters.
// Transitions marked by '+-+' are done in the GdbEngine.
//
// GdbEngine::setupEngine()
// +
// +
// (calls *Adapter->startAdapter())
// | |
// | `---> handleAdapterStartFailed()
// | +
// | EngineSetupFailed
// | {notifyEngineSetupFailed}
// |
// handleAdapterStarted()
// +
// {notifyEngineSetupOk}
//
//
//
// GdbEngine::setupInferior()
// +
// (calls *Adapter->prepareInferior())
// | |
// | `---> handleAdapterStartFailed()
// | `---> handlePrepareInferiorFailed()
// | +
// | EngineSetupFailed
// | {notifyInferiorSetupFailed}
// |
// handleInferiorPrepared()
// handleInferiorPrepared()
// +
// EngineSetupOk
// {notifyInferiorSetupOk}
@@ -775,6 +832,12 @@ class SessionEngine : public DebuggerEngine
public:
SessionEngine() : DebuggerEngine(DebuggerStartParameters()) {}
void setupEngine() {}
void setupInferior() {}
void runEngine() {}
void shutdownEngine() {}
void shutdownInferior() {}
bool isSessionEngine() const { return true; }
void loadSessionData()
@@ -2080,7 +2143,7 @@ void DebuggerPluginPrivate::setInitialState()
theDebuggerAction(RecheckDebuggingHelpers)->setEnabled(false);
theDebuggerAction(AutoDerefPointers)->setEnabled(true);
theDebuggerAction(ExpandStack)->setEnabled(false);
theDebuggerAction(ExecuteCommand)->setEnabled(m_state == InferiorStopped);
theDebuggerAction(ExecuteCommand)->setEnabled(m_state == InferiorStopOk);
//emit m_plugin->stateChanged(m_state);
}
@@ -2099,7 +2162,7 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
m_state = engine->state();
bool actionsEnabled = DebuggerEngine::debuggerActionsEnabled(m_state);
//if (m_state == InferiorStopped)
//if (m_state == InferiorStopOk)
// resetLocation();
//qDebug() << "PLUGIN SET STATE: " << m_state;
@@ -2108,20 +2171,20 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
cleanupViews();
}
const bool startIsContinue = (m_state == InferiorStopped);
const bool startIsContinue = (m_state == InferiorStopOk);
ICore *core = ICore::instance();
if (startIsContinue)
core->updateAdditionalContexts(Core::Context(), m_gdbRunningContext);
else
core->updateAdditionalContexts(m_gdbRunningContext, Core::Context());
const bool started = m_state == InferiorRunning
|| m_state == InferiorRunningRequested
|| m_state == InferiorStopping
|| m_state == InferiorStopped;
const bool started = m_state == InferiorRunOk
|| m_state == InferiorRunRequested
|| m_state == InferiorStopRequested
|| m_state == InferiorStopOk;
const bool starting = m_state == EngineSettingUp;
//const bool running = m_state == InferiorRunning;
const bool starting = m_state == EngineSetupRequested;
//const bool running = m_state == InferiorRunOk;
m_startExternalAction->setEnabled(!started && !starting);
m_attachExternalAction->setEnabled(!started && !starting);
@@ -2132,21 +2195,21 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
#endif
m_startRemoteAction->setEnabled(!started && !starting);
const bool detachable = m_state == InferiorStopped
const bool detachable = m_state == InferiorStopOk
&& engine->startParameters().startMode != AttachCore;
m_detachAction->setEnabled(detachable);
const bool stoppable = m_state == InferiorRunning
|| m_state == InferiorRunningRequested
|| m_state == InferiorStopping
|| m_state == InferiorStopped
const bool stoppable = m_state == InferiorRunOk
|| m_state == InferiorRunRequested
|| m_state == InferiorStopRequested
|| m_state == InferiorStopOk
|| m_state == InferiorUnrunnable;
const bool running = m_state == InferiorRunning;
const bool running = m_state == InferiorRunOk;
// FIXME ABC
// if (running)
// threadsHandler()->notifyRunning();
const bool stopped = m_state == InferiorStopped;
const bool stopped = m_state == InferiorStopOk;
if (stopped)
QApplication::alert(mainWindow(), 3000);
@@ -2192,9 +2255,9 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
&& (m_capabilities & AutoDerefPointersCapability);
theDebuggerAction(AutoDerefPointers)->setEnabled(canDeref);
theDebuggerAction(ExpandStack)->setEnabled(actionsEnabled);
theDebuggerAction(ExecuteCommand)->setEnabled(m_state == InferiorStopped);
theDebuggerAction(ExecuteCommand)->setEnabled(m_state == InferiorStopOk);
const bool notbusy = m_state == InferiorStopped
const bool notbusy = m_state == InferiorStopOk
|| m_state == DebuggerNotReady
|| m_state == InferiorUnrunnable;
setBusyCursor(!notbusy);
@@ -2317,7 +2380,7 @@ void DebuggerPluginPrivate::aboutToSaveSession()
void DebuggerPluginPrivate::interruptDebuggingRequest()
{
if (state() == InferiorRunning)
if (state() == InferiorRunOk)
notifyCurrentEngine(RequestExecInterruptRole);
else
exitDebugger();
@@ -2690,8 +2753,8 @@ bool DebuggerListener::coreAboutToClose()
case EngineSetupFailed: // debuggee can cause problems.
case InferiorUnrunnable:
case InferiorSetupFailed:
case InferiorStopped:
case InferiorShutDown:
case InferiorStopOk:
case InferiorShutdownOk:
cleanTermination = true;
break;
default:
@@ -39,7 +39,7 @@ namespace Debugger {
namespace Internal {
AbstractGdbAdapter::AbstractGdbAdapter(GdbEngine *engine, QObject *parent)
: QObject(parent), m_engine(engine)
: QObject(parent), m_engine(engine)
{
}
@@ -48,19 +48,20 @@ AbstractGdbAdapter::~AbstractGdbAdapter()
disconnect();
}
void AbstractGdbAdapter::shutdown()
{
}
//void AbstractGdbAdapter::shutdown()
//{
//}
void AbstractGdbAdapter::runAdapter()
{
qDebug() << "START INFERIOR PHASE 2";
}
//void AbstractGdbAdapter::runEngine()
//{
//}
/*
const char *AbstractGdbAdapter::inferiorShutdownCommand() const
{
return "kill";
}
*/
void AbstractGdbAdapter::write(const QByteArray &data)
{
@@ -87,7 +88,7 @@ QString AbstractGdbAdapter::msgInferiorSetupOk()
return tr("Application started");
}
QString AbstractGdbAdapter::msgInferiorRunning()
QString AbstractGdbAdapter::msgInferiorRunOk()
{
return tr("Application running");
}
@@ -65,10 +65,11 @@ public:
virtual void startAdapter() = 0;
virtual void setupInferior() = 0;
virtual void runAdapter();
virtual void runEngine() = 0;
virtual void interruptInferior() = 0;
virtual void shutdown();
virtual const char *inferiorShutdownCommand() const;
virtual void shutdownInferior() = 0;
virtual void shutdownAdapter() = 0;
//virtual const char *inferiorShutdownCommand() const;
virtual AbstractGdbProcess *gdbProc() = 0;
virtual DumperHandling dumperHandling() const = 0;
@@ -77,7 +78,7 @@ public:
static QString msgInferiorStopFailed(const QString &why);
static QString msgAttachedToStoppedInferior();
static QString msgInferiorSetupOk();
static QString msgInferiorRunning();
static QString msgInferiorRunOk();
static QString msgConnectRemoteServerFailed(const QString &why);
// Trk specific stuff
@@ -49,7 +49,7 @@ AbstractPlainGdbAdapter::AbstractPlainGdbAdapter(GdbEngine *engine,
void AbstractPlainGdbAdapter::setupInferior()
{
QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state());
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
if (!startParameters().processArgs.isEmpty()) {
QString args = startParameters().processArgs.join(_(" "));
m_engine->postCommand("-exec-arguments " + toLocalEncoding(args));
@@ -60,7 +60,7 @@ void AbstractPlainGdbAdapter::setupInferior()
void AbstractPlainGdbAdapter::handleFileExecAndSymbols(const GdbResponse &response)
{
QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state());
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
if (response.resultClass == GdbResultDone) {
if (infoTargetNecessary()) {
// Old gdbs do not announce the PID for programs without pthreads.
@@ -76,31 +76,33 @@ void AbstractPlainGdbAdapter::handleFileExecAndSymbols(const GdbResponse &respon
// Extend the message a bit in unknown cases.
if (!ba.endsWith("File format not recognized"))
msg = tr("Starting executable failed:\n") + msg;
m_engine->handleInferiorSetupFailed(msg);
m_engine->notifyInferiorSetupFailed(msg);
}
}
void AbstractPlainGdbAdapter::runAdapter()
void AbstractPlainGdbAdapter::runEngine()
{
setState(InferiorRunningRequested);
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
m_engine->postCommand("-exec-run", GdbEngine::RunRequest, CB(handleExecRun));
}
void AbstractPlainGdbAdapter::handleExecRun(const GdbResponse &response)
{
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
if (response.resultClass == GdbResultRunning) {
QTC_ASSERT(state() == InferiorRunning, qDebug() << state());
m_engine->notifyEngineRunAndInferiorRunOk();
//showStatusMessage(tr("Running..."));
showMessage(_("INFERIOR STARTED"));
showMessage(msgInferiorSetupOk(), StatusBar);
// FIXME: That's the wrong place for it.
if (theDebuggerBoolSetting(EnableReverseDebugging))
m_engine->postCommand("target record");
} else {
QTC_ASSERT(state() == InferiorRunningRequested, qDebug() << state());
QString msg = fromLocalEncoding(response.data.findChild("msg").data());
//QTC_ASSERT(status() == InferiorRunning, /**/);
//QTC_ASSERT(status() == InferiorRunOk, /**/);
//interruptInferior();
m_engine->handleInferiorSetupFailed(msg);
showMessage(msg);
m_engine->notifyEngineRunFailed();
}
}
@@ -118,10 +120,10 @@ void AbstractPlainGdbAdapter::handleInfoTarget(const GdbResponse &response)
m_engine->postCommand("tbreak *0x" + needle.cap(1).toAscii());
// Do nothing here - inferiorPrepared handles the sequencing.
} else {
m_engine->handleInferiorSetupFailed(_("Parsing start address failed"));
m_engine->notifyInferiorSetupFailed(_("Parsing start address failed"));
}
} else if (response.resultClass == GdbResultError) {
m_engine->handleInferiorSetupFailed(_("Fetching start address failed"));
m_engine->notifyInferiorSetupFailed(_("Fetching start address failed"));
}
}
@@ -36,13 +36,15 @@ namespace Debugger {
namespace Internal {
class AbstractPlainGdbAdapter : public AbstractGdbAdapter
{ // Needs tr - context
{
// Needs tr - context
Q_OBJECT
public:
AbstractPlainGdbAdapter(GdbEngine *engine, QObject *parent = 0);
virtual void setupInferior();
virtual void runAdapter();
void setupInferior();
void runEngine();
protected:
void handleInfoTarget(const GdbResponse &response);
+24 -6
View File
@@ -56,7 +56,7 @@ AttachGdbAdapter::AttachGdbAdapter(GdbEngine *engine, QObject *parent)
void AttachGdbAdapter::startAdapter()
{
QTC_ASSERT(state() == EngineSettingUp, qDebug() << state());
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
showMessage(_("TRYING TO START ADAPTER"));
if (!m_engine->startGdb())
@@ -67,34 +67,52 @@ void AttachGdbAdapter::startAdapter()
void AttachGdbAdapter::setupInferior()
{
QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state());
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
const qint64 pid = startParameters().attachPID;
m_engine->postCommand("attach " + QByteArray::number(pid), CB(handleAttach));
// Task 254674 does not want to remove them
//qq->breakHandler()->removeAllBreakpoints();
}
void AttachGdbAdapter::runEngine()
{
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
m_engine->notifyInferiorStopOk();
}
void AttachGdbAdapter::handleAttach(const GdbResponse &response)
{
QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state());
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
if (response.resultClass == GdbResultDone) {
setState(InferiorStopped);
showMessage(_("INFERIOR ATTACHED"));
showMessage(msgAttachedToStoppedInferior(), StatusBar);
m_engine->handleInferiorPrepared();
m_engine->updateAll();
} else {
QString msg = QString::fromLocal8Bit(response.data.findChild("msg").data());
m_engine->handleInferiorSetupFailed(msg);
m_engine->notifyInferiorSetupFailed(msg);
}
}
void AttachGdbAdapter::interruptInferior()
{
QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state(); return);
const qint64 pid = startParameters().attachPID;
QTC_ASSERT(pid > 0, return);
if (!interruptProcess(pid))
if (!interruptProcess(pid)) {
showMessage(_("CANNOT INTERRUPT %1").arg(pid));
m_engine->notifyInferiorStopFailed();
}
}
void AttachGdbAdapter::shutdownInferior()
{
m_engine->defaultInferiorShutdown("detach");
}
void AttachGdbAdapter::shutdownAdapter()
{
m_engine->notifyAdapterShutdownOk();
}
} // namespace Internal
+6 -4
View File
@@ -50,15 +50,17 @@ class AttachGdbAdapter : public AbstractGdbAdapter
public:
AttachGdbAdapter(GdbEngine *engine, QObject *parent = 0);
virtual DumperHandling dumperHandling() const { return DumperLoadedByGdb; }
private:
DumperHandling dumperHandling() const { return DumperLoadedByGdb; }
void startAdapter();
void setupInferior();
void runEngine();
void interruptInferior();
const char *inferiorShutdownCommand() const { return "detach"; }
AbstractGdbProcess *gdbProc() { return &m_gdbProc; }
void shutdownInferior();
void shutdownAdapter();
private:
AbstractGdbProcess *gdbProc() { return &m_gdbProc; }
void handleAttach(const GdbResponse &response);
LocalGdbProcess m_gdbProc;
@@ -574,7 +574,7 @@ void GdbEngine::updateAllClassic()
{
PRECONDITION;
PENDING_DEBUG("UPDATING ALL\n");
QTC_ASSERT(state() == InferiorUnrunnable || state() == InferiorStopped, /**/);
QTC_ASSERT(state() == InferiorUnrunnable || state() == InferiorStopOk, /**/);
tryLoadDebuggingHelpersClassic();
reloadModulesInternal();
postCommand("-stack-list-frames", WatchUpdate,
+19 -9
View File
@@ -59,7 +59,7 @@ CoreGdbAdapter::CoreGdbAdapter(GdbEngine *engine, QObject *parent)
void CoreGdbAdapter::startAdapter()
{
QTC_ASSERT(state() == EngineSettingUp, qDebug() << state());
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
showMessage(_("TRYING TO START ADAPTER"));
if (!m_engine->startGdb())
@@ -70,7 +70,7 @@ void CoreGdbAdapter::startAdapter()
void CoreGdbAdapter::setupInferior()
{
QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state());
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
m_executable = startParameters().executable;
if (m_executable.isEmpty()) {
#ifdef EXE_FROM_CORE
@@ -103,7 +103,7 @@ void CoreGdbAdapter::loadExeAndSyms()
void CoreGdbAdapter::handleFileExecAndSymbols(const GdbResponse &response)
{
QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state());
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
if (response.resultClass == GdbResultDone) {
showMessage(tr("Symbols found."), StatusBar);
} else {
@@ -124,7 +124,7 @@ void CoreGdbAdapter::loadCoreFile()
void CoreGdbAdapter::handleTargetCore(const GdbResponse &response)
{
QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state());
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
if (response.resultClass == GdbResultDone) {
#ifdef EXE_FROM_CORE
if (m_round == 1) {
@@ -160,22 +160,32 @@ void CoreGdbAdapter::handleTargetCore(const GdbResponse &response)
} else {
QString msg = tr("Attach to core \"%1\" failed:\n").arg(startParameters().coreFile)
+ QString::fromLocal8Bit(response.data.findChild("msg").data());
m_engine->handleInferiorSetupFailed(msg);
m_engine->notifyInferiorSetupFailed(msg);
}
}
void CoreGdbAdapter::runAdapter()
void CoreGdbAdapter::runEngine()
{
QTC_ASSERT(state() == InferiorSetupOk, qDebug() << state());
setState(InferiorUnrunnable);
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
m_engine->notifyInferiorUnrunnable();
m_engine->updateAll();
}
void CoreGdbAdapter::interruptInferior()
{
// A core should never 'run'
// A core never runs, so this cannot be called.
QTC_ASSERT(false, /**/);
}
void CoreGdbAdapter::shutdownInferior()
{
m_engine->notifyInferiorShutdownOk();
}
void CoreGdbAdapter::shutdownAdapter()
{
m_engine->notifyAdapterShutdownOk();
}
} // namespace Internal
} // namespace Debugger
+3 -1
View File
@@ -59,8 +59,10 @@ private:
void startAdapter();
void setupInferior();
void runAdapter();
void runEngine();
void interruptInferior();
void shutdownInferior();
void shutdownAdapter();
AbstractGdbProcess *gdbProc() { return &m_gdbProc; }
File diff suppressed because it is too large Load Diff
+8 -3
View File
@@ -110,10 +110,10 @@ private: ////////// General Interface //////////
virtual void runEngine();
virtual unsigned debuggerCapabilities() const;
virtual void exitDebugger();
virtual void quitDebugger();
virtual void detachDebugger();
virtual void shutdown();
virtual void shutdownEngine();
virtual void shutdownInferior();
virtual void executeDebuggerCommand(const QString &command);
virtual QString qtNamespace() const { return m_dumperHelper.qtNamespace(); }
@@ -136,6 +136,7 @@ private: ////////// Gdb Process Management //////////
void handleGdbExit(const GdbResponse &response);
void handleAdapterStarted();
void defaultInferiorShutdown(const char *cmd);
// Something went wrong with the adapter *before* adapterStarted() was emitted.
// Make sure to clean up everything before emitting this signal.
@@ -149,7 +150,10 @@ private: ////////// Gdb Process Management //////////
void finishInferiorSetup();
// The adapter is still running just fine, but it failed to acquire a debuggee.
void handleInferiorSetupFailed(const QString &msg);
void notifyInferiorSetupFailed(const QString &msg);
void notifyAdapterShutdownOk();
void notifyAdapterShutdownFailed();
// Something went wrong with the adapter *after* adapterStarted() was emitted.
// Make sure to clean up everything before emitting this signal.
@@ -530,6 +534,7 @@ private: ////////// View & Data Stuff //////////
int buttons = 0);
QMainWindow *mainWindow() const;
AbstractGdbProcess *gdbProc() const;
void showExecutionError(const QString &message);
static QString m_toolTipExpression;
static QPoint m_toolTipPos;
@@ -68,7 +68,7 @@ AbstractGdbAdapter::DumperHandling LocalPlainGdbAdapter::dumperHandling() const
void LocalPlainGdbAdapter::startAdapter()
{
QTC_ASSERT(state() == EngineSettingUp, qDebug() << state());
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
showMessage(_("TRYING TO START ADAPTER"));
QStringList gdbArgs;
@@ -94,6 +94,28 @@ void LocalPlainGdbAdapter::startAdapter()
m_engine->handleAdapterStarted();
}
void LocalPlainGdbAdapter::setupInferior()
{
AbstractPlainGdbAdapter::setupInferior();
}
void LocalPlainGdbAdapter::runEngine()
{
AbstractPlainGdbAdapter::runEngine();
}
void LocalPlainGdbAdapter::shutdownInferior()
{
m_engine->defaultInferiorShutdown("kill");
}
void LocalPlainGdbAdapter::shutdownAdapter()
{
showMessage(_("PLAIN ADAPTER SHUTDOWN %1").arg(state()));
m_outputCollector.shutdown();
m_engine->notifyAdapterShutdownOk();
}
void LocalPlainGdbAdapter::checkForReleaseBuild()
{
// Quick check for a "release" build
@@ -128,14 +150,10 @@ void LocalPlainGdbAdapter::interruptInferior()
return;
}
if (!interruptProcess(attachedPID))
if (!interruptProcess(attachedPID)) {
showMessage(_("CANNOT INTERRUPT %1").arg(attachedPID));
}
void LocalPlainGdbAdapter::shutdown()
{
showMessage(_("PLAIN ADAPTER SHUTDOWN %1").arg(state()));
m_outputCollector.shutdown();
m_engine->notifyInferiorStopFailed();
}
}
QByteArray LocalPlainGdbAdapter::execFilePath() const
@@ -52,14 +52,17 @@ class LocalPlainGdbAdapter : public AbstractPlainGdbAdapter
public:
LocalPlainGdbAdapter(GdbEngine *engine, QObject *parent = 0);
virtual DumperHandling dumperHandling() const;
private:
void startAdapter();
void setupInferior();
void runEngine();
void interruptInferior();
void shutdown();
void shutdownInferior();
void shutdownAdapter();
DumperHandling dumperHandling() const;
AbstractGdbProcess *gdbProc() { return &m_gdbProc; }
private:
virtual QByteArray execFilePath() const;
virtual bool infoTargetNecessary() const;
virtual QByteArray toLocalEncoding(const QString &s) const;
+1 -1
View File
@@ -196,7 +196,7 @@ void GdbEngine::updateAllPython()
{
PRECONDITION;
//PENDING_DEBUG("UPDATING ALL\n");
QTC_ASSERT(state() == InferiorUnrunnable || state() == InferiorStopped, /**/);
QTC_ASSERT(state() == InferiorUnrunnable || state() == InferiorStopOk, /**/);
reloadModulesInternal();
postCommand("-stack-list-frames", CB(handleStackListFrames),
QVariant::fromValue<StackCookie>(StackCookie(false, true)));
@@ -84,7 +84,7 @@ AbstractGdbAdapter::DumperHandling RemoteGdbServerAdapter::dumperHandling() cons
void RemoteGdbServerAdapter::startAdapter()
{
QTC_ASSERT(state() == EngineSettingUp, qDebug() << state());
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
showMessage(_("TRYING TO START ADAPTER"));
// FIXME: make asynchroneous
@@ -156,7 +156,7 @@ void RemoteGdbServerAdapter::readUploadStandardError()
void RemoteGdbServerAdapter::setupInferior()
{
QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state());
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
m_engine->postCommand("set architecture "
+ startParameters().remoteArchitecture.toLatin1());
@@ -181,14 +181,14 @@ void RemoteGdbServerAdapter::setupInferior()
void RemoteGdbServerAdapter::handleSetTargetAsync(const GdbResponse &response)
{
QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state());
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
if (response.resultClass == GdbResultError)
qDebug() << "Adapter too old: does not support asynchronous mode.";
}
void RemoteGdbServerAdapter::handleFileExecAndSymbols(const GdbResponse &response)
{
QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state());
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
if (response.resultClass == GdbResultDone) {
//m_breakHandler->clearBreakMarkers();
@@ -202,15 +202,15 @@ void RemoteGdbServerAdapter::handleFileExecAndSymbols(const GdbResponse &respons
} else {
QString msg = tr("Starting remote executable failed:\n");
msg += QString::fromLocal8Bit(response.data.findChild("msg").data());
m_engine->handleInferiorSetupFailed(msg);
m_engine->notifyInferiorSetupFailed(msg);
}
}
void RemoteGdbServerAdapter::handleTargetRemote(const GdbResponse &record)
{
QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state());
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
if (record.resultClass == GdbResultDone) {
setState(InferiorStopped);
setState(InferiorStopOk);
// gdb server will stop the remote application itself.
showMessage(_("INFERIOR STARTED"));
showMessage(msgAttachedToStoppedInferior(), StatusBar);
@@ -219,11 +219,11 @@ void RemoteGdbServerAdapter::handleTargetRemote(const GdbResponse &record)
// 16^error,msg="hd:5555: Connection timed out."
QString msg = msgConnectRemoteServerFailed(
QString::fromLocal8Bit(record.data.findChild("msg").data()));
m_engine->handleInferiorSetupFailed(msg);
m_engine->notifyInferiorSetupFailed(msg);
}
}
void RemoteGdbServerAdapter::runAdapter()
void RemoteGdbServerAdapter::runEngine()
{
m_engine->continueInferiorInternal();
}
@@ -235,9 +235,14 @@ void RemoteGdbServerAdapter::interruptInferior()
m_engine->postCommand("-exec-interrupt", GdbEngine::Immediate);
}
void RemoteGdbServerAdapter::shutdown()
void RemoteGdbServerAdapter::shutdownInferior()
{
// FIXME: cleanup missing
m_engine->defaultInferiorShutdown("kill");
}
void RemoteGdbServerAdapter::shutdownAdapter()
{
m_engine->notifyAdapterShutdownOk();
}
} // namespace Internal
@@ -50,16 +50,18 @@ class RemoteGdbServerAdapter : public AbstractGdbAdapter
public:
RemoteGdbServerAdapter(GdbEngine *engine, int toolChainType, QObject *parent = 0);
virtual DumperHandling dumperHandling() const;
private:
DumperHandling dumperHandling() const;
void startAdapter();
void setupInferior();
void runAdapter();
void runEngine();
void interruptInferior();
void shutdown();
void shutdownInferior();
void shutdownAdapter();
AbstractGdbProcess *gdbProc() { return &m_gdbProc; }
private:
Q_SLOT void readUploadStandardOutput();
Q_SLOT void readUploadStandardError();
Q_SLOT void uploadProcError(QProcess::ProcessError error);
@@ -45,7 +45,7 @@ RemotePlainGdbAdapter::RemotePlainGdbAdapter(GdbEngine *engine, QObject *parent)
void RemotePlainGdbAdapter::startAdapter()
{
QTC_ASSERT(state() == EngineSettingUp, qDebug() << state());
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
showMessage(QLatin1String("TRYING TO START ADAPTER"));
if (!startParameters().workingDirectory.isEmpty())
@@ -87,5 +87,15 @@ void RemotePlainGdbAdapter::handleApplicationOutput(const QByteArray &output)
showMessage(QString::fromUtf8(output), AppOutput);
}
void RemotePlainGdbAdapter::shutdownInferior()
{
m_engine->defaultInferiorShutdown("kill");
}
void RemotePlainGdbAdapter::shutdownAdapter()
{
m_engine->notifyAdapterShutdownOk();
}
} // namespace Internal
} // namespace Debugger
@@ -39,16 +39,19 @@ namespace Internal {
class RemotePlainGdbAdapter : public AbstractPlainGdbAdapter
{
Q_OBJECT
friend class RemoteGdbProcess;
public:
friend class RemoteGdbProcess;
RemotePlainGdbAdapter(GdbEngine *engine, QObject *parent = 0);
virtual void startAdapter();
virtual void interruptInferior();
virtual AbstractGdbProcess *gdbProc() { return &m_gdbProc; }
virtual DumperHandling dumperHandling() const { return DumperLoadedByGdbPreload; }
private:
void startAdapter();
void interruptInferior();
void shutdownInferior();
void shutdownAdapter();
AbstractGdbProcess *gdbProc() { return &m_gdbProc; }
DumperHandling dumperHandling() const { return DumperLoadedByGdbPreload; }
virtual QByteArray execFilePath() const;
virtual bool infoTargetNecessary() const;
virtual QByteArray toLocalEncoding(const QString &s) const;
+16 -9
View File
@@ -252,16 +252,15 @@ void TcfTrkGdbAdapter::handleTcfTrkRunControlModuleLoadContextSuspendedEvent(con
void TcfTrkGdbAdapter::handleTargetRemote(const GdbResponse &record)
{
QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state());
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
if (record.resultClass == GdbResultDone) {
setState(InferiorStopped);
m_engine->handleInferiorPrepared();
if (debug)
qDebug() << "handleTargetRemote" << m_session.toString();
} else {
QString msg = tr("Connecting to TRK server adapter failed:\n")
+ QString::fromLocal8Bit(record.data.findChild("msg").data());
m_engine->handleInferiorSetupFailed(msg);
m_engine->notifyInferiorSetupFailed(msg);
}
}
@@ -337,7 +336,7 @@ void TcfTrkGdbAdapter::startGdb()
void TcfTrkGdbAdapter::tcftrkDeviceError(const QString &errorString)
{
logMessage(errorString);
if (state() == EngineSettingUp) {
if (state() == EngineSetupRequested) {
m_engine->handleAdapterStartFailed(errorString, QString());
} else {
m_engine->handleAdapterCrashed(errorString);
@@ -956,7 +955,7 @@ void TcfTrkGdbAdapter::startAdapter()
// Unixish gdbs accept only forward slashes
m_symbolFile.replace(QLatin1Char('\\'), QLatin1Char('/'));
// Start
QTC_ASSERT(state() == EngineSettingUp, qDebug() << state());
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
showMessage(_("TRYING TO START ADAPTER"));
logMessage(QLatin1String("### Starting TcfTrkGdbAdapter"));
@@ -985,7 +984,7 @@ void TcfTrkGdbAdapter::startAdapter()
void TcfTrkGdbAdapter::setupInferior()
{
QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state());
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
m_trkDevice->sendProcessStartCommand(TcfTrkCallback(this, &TcfTrkGdbAdapter::handleCreateProcess),
m_remoteExecutable, m_uid, m_remoteArguments,
QString(), true);
@@ -1011,7 +1010,7 @@ void TcfTrkGdbAdapter::handleCreateProcess(const TcfTrkCommandResult &result)
if (!result) {
const QString errorMessage = result.errorString();
logMessage(QString::fromLatin1("Failed to start process: %1").arg(errorMessage), LogError);
m_engine->handleInferiorSetupFailed(result.errorString());
m_engine->notifyInferiorSetupFailed(result.errorString());
return;
}
QTC_ASSERT(!result.values.isEmpty(), return);
@@ -1029,8 +1028,10 @@ void TcfTrkGdbAdapter::handleCreateProcess(const TcfTrkCommandResult &result)
m_session.dataseg = 0;
}
void TcfTrkGdbAdapter::runAdapter()
void TcfTrkGdbAdapter::runEngine()
{
m_engine->notifyInferiorStopOk();
// Trigger the initial "continue" manually.
m_engine->continueInferiorInternal();
}
@@ -1086,9 +1087,15 @@ void TcfTrkGdbAdapter::cleanup()
} //!m_trkIODevice.isNull()
}
void TcfTrkGdbAdapter::shutdown()
void TcfTrkGdbAdapter::shutdownInferior()
{
m_engine->defaultInferiorShutdown("kill");
}
void TcfTrkGdbAdapter::shutdownAdapter()
{
cleanup();
m_engine->notifyAdapterShutdownOk();
}
void TcfTrkGdbAdapter::trkReloadRegisters()
+3 -2
View File
@@ -105,9 +105,10 @@ public:
private:
void startAdapter();
void setupInferior();
void runAdapter();
void runEngine();
void interruptInferior();
void shutdown();
void shutdownInferior();
void shutdownAdapter();
void handleWriteRegister(const tcftrk::TcfTrkCommandResult &result);
void reportRegisters();
void handleReadRegisters(const tcftrk::TcfTrkCommandResult &result);
+25 -10
View File
@@ -81,7 +81,7 @@ AbstractGdbAdapter::DumperHandling TermGdbAdapter::dumperHandling() const
void TermGdbAdapter::startAdapter()
{
QTC_ASSERT(state() == EngineSettingUp, qDebug() << state());
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
showMessage(_("TRYING TO START ADAPTER"));
// Currently, adapters are not re-used
@@ -111,13 +111,13 @@ void TermGdbAdapter::startAdapter()
void TermGdbAdapter::handleInferiorSetupOk()
{
QTC_ASSERT(state() == EngineSettingUp, qDebug() << state());
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
m_engine->handleAdapterStarted();
}
void TermGdbAdapter::setupInferior()
{
QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state());
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
const qint64 attachedPID = m_stubProc.applicationPID();
m_engine->notifyInferiorPid(attachedPID);
m_engine->postCommand("attach " + QByteArray::number(attachedPID),
@@ -126,9 +126,8 @@ void TermGdbAdapter::setupInferior()
void TermGdbAdapter::handleStubAttached(const GdbResponse &response)
{
QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state());
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
if (response.resultClass == GdbResultDone) {
setState(InferiorStopped);
showMessage(_("INFERIOR ATTACHED"));
m_engine->handleInferiorPrepared();
#ifdef Q_OS_LINUX
@@ -136,12 +135,15 @@ void TermGdbAdapter::handleStubAttached(const GdbResponse &response)
#endif
} else if (response.resultClass == GdbResultError) {
QString msg = QString::fromLocal8Bit(response.data.findChild("msg").data());
m_engine->handleInferiorSetupFailed(msg);
m_engine->notifyInferiorSetupFailed(msg);
}
}
void TermGdbAdapter::runAdapter()
void TermGdbAdapter::runEngine()
{
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
m_engine->notifyEngineRunAndInferiorStopOk();
m_engine->notifyInferiorRunRequested();
m_engine->continueInferiorInternal();
}
@@ -171,10 +173,23 @@ void TermGdbAdapter::stubMessage(const QString &msg, bool)
void TermGdbAdapter::stubExited()
{
if (state() == EngineShutdownRequested || state() == DebuggerFinished) {
showMessage(_("STUB EXITED EXPECTEDLY"));
return;
}
showMessage(_("STUB EXITED"));
if (state() != EngineSettingUp // From previous instance
&& state() != EngineShuttingDown && state() != DebuggerNotReady)
m_engine->handleAdapterCrashed(QString());
qDebug() << "STUB EXITED IN STATE: " << state();
m_engine->notifyEngineIll();
}
void TermGdbAdapter::shutdownInferior()
{
m_engine->defaultInferiorShutdown("kill");
}
void TermGdbAdapter::shutdownAdapter()
{
m_engine->notifyAdapterShutdownOk();
}
} // namespace Internal
+6 -3
View File
@@ -53,15 +53,18 @@ public:
TermGdbAdapter(GdbEngine *engine, QObject *parent = 0);
~TermGdbAdapter();
virtual DumperHandling dumperHandling() const;
private:
DumperHandling dumperHandling() const;
void startAdapter();
void setupInferior();
void runAdapter();
void runEngine();
void interruptInferior();
void shutdownInferior();
void shutdownAdapter();
AbstractGdbProcess *gdbProc() { return &m_gdbProc; }
private:
void handleStubAttached(const GdbResponse &response);
#ifdef Q_OS_LINUX
void handleEntryPoint(const GdbResponse &response);
+14 -9
View File
@@ -254,7 +254,7 @@ void TrkGdbAdapter::emitDelayedInferiorSetupFailed(const QString &msg)
void TrkGdbAdapter::slotEmitDelayedInferiorSetupFailed()
{
m_engine->handleInferiorSetupFailed(m_adapterFailMessage);
m_engine->notifyInferiorSetupFailed(m_adapterFailMessage);
}
@@ -1501,7 +1501,7 @@ void TrkGdbAdapter::startAdapter()
// Unixish gdbs accept only forward slashes
m_symbolFile.replace(QLatin1Char('\\'), QLatin1Char('/'));
// Start
QTC_ASSERT(state() == EngineSettingUp, qDebug() << state());
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
showMessage(_("TRYING TO START ADAPTER"));
logMessage(QLatin1String("### Starting TrkGdbAdapter"));
@@ -1545,14 +1545,14 @@ void TrkGdbAdapter::startAdapter()
void TrkGdbAdapter::setupInferior()
{
QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state());
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
sendTrkMessage(0x40, TrkCB(handleCreateProcess),
trk::Launcher::startProcessMessage(m_remoteExecutable, m_remoteArguments));
}
void TrkGdbAdapter::handleCreateProcess(const TrkResult &result)
{
QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state());
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
// 40 00 00]
//logMessage(" RESULT: " + result.toString());
// [80 08 00 00 00 01 B5 00 00 01 B6 78 67 40 00 00 40 00 00]
@@ -1602,18 +1602,18 @@ void TrkGdbAdapter::handleCreateProcess(const TrkResult &result)
void TrkGdbAdapter::handleTargetRemote(const GdbResponse &record)
{
QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state());
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
if (record.resultClass == GdbResultDone) {
setState(InferiorStopped);
setState(InferiorStopOk);
m_engine->handleInferiorPrepared();
} else {
QString msg = tr("Connecting to TRK server adapter failed:\n")
+ QString::fromLocal8Bit(record.data.findChild("msg").data());
m_engine->handleInferiorSetupFailed(msg);
m_engine->notifyInferiorSetupFailed(msg);
}
}
void TrkGdbAdapter::runAdapter()
void TrkGdbAdapter::runEngine()
{
m_engine->continueInferiorInternal();
}
@@ -1856,7 +1856,12 @@ void TrkGdbAdapter::cleanup()
m_gdbServer = 0;
}
void TrkGdbAdapter::shutdown()
void TrkGdbAdapter::shutdownInferior()
{
m_engine->defaultInferiorShutdown("kill");
}
void TrkGdbAdapter::shutdownAdapter()
{
cleanup();
}
+3 -2
View File
@@ -113,9 +113,10 @@ private:
void startAdapter();
bool initializeDevice(const QString &remoteChannel, QString *errorMessage);
void setupInferior();
void runAdapter();
void runEngine();
void interruptInferior();
void shutdown();
void shutdownInferior();
void shutdownAdapter();
AbstractGdbProcess *gdbProc() { return &m_gdbProc; }
void cleanup();
+30 -34
View File
@@ -118,29 +118,26 @@ void PdbEngine::postCommand(const QByteArray &command,
m_pdbProc.write(cmd.command + "\n");
}
void PdbEngine::shutdown()
void PdbEngine::shutdownInferior()
{
exitDebugger();
QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state());
notifyInferiorShutdownOk();
}
void PdbEngine::exitDebugger()
void PdbEngine::shutdownEngine()
{
if (state() == DebuggerNotReady)
return;
SDEBUG("PdbEngine::exitDebugger()");
QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state());
SDEBUG("PdbEngine::shutdownEngine()");
m_pdbProc.kill();
//if (m_scriptEngine->isEvaluating())
// m_scriptEngine->abortEvaluation();
setState(InferiorShuttingDown);
setState(InferiorShutDown);
setState(EngineShuttingDown);
//m_scriptEngine->setAgent(0);
setState(DebuggerNotReady);
notifyEngineShutdownOk();
}
void PdbEngine::setupEngine()
{
QTC_ASSERT(state() == EngineSettingUp, qDebug() << state());
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
m_scriptFileName = QFileInfo(startParameters().executable).absoluteFilePath();
QFile scriptFile(m_scriptFileName);
@@ -187,7 +184,6 @@ void PdbEngine::setupEngine()
const QString title = tr("Adapter start failed");
Core::ICore::instance()->showWarningWithOptions(title, msg);
}
shutdown();
notifyEngineSetupFailed();
return;
}
@@ -196,7 +192,7 @@ void PdbEngine::setupEngine()
void PdbEngine::setupInferior()
{
QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state());
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
attemptBreakpointSynchronization();
showMessage(_("PDB STARTED, INITIALIZING IT"));
@@ -215,54 +211,54 @@ void PdbEngine::runEngine()
void PdbEngine::interruptInferior()
{
setState(InferiorStopped);
setState(InferiorStopOk);
}
void PdbEngine::executeStep()
{
resetLocation();
setState(InferiorRunningRequested);
setState(InferiorRunning);
setState(InferiorRunRequested);
setState(InferiorRunOk);
postCommand("step", CB(handleUpdateAll));
}
void PdbEngine::executeStepI()
{
resetLocation();
setState(InferiorRunningRequested);
setState(InferiorRunning);
setState(InferiorRunRequested);
setState(InferiorRunOk);
postCommand("step", CB(handleUpdateAll));
}
void PdbEngine::executeStepOut()
{
resetLocation();
setState(InferiorRunningRequested);
setState(InferiorRunning);
setState(InferiorRunRequested);
setState(InferiorRunOk);
postCommand("finish", CB(handleUpdateAll));
}
void PdbEngine::executeNext()
{
resetLocation();
setState(InferiorRunningRequested);
setState(InferiorRunning);
setState(InferiorRunRequested);
setState(InferiorRunOk);
postCommand("next", CB(handleUpdateAll));
}
void PdbEngine::executeNextI()
{
resetLocation();
setState(InferiorRunningRequested);
setState(InferiorRunning);
setState(InferiorRunRequested);
setState(InferiorRunOk);
postCommand("next", CB(handleUpdateAll));
}
void PdbEngine::continueInferior()
{
resetLocation();
setState(InferiorRunningRequested);
setState(InferiorRunning);
setState(InferiorRunRequested);
setState(InferiorRunOk);
// Callback will be triggered e.g. when breakpoint is hit.
postCommand("continue", CB(handleUpdateAll));
}
@@ -290,7 +286,7 @@ void PdbEngine::executeJumpToLine(const QString &fileName, int lineNumber)
void PdbEngine::activateFrame(int frameIndex)
{
resetLocation();
if (state() != InferiorStopped && state() != InferiorUnrunnable)
if (state() != InferiorStopOk && state() != InferiorUnrunnable)
return;
StackHandler *handler = stackHandler();
@@ -460,7 +456,7 @@ void PdbEngine::setToolTipExpression(const QPoint &mousePos,
Q_UNUSED(editor)
Q_UNUSED(cursorPos)
if (state() != InferiorStopped) {
if (state() != InferiorStopOk) {
//SDEBUG("SUPPRESSING DEBUGGER TOOLTIP, INFERIOR NOT STOPPED");
return;
}
@@ -516,7 +512,7 @@ void PdbEngine::setToolTipExpression(const QPoint &mousePos,
}
#if 0
//if (status() != InferiorStopped)
//if (status() != InferiorStopOk)
// return;
// FIXME: 'exp' can contain illegal characters
@@ -566,7 +562,7 @@ void PdbEngine::handlePdbError(QProcess::ProcessError error)
case QProcess::Timedout:
default:
m_pdbProc.kill();
setState(EngineShuttingDown, true);
setState(EngineShutdownRequested, true);
plugin()->showMessageBox(QMessageBox::Critical, tr("Pdb I/O Error"),
errorMessage(error));
break;
@@ -665,8 +661,8 @@ void PdbEngine::handleResponse(const QByteArray &response0)
frame.line = lineNumber;
if (frame.line > 0 && QFileInfo(frame.file).exists()) {
gotoLocation(frame, true);
setState(InferiorStopping);
setState(InferiorStopped);
setState(InferiorStopRequested);
setState(InferiorStopOk);
return;
}
}
@@ -682,8 +678,8 @@ void PdbEngine::handleFirstCommand(const PdbResponse &response)
void PdbEngine::handleUpdateAll(const PdbResponse &response)
{
Q_UNUSED(response);
setState(InferiorStopping);
setState(InferiorStopped);
setState(InferiorStopRequested);
setState(InferiorStopOk);
updateAll();
}
+5 -6
View File
@@ -69,15 +69,14 @@ private:
void executeStepI();
void executeNextI();
void shutdown();
void setToolTipExpression(const QPoint &mousePos,
TextEditor::ITextEditor *editor, int cursorPos);
void setupEngine();
void setupInferior();
void runEngine();
void shutdownInferior();
void shutdownEngine();
void exitDebugger();
void setToolTipExpression(const QPoint &mousePos,
TextEditor::ITextEditor *editor, int cursorPos);
void continueInferior();
void interruptInferior();
@@ -92,7 +91,7 @@ private:
void attemptBreakpointSynchronization();
void assignValueInDebugger(const QString &expr, const QString &value);
void executeDebuggerCommand(const QString & command);
void executeDebuggerCommand(const QString &command);
void loadSymbols(const QString &moduleName);
void loadAllSymbols();
+42 -29
View File
@@ -207,26 +207,39 @@ void QmlEngine::executeDebuggerCommand(const QString &command)
//enqueueCommand(tcf);
}
void QmlEngine::shutdown()
void QmlEngine::setupInferior()
{
exitDebugger();
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
attemptBreakpointSynchronization();
notifyInferiorSetupOk();
}
void QmlEngine::runEngine()
{
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
//notifyEngineRunOk();
}
void QmlEngine::shutdownInferior()
{
QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state());
notifyInferiorShutdownOk();
}
void QmlEngine::shutdownEngine()
{
QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state());
//m_objectTreeWidget->saveSettings(m_settings);
//m_propertiesWidget->saveSettings(m_settings);
//m_settings.saveSettings(Core::ICore::instance()->settings());
}
void QmlEngine::exitDebugger()
{
SDEBUG("QmlEngine::exitDebugger()");
}
const int serverPort = 3768;
void QmlEngine::setupEngine()
{
#if 0
QTC_ASSERT(state() == EngineStarting, qDebug() << state());
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
const DebuggerStartParameters &sp = startParameters();
const int pos = sp.remoteChannel.indexOf(QLatin1Char(':'));
const QString host = sp.remoteChannel.left(pos);
@@ -302,8 +315,8 @@ void QmlEngine::setupConnection()
notifyEngineSetupOk();
qDebug() << "CONNECTION SUCCESSFUL";
setState(InferiorRunningRequested);
setState(InferiorRunning);
setState(InferiorRunRequested);
setState(InferiorRunOk);
// reloadEngines();
@@ -316,8 +329,8 @@ void QmlEngine::continueInferior()
QDataStream rs(&reply, QIODevice::WriteOnly);
rs << QByteArray("CONTINUE");
sendMessage(reply);
setState(InferiorRunningRequested);
setState(InferiorRunning);
setState(InferiorRunRequested);
setState(InferiorRunOk);
}
void QmlEngine::interruptInferior()
@@ -336,8 +349,8 @@ void QmlEngine::executeStep()
QDataStream rs(&reply, QIODevice::WriteOnly);
rs << QByteArray("STEPINTO");
sendMessage(reply);
setState(InferiorRunningRequested);
setState(InferiorRunning);
setState(InferiorRunRequested);
setState(InferiorRunOk);
}
void QmlEngine::executeStepI()
@@ -347,8 +360,8 @@ void QmlEngine::executeStepI()
QDataStream rs(&reply, QIODevice::WriteOnly);
rs << QByteArray("STEPINTO");
sendMessage(reply);
setState(InferiorRunningRequested);
setState(InferiorRunning);
setState(InferiorRunRequested);
setState(InferiorRunOk);
}
void QmlEngine::executeStepOut()
@@ -358,8 +371,8 @@ void QmlEngine::executeStepOut()
QDataStream rs(&reply, QIODevice::WriteOnly);
rs << QByteArray("STEPOUT");
sendMessage(reply);
setState(InferiorRunningRequested);
setState(InferiorRunning);
setState(InferiorRunRequested);
setState(InferiorRunOk);
}
void QmlEngine::executeNext()
@@ -368,8 +381,8 @@ void QmlEngine::executeNext()
QDataStream rs(&reply, QIODevice::WriteOnly);
rs << QByteArray("STEPOVER");
sendMessage(reply);
setState(InferiorRunningRequested);
setState(InferiorRunning);
setState(InferiorRunRequested);
setState(InferiorRunOk);
SDEBUG("QmlEngine::nextExec()");
}
@@ -619,8 +632,8 @@ void QmlEngine::messageReceived(const QByteArray &message)
showMessage(_("RECEIVED RESPONSE: ") + quoteUnprintableLatin1(message));
if (command == "STOPPED") {
setState(InferiorStopping);
setState(InferiorStopped);
setState(InferiorStopRequested);
setState(InferiorStopOk);
QList<QPair<QString, QPair<QString, qint32> > > backtrace;
QList<QPair<QString, QVariant> > watches;
@@ -713,7 +726,7 @@ void QmlEngine::handleProcError(QProcess::ProcessError error)
case QProcess::Timedout:
default:
m_proc.kill();
setState(EngineShuttingDown, true);
setState(EngineShutdownRequested, true);
plugin()->showMessageBox(QMessageBox::Critical, tr("Gdb I/O Error"),
errorMessage(error));
break;
@@ -1253,7 +1266,7 @@ void QmlEngine::debuggerStateChanged(int newState)
if (m_simultaneousCppAndQmlDebugMode) {
switch(newState) {
case Debugger::EngineSettingUp:
case Debugger::EngineSetupRequested:
{
m_connectionInitialized = false;
break;
@@ -1262,9 +1275,9 @@ void QmlEngine::debuggerStateChanged(int newState)
case Debugger::InferiorSetupFailed:
emit statusMessage(QString(tr("Debugging failed: could not start C++ debugger.")));
break;
case Debugger::InferiorRunningRequested:
case Debugger::InferiorRunRequested:
{
if (m_cppDebuggerState == Debugger::InferiorStopped) {
if (m_cppDebuggerState == Debugger::InferiorStopOk) {
// re-enable UI again
m_objectTreeWidget->setEnabled(true);
m_propertiesWidget->setEnabled(true);
@@ -1272,7 +1285,7 @@ void QmlEngine::debuggerStateChanged(int newState)
}
break;
}
case Debugger::InferiorRunning:
case Debugger::InferiorRunOk:
{
if (!m_connectionInitialized) {
m_connectionInitialized = true;
@@ -1281,14 +1294,14 @@ void QmlEngine::debuggerStateChanged(int newState)
}
break;
}
case Debugger::InferiorStopped:
case Debugger::InferiorStopOk:
{
m_objectTreeWidget->setEnabled(false);
m_propertiesWidget->setEnabled(false);
m_expressionWidget->setEnabled(false);
break;
}
case Debugger::EngineShuttingDown:
case Debugger::EngineShutdownRequested:
{
m_connectionInitialized = false;
// here it's safe to enable the debugger windows again -
+6 -3
View File
@@ -86,10 +86,13 @@ private:
void executeStepI();
void executeNextI();
void shutdown();
void setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos);
void setupEngine();
void exitDebugger();
void setupInferior();
void runEngine();
void shutdownInferior();
void shutdownEngine();
void setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos);
void continueInferior();
void interruptInferior();
+1 -1
View File
@@ -170,7 +170,7 @@ void RegisterWindow::contextMenuEvent(QContextMenuEvent *ev)
QAction *actReload = menu.addAction(tr("Reload Register Listing"));
actReload->setEnabled((engineCapabilities & RegisterCapability)
&& (state == InferiorStopped || state == InferiorUnrunnable));
&& (state == InferiorStopOk || state == InferiorUnrunnable));
menu.addSeparator();
+88 -65
View File
@@ -65,7 +65,7 @@
#include <QtScript/QScriptValue>
#include <QtScript/QScriptValueIterator>
#define DEBUG_SCRIPT 1
//#define DEBUG_SCRIPT 1
#if DEBUG_SCRIPT
# define SDEBUG(s) qDebug() << s
#else
@@ -101,34 +101,44 @@ public:
int baseLineNumber);
void scriptUnload(qint64 id);
void showMessage(const QString &msg);
private:
void maybeBreakNow(bool byFunction);
ScriptEngine *q;
int m_depth;
int m_contextDepth;
};
ScriptAgent::ScriptAgent(ScriptEngine *debugger, QScriptEngine *script)
: QScriptEngineAgent(script), q(debugger)
: QScriptEngineAgent(script), q(debugger), m_depth(0), m_contextDepth(0)
{}
void ScriptAgent::showMessage(const QString &msg)
{
SDEBUG(msg);
q->showMessage(msg, LogMisc);
}
void ScriptAgent::contextPop()
{
SDEBUG("ScriptAgent::contextPop: ");
//showMessage(_("ContextPop: %1").arg(m_contextDepth));
--m_contextDepth;
}
void ScriptAgent::contextPush()
{
SDEBUG("ScriptAgent::contextPush: ");
++m_contextDepth;
//showMessage(_("ContextPush: %1 ").arg(m_contextDepth));
}
void ScriptAgent::exceptionCatch(qint64 scriptId, const QScriptValue & exception)
{
Q_UNUSED(scriptId)
Q_UNUSED(exception)
const QString msg = QString::fromLatin1("An exception was caught on %1: '%2'").
arg(scriptId).arg(exception.toString());
SDEBUG(msg);
q->showMessage(msg, LogMisc);
showMessage(_("An exception was caught on %1: '%2'").
arg(scriptId).arg(exception.toString()));
}
void ScriptAgent::exceptionThrow(qint64 scriptId, const QScriptValue &exception,
@@ -137,16 +147,15 @@ void ScriptAgent::exceptionThrow(qint64 scriptId, const QScriptValue &exception,
Q_UNUSED(scriptId)
Q_UNUSED(exception)
Q_UNUSED(hasHandler)
const QString msg = QString::fromLatin1("An exception occurred on %1: '%2'").
arg(scriptId).arg(exception.toString());
SDEBUG(msg);
q->showMessage(msg, LogMisc);
showMessage(_("An exception occurred on %1: '%2'").
arg(scriptId).arg(exception.toString()));
}
void ScriptAgent::functionEntry(qint64 scriptId)
{
Q_UNUSED(scriptId)
q->showMessage(QString::fromLatin1("Function entry occurred on %1").arg(scriptId), LogMisc);
++m_depth;
//showMessage(_("Function entry occurred on %1, depth: %2").arg(scriptId));
q->checkForBreakCondition(true);
}
@@ -154,17 +163,17 @@ void ScriptAgent::functionExit(qint64 scriptId, const QScriptValue &returnValue)
{
Q_UNUSED(scriptId)
Q_UNUSED(returnValue)
const QString msg = QString::fromLatin1("Function exit occurred on %1: '%2'").arg(scriptId).arg(returnValue.toString());
SDEBUG(msg);
q->showMessage(msg, LogMisc);
--m_depth;
//showMessage(_("Function exit occurred on %1: '%2'").
// arg(scriptId).arg(returnValue.toString()));
}
void ScriptAgent::positionChange(qint64 scriptId, int lineNumber, int columnNumber)
{
SDEBUG("ScriptAgent::position: " << lineNumber);
Q_UNUSED(scriptId)
Q_UNUSED(lineNumber)
Q_UNUSED(columnNumber)
//showMessage(_("Position: %1").arg(lineNumber));
q->checkForBreakCondition(false);
}
@@ -175,14 +184,13 @@ void ScriptAgent::scriptLoad(qint64 scriptId, const QString &program,
Q_UNUSED(program)
Q_UNUSED(fileName)
Q_UNUSED(baseLineNumber)
q->showMessage(QString::fromLatin1("Loaded: %1 id: %2")
.arg(fileName).arg(scriptId), LogMisc);
showMessage(_("Loaded: %1 id: %2").arg(fileName).arg(scriptId));
}
void ScriptAgent::scriptUnload(qint64 scriptId)
{
Q_UNUSED(scriptId)
SDEBUG("ScriptAgent::scriptUnload: " << scriptId);
showMessage(_("Unload script id %1 ").arg(scriptId));
}
@@ -207,37 +215,36 @@ void ScriptEngine::executeDebuggerCommand(const QString &command)
XSDEBUG("FIXME: ScriptEngine::executeDebuggerCommand()");
}
void ScriptEngine::shutdown()
void ScriptEngine::shutdownInferior()
{
exitDebugger();
}
void ScriptEngine::exitDebugger()
{
if (state() == DebuggerNotReady)
return;
SDEBUG("ScriptEngine::exitDebugger()");
QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state());
SDEBUG("ScriptEngine::shutdownInferior()");
m_scriptEngine->setAgent(0);
//m_scriptAgent.reset(0);
m_stopped = false;
m_stopOnNextLine = false;
if (m_scriptEngine->isEvaluating())
m_scriptEngine->abortEvaluation();
setState(InferiorShuttingDown);
setState(InferiorShutDown);
notifyInferiorShutdownOk();
}
setState(EngineShuttingDown);
void ScriptEngine::shutdownEngine()
{
QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state());
m_scriptEngine->setAgent(0);
setState(DebuggerNotReady);
notifyEngineShutdownOk();
}
void ScriptEngine::setupEngine()
{
QTC_ASSERT(state() == EngineSettingUp, qDebug() << state());
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
showMessage(_("STARTING SCRIPT DEBUGGER"), LogMisc);
if (m_scriptEngine.isNull())
m_scriptEngine = Core::ICore::instance()->scriptManager()->scriptEngine();
if (!m_scriptAgent)
m_scriptAgent.reset(new ScriptAgent(this, m_scriptEngine.data()));
QTC_ASSERT(!m_scriptAgent, /**/);
m_scriptAgent.reset(new ScriptAgent(this, m_scriptEngine.data()));
m_scriptEngine->setAgent(m_scriptAgent.data());
//m_scriptEngine->setAgent(new ScriptAgent(this, m_scriptEngine.data()));
/* Keep the gui alive (have the engine call processEvents() while the script
* is run in the foreground). */
m_scriptEngine->setProcessEventsInterval(1 /*ms*/);
@@ -251,12 +258,12 @@ void ScriptEngine::setupEngine()
void ScriptEngine::setupInferior()
{
QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state());
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
m_scriptFileName = QFileInfo(startParameters().executable).absoluteFilePath();
showMessage(_("SCRIPT FILE: ") + m_scriptFileName);
QFile scriptFile(m_scriptFileName);
if (!scriptFile.open(QIODevice::ReadOnly|QIODevice::Text)) {
showMessage(QString::fromLatin1("Cannot open %1: %2").
showMessage(_("Cannot open %1: %2").
arg(m_scriptFileName, scriptFile.errorString()), LogError);
notifyEngineSetupFailed();
return;
@@ -270,6 +277,8 @@ void ScriptEngine::setupInferior()
void ScriptEngine::continueInferior()
{
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
notifyInferiorRunRequested();
SDEBUG("ScriptEngine::continueInferior()");
m_stopped = false;
m_stopOnNextLine = false;
@@ -280,7 +289,7 @@ static const char *qtExtensionsC[] = {
"qt.sql", "qt.opengl", "qt.webkit", "qt.xmlpatterns", "qt.uitools"
};
bool ScriptEngine::importExtensions()
void ScriptEngine::importExtensions()
{
SDEBUG("ScriptEngine::importExtensions()");
QStringList extensions;
@@ -288,11 +297,11 @@ bool ScriptEngine::importExtensions()
for (int e = 0; e < extCount; e++)
extensions.append(QLatin1String(qtExtensionsC[e]));
if (m_scriptEngine->importedExtensions().contains(extensions.front()))
return true;
return; // true;
QDir dir(QLatin1String("/home/apoenitz/dev/qtscriptgenerator"));
if (!dir.cd(QLatin1String("plugins"))) {
fprintf(stderr, "plugins folder does not exist -- did you build the bindings?\n");
return false;
return; // false;
}
QStringList paths = qApp->libraryPaths();
paths << dir.absolutePath();
@@ -319,45 +328,43 @@ bool ScriptEngine::importExtensions()
qPrintable(failExtensions.join(QLatin1String(", "))), qPrintable(dir.absolutePath()));
}
}
return failExtensions.isEmpty();
return; // failExtensions.isEmpty();
}
void ScriptEngine::runEngine()
{
QTC_ASSERT(state() == InferiorSetupOk, qDebug() << state());
setState(InferiorRunningRequested);
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
SDEBUG("ScriptEngine::runEngine()");
notifyEngineRunAndInferiorRunOk();
showStatusMessage(tr("Running requested..."), 5000);
showMessage(QLatin1String("Running: ") + m_scriptFileName, LogMisc);
SDEBUG("ScriptEngine::runEngine()");
importExtensions();
setState(InferiorRunning);
const QScriptValue result = m_scriptEngine->evaluate(m_scriptContents, m_scriptFileName);
setState(InferiorStopping);
setState(InferiorStopped);
QString msg;
if (m_scriptEngine->hasUncaughtException()) {
msg = QString::fromLatin1("An exception occurred during execution at line: %1\n%2\n")
msg = _("An exception occurred during execution at line: %1\n%2\n")
.arg(m_scriptEngine->uncaughtExceptionLineNumber())
.arg(m_scriptEngine->uncaughtException().toString());
msg += m_scriptEngine->uncaughtExceptionBacktrace()
.join(QString(QLatin1Char('\n')));
} else {
msg = QString::fromLatin1("Evaluation returns '%1'")
.arg(result.toString());
msg = _("Evaluation returns '%1'").arg(result.toString());
}
showMessage(msg, LogMisc);
exitDebugger();
showMessage(_("This was the outermost function."));
notifyInferiorExited();
}
void ScriptEngine::interruptInferior()
{
m_stopped = false;
m_stopOnNextLine = true;
XSDEBUG("ScriptEngine::interruptInferior()");
}
void ScriptEngine::executeStep()
{
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
notifyInferiorRunRequested();
//SDEBUG("ScriptEngine::stepExec()");
m_stopped = false;
m_stopOnNextLine = true;
@@ -365,6 +372,8 @@ void ScriptEngine::executeStep()
void ScriptEngine::executeStepI()
{
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
notifyInferiorRunRequested();
//SDEBUG("ScriptEngine::stepIExec()");
m_stopped = false;
m_stopOnNextLine = true;
@@ -372,6 +381,8 @@ void ScriptEngine::executeStepI()
void ScriptEngine::executeStepOut()
{
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
notifyInferiorRunRequested();
//SDEBUG("ScriptEngine::stepOutExec()");
m_stopped = false;
m_stopOnNextLine = true;
@@ -379,6 +390,8 @@ void ScriptEngine::executeStepOut()
void ScriptEngine::executeNext()
{
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
notifyInferiorRunRequested();
//SDEBUG("ScriptEngine::nextExec()");
m_stopped = false;
m_stopOnNextLine = true;
@@ -386,6 +399,8 @@ void ScriptEngine::executeNext()
void ScriptEngine::executeNextI()
{
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
notifyInferiorRunRequested();
//SDEBUG("ScriptEngine::nextIExec()");
m_stopped = false;
m_stopOnNextLine = true;
@@ -393,6 +408,8 @@ void ScriptEngine::executeNextI()
void ScriptEngine::executeRunToLine(const QString &fileName, int lineNumber)
{
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
notifyInferiorRunRequested();
Q_UNUSED(fileName)
Q_UNUSED(lineNumber)
SDEBUG("FIXME: ScriptEngine::runToLineExec()");
@@ -400,12 +417,16 @@ void ScriptEngine::executeRunToLine(const QString &fileName, int lineNumber)
void ScriptEngine::executeRunToFunction(const QString &functionName)
{
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
notifyInferiorRunRequested();
Q_UNUSED(functionName)
XSDEBUG("FIXME: ScriptEngine::runToFunctionExec()");
}
void ScriptEngine::executeJumpToLine(const QString &fileName, int lineNumber)
{
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
notifyInferiorRunRequested();
Q_UNUSED(fileName)
Q_UNUSED(lineNumber)
XSDEBUG("FIXME: ScriptEngine::jumpToLineExec()");
@@ -481,7 +502,7 @@ void ScriptEngine::setToolTipExpression(const QPoint &mousePos,
Q_UNUSED(editor)
Q_UNUSED(cursorPos)
if (state() != InferiorStopped) {
if (state() != InferiorStopOk) {
//SDEBUG("SUPPRESSING DEBUGGER TOOLTIP, INFERIOR NOT STOPPED");
return;
}
@@ -537,7 +558,7 @@ void ScriptEngine::setToolTipExpression(const QPoint &mousePos,
}
#if 0
//if (m_manager->status() != InferiorStopped)
//if (m_manager->status() != InferiorStopOk)
// return;
// FIXME: 'exp' can contain illegal characters
@@ -591,6 +612,11 @@ static BreakpointData *findBreakPointByFileName(BreakHandler *handler,
bool ScriptEngine::checkForBreakCondition(bool byFunction)
{
// FIXME: Should that ever happen after setAgent(0) in shutdownInferior()?
// In practice, it does, so chicken out.
if (targetState() == DebuggerFinished)
return false;
const QScriptContext *context = m_scriptEngine->currentContext();
const QScriptContextInfo info(context);
@@ -599,7 +625,7 @@ bool ScriptEngine::checkForBreakCondition(bool byFunction)
const QString fileName = info.fileName();
const int lineNumber = byFunction
? info.functionStartLineNumber() : info.lineNumber();
SDEBUG("checkForBreakCondition" << byFunction << functionName
SDEBUG(Q_FUNC_INFO << byFunction << functionName
<< lineNumber << fileName);
if (m_stopOnNextLine) {
// Interrupt inferior
@@ -627,8 +653,7 @@ bool ScriptEngine::checkForBreakCondition(bool byFunction)
data->pending = false;
data->updateMarker();
}
setState(InferiorStopping);
setState(InferiorStopped);
notifyInferiorSpontaneousStop();
SDEBUG("Stopped at " << lineNumber << fileName);
showStatusMessage(tr("Stopped at %1:%2.").arg(fileName).arg(lineNumber), 5000);
@@ -644,7 +669,7 @@ void ScriptEngine::updateLocals()
{
QScriptContext *context = m_scriptEngine->currentContext();
watchHandler()->beginCycle();
//SDEBUG("UPDATE LOCALS");
SDEBUG(Q_FUNC_INFO);
//
// Build stack
@@ -674,24 +699,22 @@ void ScriptEngine::updateLocals()
WatchData data;
data.iname = "local";
data.name = QString::fromLatin1(data.iname);
data.name = _(data.iname);
data.scriptValue = context->activationObject();
watchHandler()->beginCycle();
updateSubItem(data);
watchHandler()->endCycle();
// FIXME: Use an extra thread. This here is evil
// FIXME: Use an extra thread. This here is evil.
m_stopped = true;
showStatusMessage(tr("Stopped."), 5000);
while (m_stopped) {
//SDEBUG("LOOPING");
QApplication::processEvents();
}
setState(InferiorRunningRequested);
setState(InferiorRunning);
// Clear any exceptions occurred during locals evaluation.
m_scriptEngine->clearExceptions();
m_scriptEngine->setAgent(m_scriptAgent.data());
SDEBUG("Continuing");
notifyInferiorRunOk();
}
void ScriptEngine::updateWatchData(const WatchData &data)
@@ -713,7 +736,7 @@ void ScriptEngine::updateSubItem(const WatchData &data0)
{
WatchData data = data0;
QList<WatchData> children;
SDEBUG("\nUPDATE SUBITEM: " << data.toString() << data.scriptValue.toString());
//SDEBUG("\nUPDATE SUBITEM: " << data.toString() << data.scriptValue.toString());
QTC_ASSERT(data.isValid(), return);
if (data.isTypeNeeded() || data.isValueNeeded()) {
+3 -3
View File
@@ -68,13 +68,13 @@ private:
void executeStepI();
void executeNextI();
void shutdown();
void setToolTipExpression(const QPoint &mousePos,
TextEditor::ITextEditor *editor, int cursorPos);
void setupEngine();
void setupInferior();
void runEngine();
void exitDebugger();
void shutdownInferior();
void shutdownEngine();
void continueInferior();
void interruptInferior();
@@ -108,7 +108,7 @@ private:
private:
friend class ScriptAgent;
bool importExtensions();
void importExtensions();
QSharedPointer<QScriptEngine> m_scriptEngine;
QString m_scriptContents;
+34 -20
View File
@@ -155,14 +155,11 @@ void TcfEngine::socketReadyRead()
void TcfEngine::socketConnected()
{
showStatusMessage("Socket connected.");
if (m_socket->waitForConnected(2000))
notifyEngineSetupOk();
else
notifyEngineSetupFailed();
}
void TcfEngine::socketDisconnected()
{
showStatusMessage("Socket disconnected.");
XSDEBUG("FIXME: TcfEngine::socketDisconnected()");
}
@@ -171,7 +168,7 @@ void TcfEngine::socketError(QAbstractSocket::SocketError)
QString msg = tr("%1.").arg(m_socket->errorString());
//QMessageBox::critical(q->mainWindow(), tr("Error"), msg);
showStatusMessage(msg);
exitDebugger();
notifyEngineIll();
}
void TcfEngine::executeDebuggerCommand(const QString &command)
@@ -189,29 +186,46 @@ void TcfEngine::executeDebuggerCommand(const QString &command)
enqueueCommand(tcf);
}
void TcfEngine::shutdown()
{
m_congestion = 0;
m_inAir = 0;
m_services.clear();
exitDebugger();
}
void TcfEngine::exitDebugger()
{
SDEBUG("TcfEngine::exitDebugger()");
}
void TcfEngine::setupEngine()
{
QTC_ASSERT(state() == EngineSettingUp, qDebug() << state());
setState(InferiorRunningRequested);
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
showStatusMessage(tr("Running requested..."), 5000);
const DebuggerStartParameters &sp = startParameters();
const int pos = sp.remoteChannel.indexOf(QLatin1Char(':'));
const QString host = sp.remoteChannel.left(pos);
const quint16 port = sp.remoteChannel.mid(pos + 1).toInt();
m_socket->connectToHost(host, port);
if (m_socket->waitForConnected())
notifyEngineSetupOk();
else
notifyEngineSetupFailed();
}
void TcfEngine::setupInferior()
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
notifyInferiorSetupOk();
}
void TcfEngine::runEngine()
{
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
//notifyEngineRunOk();
}
void TcfEngine::shutdownInferior()
{
QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state());
notifyInferiorShutdownOk();
}
void TcfEngine::shutdownEngine()
{
QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state());
m_congestion = 0;
m_inAir = 0;
m_services.clear();
notifyEngineShutdownOk();
}
void TcfEngine::continueInferior()
+8 -4
View File
@@ -72,10 +72,14 @@ private:
void executeStepI();
void executeNextI();
void shutdown();
void setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos);
void setupEngine();
void exitDebugger();
void setupInferior();
void runEngine();
void shutdownInferior();
void shutdownEngine();
void setToolTipExpression(const QPoint &mousePos,
TextEditor::ITextEditor *editor, int cursorPos);
void continueInferior();
void interruptInferior();
@@ -90,7 +94,7 @@ private:
void attemptBreakpointSynchronization();
void assignValueInDebugger(const QString &expr, const QString &value);
void executeDebuggerCommand(const QString & command);
void executeDebuggerCommand(const QString &command);
void loadSymbols(const QString &moduleName);
void loadAllSymbols();
+4
View File
@@ -36,3 +36,7 @@ function cube(a)
}
var a = cube(3);
a += 1
a += 1
a += 1
a += 1
+16
View File
@@ -1779,10 +1779,25 @@ namespace ns {
void testStuff()
{
typedef unsigned short wchar;
wchar *str = new wchar[10];
str[2] = 0;
str[1] = 'B';
str[0] = 'A';
str[0] = 'A';
str[0] = 'A';
str[0] = 'A';
QString foo = "foo";
wchar *f = (wchar*)foo.utf16();
str[0] = 'A';
str[0] = 'A';
str[0] = 'A';
/*
ns::vl j = 1000;
ns::verylong k = 1000;
++j;
++k;
*/
}
void testPassByReferenceHelper(Foo &f)
@@ -1854,6 +1869,7 @@ int main(int argc, char *argv[])
//testWCout0();
//testWCout();
testColor();
return 0;
testQRegion();
testStuff();
testPeekAndPoke3();