fix shutdown paths

this includes:
- move the gdb ownership back to the engine (thus strip down the
  adaptors as far as possible)
- make gdb startup synchronous
- make adapter shutdown synchronous
- fix the state transitions relating to shutdown
This commit is contained in:
Oswald Buddenhagen
2009-10-20 11:02:16 +02:00
parent 4b0060c537
commit b3addf14f1
19 changed files with 302 additions and 649 deletions

View File

@@ -824,6 +824,9 @@ void CdbDebugEnginePrivate::processCreatedAttached(ULONG64 processHandle, ULONG6
void CdbDebugEngine::processTerminated(unsigned long exitCode)
{
manager()->showDebuggerOutput(LogMisc, tr("The process exited with exit code %1.").arg(exitCode));
if (m_engine->state() != InferiorStopping)
setState(InferiorStopping, Q_FUNC_INFO, __LINE__);
setState(InferiorStopped, Q_FUNC_INFO, __LINE__);
setState(InferiorShuttingDown, Q_FUNC_INFO, __LINE__);
m_d->setDebuggeeHandles(0, 0);
m_d->clearForRun();
@@ -919,14 +922,11 @@ void CdbDebugEnginePrivate::endDebugging(EndDebuggingMode em)
errorMessage.clear();
}
// Clean up resources (open files, etc.)
m_engine->setState(AdapterShuttingDown, Q_FUNC_INFO, __LINE__);
m_engine->setState(EngineShuttingDown, Q_FUNC_INFO, __LINE__);
clearForRun();
const HRESULT hr = m_cif.debugClient->EndSession(DEBUG_END_PASSIVE);
if (SUCCEEDED(hr)) {
m_engine->setState(DebuggerNotReady, Q_FUNC_INFO, __LINE__);
} else {
m_engine->setState(AdapterShutdownFailed, Q_FUNC_INFO, __LINE__);
m_engine->setState(DebuggerNotReady, Q_FUNC_INFO, __LINE__);
m_engine->setState(DebuggerNotReady, Q_FUNC_INFO, __LINE__);
if (!SUCCEEDED(hr)) {
errorMessage = QString::fromLatin1("There were errors trying to end debugging: %1").arg(msgComFailed("EndSession", hr));
manager()->showDebuggerOutput(LogError, errorMessage);
}

View File

@@ -79,15 +79,13 @@ enum DebuggerState
InferiorStopping, // Debuggee running, stop requested
InferiorStopped, // Debuggee stopped
InferiorStopFailed, // Debuggee stopped
InferiorStopFailed, // Debuggee not stopped, will kill debugger
InferiorShuttingDown,
InferiorShutDown,
InferiorShutdownFailed,
AdapterShuttingDown,
//AdapterShutDown, // Use DebuggerNotReady instead
AdapterShutdownFailed,
EngineShuttingDown
};
enum DebuggerStartMode

View File

@@ -101,43 +101,35 @@
// gdbserver, the trk client etc are referred to as 'Adapter',
// whereas the debugged process is referred to as 'Inferior'.
//
// 0 == DebuggerNotReady
// 0 == DebuggerNotReady
// |
// EngineStarting
// EngineStarting
// |
// AdapterStarting --> AdapterStartFailed --> 0
// AdapterStarting --> AdapterStartFailed --> 0
// |
// AdapterStarted
// |
// InferiorStarting --> InferiorStartFailed --> 0
// |
// (core) | (attach) (remote)
// .-----------------<-|->--------------------.
// | v |
// InferiorUnrunnable | |
// | | v
// | | (plain)
// | | (trk)
// | |
// | | .------------------------------------.
// | | v |
// | InferiorRunningRequested v |
// | | | |
// | .---- InferiorRunning | |
// | | | | |
// | | InferiorStopping | |
// | | | | |
// | v v | |
// | |<--- InferiorStopped <-----------' |
// | | | |
// | | `---------------------------------------'
// | |
// | '---> InferiorShuttingDown -> InferiorShutdownFailed
// | |
// | InferiorShutDown
// | |
// | v
// '------------> AdapterShuttingDown -> AdapterShutdownFailed --> 0
// AdapterStarted ------------------------------------.
// | v
// InferiorStarting ----> InferiorStartFailed -------->|
// | |
// (core) | (attach) (term) (remote) |
// .-----------------<-|->------------------. |
// | v | |
// InferiorUnrunnable | (plain) | |
// | | (trk) | |
// | | | |
// | .--> InferiorRunningRequested | |
// | | | | |
// | | InferiorRunning | |
// | | | | |
// | | InferiorStopping | |
// | | | | |
// | '------ InferiorStopped <-----------' |
// | | v
// | InferiorShuttingDown -> InferiorShutdownFailed ---->|
// | | |
// | InferiorShutDown |
// | | |
// '--------> EngineShuttingDown <--------------------------------'
// |
// 0
//
@@ -208,8 +200,7 @@ static const char *stateName(int s)
SN(InferiorShuttingDown)
SN(InferiorShutDown)
SN(InferiorShutdownFailed)
SN(AdapterShuttingDown)
SN(AdapterShutdownFailed)
SN(EngineShuttingDown)
}
return "<unknown>";
#undef SN
@@ -1574,7 +1565,7 @@ static bool isAllowedTransition(int from, int to)
case AdapterStarting:
return to == AdapterStarted || to == AdapterStartFailed;
case AdapterStarted:
return to == InferiorStarting;
return to == InferiorStarting || to == EngineShuttingDown;
case AdapterStartFailed:
return to == DebuggerNotReady;
@@ -1582,37 +1573,38 @@ static bool isAllowedTransition(int from, int to)
return to == InferiorRunningRequested || to == InferiorStopped
|| to == InferiorStartFailed || to == InferiorUnrunnable;
case InferiorStartFailed:
return to == DebuggerNotReady;
return to == EngineShuttingDown;
case InferiorRunningRequested:
return to == InferiorRunning;
case InferiorRunning:
return to == InferiorStopping || to == InferiorShuttingDown;
return to == InferiorStopping;
case InferiorStopping:
return to == InferiorStopped || to == InferiorStopFailed;
case InferiorStopped:
return to == InferiorRunningRequested || to == InferiorShuttingDown;
case InferiorStopFailed:
return to == DebuggerNotReady;
return to == EngineShuttingDown;
case InferiorUnrunnable:
return to == AdapterShuttingDown;
return to == EngineShuttingDown;
case InferiorShuttingDown:
return to == InferiorShutDown || to == InferiorShutdownFailed;
case InferiorShutDown:
return to == AdapterShuttingDown;
return to == EngineShuttingDown;
case InferiorShutdownFailed:
return to == EngineShuttingDown;
case AdapterShuttingDown:
case EngineShuttingDown:
return to == DebuggerNotReady;
default:
qDebug() << "UNKNOWN STATE: " << from;
}
qDebug() << "UNKNOWN STATE:" << from;
return false;
}
void DebuggerManager::setState(DebuggerState state)
void DebuggerManager::setState(DebuggerState state, bool forced)
{
//STATE_DEBUG("STATUS CHANGE: FROM " << stateName(d->m_state)
// << " TO " << stateName(state));
@@ -1621,7 +1613,7 @@ void DebuggerManager::setState(DebuggerState state)
.arg(stateName(d->m_state)).arg(d->m_state).arg(stateName(state)).arg(state);
//if (!((d->m_state == -1 && state == 0) || (d->m_state == 0 && state == 0)))
// qDebug() << msg;
if (!isAllowedTransition(d->m_state, state))
if (!forced && !isAllowedTransition(d->m_state, state))
qDebug() << "UNEXPECTED STATE TRANSITION: " << msg;
showDebuggerOutput(LogDebug, msg);
@@ -1715,8 +1707,7 @@ bool DebuggerManager::debuggerActionsEnabled() const
case InferiorShuttingDown:
case InferiorShutDown:
case InferiorShutdownFailed:
case AdapterShuttingDown:
case AdapterShutdownFailed:
case EngineShuttingDown:
break;
}
return false;
@@ -1793,9 +1784,9 @@ DebuggerState IDebuggerEngine::state() const
return m_manager->state();
}
void IDebuggerEngine::setState(DebuggerState state)
void IDebuggerEngine::setState(DebuggerState state, bool forced)
{
m_manager->setState(state);
m_manager->setState(state, forced);
}
//////////////////////////////////////////////////////////////////////

View File

@@ -285,7 +285,7 @@ private:
void cleanupViews();
void setState(DebuggerState state);
void setState(DebuggerState state, bool forced = false);
//
// internal implementation

View File

@@ -47,35 +47,18 @@ AbstractGdbAdapter::~AbstractGdbAdapter()
disconnect();
}
// This cannot be in the c'tor, as it would not connect the "virtual" slots
void AbstractGdbAdapter::commonInit()
void AbstractGdbAdapter::shutdown()
{
QTC_ASSERT(state() == EngineStarting, qDebug() << state());
connect(&m_gdbProc, SIGNAL(error(QProcess::ProcessError)),
this, SLOT(handleGdbError(QProcess::ProcessError)));
connect(&m_gdbProc, SIGNAL(started()),
this, SLOT(handleGdbStarted()));
connect(&m_gdbProc, SIGNAL(finished(int, QProcess::ExitStatus)),
this, SLOT(handleGdbFinished(int, QProcess::ExitStatus)));
connect(&m_gdbProc, SIGNAL(readyReadStandardOutput()),
this, SIGNAL(readyReadStandardOutput()));
connect(&m_gdbProc, SIGNAL(readyReadStandardError()),
this, SIGNAL(readyReadStandardError()));
}
QByteArray AbstractGdbAdapter::readAllStandardOutput()
const char *AbstractGdbAdapter::inferiorShutdownCommand() const
{
return m_gdbProc.readAllStandardOutput();
}
QByteArray AbstractGdbAdapter::readAllStandardError()
{
return m_gdbProc.readAllStandardError();
return "kill";
}
void AbstractGdbAdapter::write(const QByteArray &data)
{
m_gdbProc.write(data);
m_engine->m_gdbProc.write(data);
}
bool AbstractGdbAdapter::isTrkAdapter() const

View File

@@ -42,7 +42,7 @@ namespace Internal {
// debugging and TrkGdbAdapter used for on-device debugging.
// In the PlainGdbAdapter case it's just a wrapper around a QProcess running
// gdb, in the TrkGdbAdapter case it's the interface to the gdb process in
// the whole rfomm/gdb/gdbserver combo.
// the whole rfcomm/gdb/gdbserver combo.
class AbstractGdbAdapter : public QObject
{
Q_OBJECT
@@ -51,34 +51,39 @@ public:
AbstractGdbAdapter(GdbEngine *engine, QObject *parent = 0);
virtual ~AbstractGdbAdapter();
QByteArray readAllStandardOutput();
QByteArray readAllStandardError();
virtual void write(const QByteArray &data);
virtual bool isTrkAdapter() const; // isUtterlyBrokenAdapter
virtual void startAdapter() = 0;
virtual void startInferior() = 0;
virtual void interruptInferior() = 0;
virtual void shutdown() = 0;
virtual void shutdown();
virtual const char *inferiorShutdownCommand() const;
virtual bool dumpersAvailable() const = 0;
static QString msgGdbStopFailed(const QString &why);
static QString msgInferiorStopFailed(const QString &why);
static QString msgAttachedToStoppedInferior();
static QString msgInferiorStarted();
static QString msgInferiorRunning();
static QString msgConnectRemoteServerFailed(const QString &why);
signals:
void adapterStarted();
// Something went wrong with the adapter *before* adapterStarted() was emitted.
// Make sure to clean up everything before emitting this signal.
void adapterStartFailed(const QString &msg, const QString &settingsIdHint);
void adapterShutDown();
void adapterShutdownFailed(const QString &msg);
// Something went wrong with the adapter *after* adapterStarted() was emitted.
// Make sure to clean up everything before emitting this signal.
void adapterCrashed(const QString &msg);
// The adapter is still running just fine, but it failed to acquire a debuggee.
void inferiorStartFailed(const QString &msg);
void inferiorShutDown();
void inferiorShutdownFailed(const QString &msg);
void readyReadStandardOutput();
void readyReadStandardError();
protected:
void commonInit();
DebuggerState state() const
{ return m_engine->state(); }
void setState(DebuggerState state)
@@ -90,16 +95,7 @@ protected:
void showStatusMessage(const QString &msg) const
{ m_engine->showStatusMessage(msg); }
static QString msgGdbStopFailed(const QString &why);
static QString msgInferiorStopFailed(const QString &why);
static QString msgAttachedToStoppedInferior();
static QString msgInferiorStarted();
static QString msgInferiorRunning();
static QString msgConnectRemoteServerFailed(const QString &why);
GdbEngine * const m_engine;
QProcess m_gdbProc;
};
} // namespace Internal

View File

@@ -53,7 +53,6 @@ namespace Internal {
AttachGdbAdapter::AttachGdbAdapter(GdbEngine *engine, QObject *parent)
: AbstractGdbAdapter(engine, parent)
{
commonInit();
}
void AttachGdbAdapter::startAdapter()
@@ -62,27 +61,12 @@ void AttachGdbAdapter::startAdapter()
setState(AdapterStarting);
debugMessage(_("TRYING TO START ADAPTER"));
QStringList gdbArgs;
gdbArgs.prepend(_("mi"));
gdbArgs.prepend(_("-i"));
if (!m_engine->startGdb())
return;
QString location = theDebuggerStringSetting(GdbLocation);
m_gdbProc.start(location, gdbArgs);
}
void AttachGdbAdapter::handleGdbStarted()
{
QTC_ASSERT(state() == AdapterStarting, qDebug() << state());
emit adapterStarted();
}
void AttachGdbAdapter::handleGdbError(QProcess::ProcessError error)
{
debugMessage(_("PLAIN ADAPTER, HANDLE GDB ERROR"));
emit adapterCrashed(m_engine->errorMessage(error));
shutdown();
}
void AttachGdbAdapter::startInferior()
{
QTC_ASSERT(state() == InferiorStarting, qDebug() << state());
@@ -113,58 +97,5 @@ void AttachGdbAdapter::interruptInferior()
debugMessage(_("CANNOT INTERRUPT %1").arg(pid));
}
void AttachGdbAdapter::shutdown()
{
switch (state()) {
case InferiorStartFailed:
m_engine->postCommand(_("-gdb-exit"));
setState(DebuggerNotReady);
return;
case InferiorStopped:
setState(InferiorShuttingDown);
m_engine->postCommand(_("detach"), CB(handleDetach));
return;
case InferiorShutDown:
setState(AdapterShuttingDown);
m_engine->postCommand(_("-gdb-exit"), GdbEngine::ExitRequest, CB(handleExit));
return;
default:
QTC_ASSERT(false, qDebug() << state());
}
}
void AttachGdbAdapter::handleDetach(const GdbResponse &response)
{
if (response.resultClass == GdbResultDone) {
setState(InferiorShutDown);
emit inferiorShutDown();
shutdown(); // re-iterate...
} else {
const QString msg = msgInferiorStopFailed(__(response.data.findChild("msg").data()));
setState(InferiorShutdownFailed);
emit inferiorShutdownFailed(msg);
}
}
void AttachGdbAdapter::handleExit(const GdbResponse &response)
{
if (response.resultClass == GdbResultDone) {
// don't set state here, this will be handled in handleGdbFinished()
} else {
const QString msg = msgGdbStopFailed(__(response.data.findChild("msg").data()));
emit adapterShutdownFailed(msg);
}
}
void AttachGdbAdapter::handleGdbFinished(int, QProcess::ExitStatus)
{
debugMessage(_("GDB PROESS FINISHED"));
emit adapterShutDown();
}
} // namespace Internal
} // namespace Debugger

View File

@@ -57,16 +57,10 @@ public:
void startAdapter();
void startInferior();
void interruptInferior();
void shutdown();
const char *inferiorShutdownCommand() const { return "detach"; }
private:
void handleAttach(const GdbResponse &response);
void handleDetach(const GdbResponse &response);
void handleExit(const GdbResponse &response);
Q_SLOT void handleGdbStarted();
Q_SLOT void handleGdbFinished(int, QProcess::ExitStatus);
Q_SLOT void handleGdbError(QProcess::ProcessError error);
};
} // namespace Internal

View File

@@ -53,7 +53,6 @@ namespace Internal {
CoreGdbAdapter::CoreGdbAdapter(GdbEngine *engine, QObject *parent)
: AbstractGdbAdapter(engine, parent)
{
commonInit();
}
void CoreGdbAdapter::startAdapter()
@@ -62,27 +61,12 @@ void CoreGdbAdapter::startAdapter()
setState(AdapterStarting);
debugMessage(_("TRYING TO START ADAPTER"));
QStringList gdbArgs;
gdbArgs.prepend(_("mi"));
gdbArgs.prepend(_("-i"));
if (!m_engine->startGdb())
return;
QString location = theDebuggerStringSetting(GdbLocation);
m_gdbProc.start(location, gdbArgs);
}
void CoreGdbAdapter::handleGdbStarted()
{
QTC_ASSERT(state() == AdapterStarting, qDebug() << state());
emit adapterStarted();
}
void CoreGdbAdapter::handleGdbError(QProcess::ProcessError error)
{
debugMessage(_("PLAIN ADAPTER, HANDLE GDB ERROR"));
emit adapterCrashed(m_engine->errorMessage(error));
shutdown();
}
void CoreGdbAdapter::startInferior()
{
QTC_ASSERT(state() == InferiorStarting, qDebug() << state());
@@ -175,45 +159,12 @@ void CoreGdbAdapter::handleTargetCore2(const GdbResponse &response)
// emit inferiorStartFailed(msg);
}
}
void CoreGdbAdapter::interruptInferior()
{
// A core should never 'run'
QTC_ASSERT(false, /**/);
}
void CoreGdbAdapter::shutdown()
{
switch (state()) {
case DebuggerNotReady:
return;
case InferiorUnrunnable:
case InferiorShutDown:
setState(AdapterShuttingDown);
m_engine->postCommand(_("-gdb-exit"), GdbEngine::ExitRequest, CB(handleExit));
return;
default:
QTC_ASSERT(false, qDebug() << state());
}
}
void CoreGdbAdapter::handleExit(const GdbResponse &response)
{
if (response.resultClass == GdbResultDone) {
// don't set state here, this will be handled in handleGdbFinished()
} else {
const QString msg = msgGdbStopFailed(__(response.data.findChild("msg").data()));
emit adapterShutdownFailed(msg);
}
}
void CoreGdbAdapter::handleGdbFinished(int, QProcess::ExitStatus)
{
debugMessage(_("GDB PROESS FINISHED"));
emit adapterShutDown();
}
} // namespace Internal
} // namespace Debugger

View File

@@ -57,18 +57,12 @@ public:
void startAdapter();
void startInferior();
void interruptInferior();
void shutdown();
private:
void handleTargetCore1(const GdbResponse &response);
void handleDetach1(const GdbResponse &response);
void handleFileExecAndSymbols(const GdbResponse &response);
void handleTargetCore2(const GdbResponse &response);
void handleExit(const GdbResponse &response);
Q_SLOT void handleGdbStarted();
Q_SLOT void handleGdbError(QProcess::ProcessError error);
Q_SLOT void handleGdbFinished(int, QProcess::ExitStatus);
QString m_executable;
};

View File

@@ -105,17 +105,29 @@ namespace Internal {
static bool stateAcceptsGdbCommands(DebuggerState state)
{
return state == AdapterStarted
|| state == InferiorUnrunnable
|| state == InferiorStarting
|| state == InferiorRunningRequested
|| state == InferiorRunning
|| state == InferiorStopping
|| state == InferiorStopped
|| state == InferiorShuttingDown
|| state == InferiorShutDown
|| state == AdapterShuttingDown;
};
switch (state) {
case AdapterStarting:
case AdapterStarted:
case AdapterStartFailed:
case InferiorUnrunnable:
case InferiorStarting:
case InferiorStartFailed:
case InferiorRunningRequested:
case InferiorRunning:
case InferiorStopping:
case InferiorStopped:
case InferiorShuttingDown:
case InferiorShutDown:
case InferiorShutdownFailed:
return true;
case DebuggerNotReady:
case EngineStarting:
case InferiorStopFailed:
case EngineShuttingDown:
break;
}
return false;
}
static int &currentToken()
{
@@ -217,27 +229,13 @@ GdbEngine::~GdbEngine()
void GdbEngine::connectAdapter()
{
// Gdb Process interaction
connect(m_gdbAdapter, SIGNAL(readyReadStandardOutput()),
this, SLOT(readGdbStandardOutput()));
connect(m_gdbAdapter, SIGNAL(readyReadStandardError()),
this, SLOT(readGdbStandardError()));
connect(m_gdbAdapter, SIGNAL(adapterStarted()),
this, SLOT(handleAdapterStarted()));
connect(m_gdbAdapter, SIGNAL(adapterStartFailed(QString,QString)),
this, SLOT(handleAdapterStartFailed(QString,QString)));
connect(m_gdbAdapter, SIGNAL(adapterShutDown()),
this, SLOT(handleAdapterShutDown()));
connect(m_gdbAdapter, SIGNAL(adapterShutdownFailed(QString)),
this, SLOT(handleAdapterShutdownFailed(QString)));
connect(m_gdbAdapter, SIGNAL(inferiorStartFailed(QString)),
this, SLOT(handleInferiorStartFailed(QString)));
connect(m_gdbAdapter, SIGNAL(inferiorShutDown()),
this, SLOT(handleInferiorShutDown()));
connect(m_gdbAdapter, SIGNAL(inferiorShutdownFailed(QString)),
this, SLOT(handleInferiorShutdownFailed(QString)));
connect(m_gdbAdapter, SIGNAL(adapterCrashed(QString)),
this, SLOT(handleAdapterCrashed(QString)));
@@ -571,7 +569,7 @@ void GdbEngine::handleResponse(const QByteArray &buff)
void GdbEngine::readGdbStandardError()
{
qWarning() << "Unexpected gdb stderr:" << m_gdbAdapter->readAllStandardError();
qWarning() << "Unexpected gdb stderr:" << m_gdbProc.readAllStandardError();
}
void GdbEngine::readGdbStandardOutput()
@@ -579,7 +577,7 @@ void GdbEngine::readGdbStandardOutput()
int newstart = 0;
int scan = m_inbuffer.size();
m_inbuffer.append(m_gdbAdapter->readAllStandardOutput());
m_inbuffer.append(m_gdbProc.readAllStandardOutput());
while (newstart < m_inbuffer.size()) {
int start = newstart;
@@ -1366,8 +1364,73 @@ QString GdbEngine::fullName(const QStringList &candidates)
void GdbEngine::shutdown()
{
debugMessage(_("INITIATE GDBENGINE SHUTDOWN"));
initializeVariables();
m_gdbAdapter->shutdown();
switch (state()) {
case DebuggerNotReady: // Nothing to do! :)
case EngineStarting: // We can't get here, really
case InferiorShuttingDown: // Will auto-trigger further shutdown steps
case EngineShuttingDown: // Do not disturb! :)
break;
case AdapterStarting: // GDB is up, adapter is "doing something"
setState(AdapterStartFailed);
m_gdbAdapter->shutdown();
// fall-through
case AdapterStartFailed: // Adapter "did something", but it did not help
// FIXME set some timeout?
postCommand(_("-gdb-exit"), GdbEngine::ExitRequest, CB(handleGdbExit));
break;
case InferiorRunningRequested:
case InferiorRunning:
case InferiorStopping:
case InferiorStopped:
// FIXME set some timeout?
postCommand(_(m_gdbAdapter->inferiorShutdownCommand()),
NeedsStop, CB(handleInferiorShutdown));
setState(InferiorShuttingDown); // Do it after posting the command!
break;
case AdapterStarted: // We can't get here, really
case InferiorStartFailed:
case InferiorShutDown:
case InferiorShutdownFailed: // Whatever
case InferiorUnrunnable:
// FIXME set some timeout?
postCommand(_("-gdb-exit"), GdbEngine::ExitRequest, CB(handleGdbExit));
setState(EngineShuttingDown); // Do it after posting the command!
break;
case InferiorStarting: // This may take some time, so just short-circuit it
setState(InferiorStartFailed);
// fall-through
case InferiorStopFailed: // Tough luck, I guess. But unreachable as of now anyway.
setState(EngineShuttingDown);
m_gdbProc.terminate();
break;
}
}
void GdbEngine::handleInferiorShutdown(const GdbResponse &response)
{
QTC_ASSERT(state() == InferiorShuttingDown, qDebug() << state());
if (response.resultClass == GdbResultDone) {
debugMessage(_("INFERIOR SUCCESSFULLY SHUT DOWN"));
setState(InferiorShutDown);
} else {
debugMessage(_("INFERIOR SHUTDOWN FAILED"));
setState(InferiorShutdownFailed);
QString msg = m_gdbAdapter->msgInferiorStopFailed(_(response.data.findChild("msg").data()));
showMessageBox(QMessageBox::Critical, tr("Inferior shutdown failed"), msg);
}
shutdown(); // re-iterate...
}
void GdbEngine::handleGdbExit(const GdbResponse &response)
{
if (response.resultClass == GdbResultExit) {
debugMessage(_("GDB CLAIMS EXIT; WAITING"));
// don't set state here, this will be handled in handleGdbFinished()
} else {
QString msg = m_gdbAdapter->msgGdbStopFailed(_(response.data.findChild("msg").data()));
debugMessage(_("GDB WON'T EXIT (%1); KILLING IT").arg(msg));
m_gdbProc.terminate();
}
}
void GdbEngine::detachDebugger()
@@ -1383,8 +1446,7 @@ void GdbEngine::detachDebugger()
void GdbEngine::exitDebugger() // called from the manager
{
disconnectDebuggingHelperActions();
initializeVariables();
m_gdbAdapter->shutdown();
shutdown();
}
int GdbEngine::currentFrame() const
@@ -1445,17 +1507,17 @@ void GdbEngine::startDebugger(const DebuggerStartParametersPtr &sp)
// initializeVariables());
//QTC_ASSERT(m_gdbAdapter == 0, delete m_gdbAdapter; m_gdbAdapter = 0);
initializeVariables();
m_startParameters = sp;
delete m_gdbAdapter;
m_gdbAdapter = createAdapter(sp);
connectAdapter();
if (startModeAllowsDumpers())
connectDebuggingHelperActions();
initializeVariables();
connectAdapter();
m_gdbAdapter->startAdapter();
}
@@ -4089,19 +4151,37 @@ void GdbEngine::gotoLocation(const StackFrame &frame, bool setMarker)
// Starting up & shutting down
//
void GdbEngine::handleAdapterStartFailed(const QString &msg, const QString &settingsIdHint)
bool GdbEngine::startGdb(const QStringList &args, const QString &gdb)
{
setState(AdapterStartFailed);
debugMessage(_("ADAPTER START FAILED"));
Core::ICore::instance()->showWarningWithOptions(tr("Adapter start failed"), msg, QString(),
QLatin1String(Debugger::Constants::DEBUGGER_SETTINGS_CATEGORY), settingsIdHint);
shutdown();
}
debugMessage(_("STARTING GDB ") + gdb);
void GdbEngine::handleAdapterStarted()
{
setState(AdapterStarted);
debugMessage(_("ADAPTER SUCCESSFULLY STARTED, INITIALIZING GDB"));
m_gdbProc.disconnect(); // From any previous runs
QString location = gdb;
if (location.isEmpty())
location = theDebuggerStringSetting(GdbLocation);
QStringList gdbArgs;
gdbArgs << _("-i");
gdbArgs << _("mi");
gdbArgs += args;
m_gdbProc.start(location, gdbArgs);
if (!m_gdbProc.waitForStarted()) {
handleAdapterStartFailed(m_gdbProc.errorString());
return false;
}
// Do this only after the process is running, so we get no needless error notifications
connect(&m_gdbProc, SIGNAL(error(QProcess::ProcessError)),
SLOT(handleGdbError(QProcess::ProcessError)));
connect(&m_gdbProc, SIGNAL(finished(int, QProcess::ExitStatus)),
SLOT(handleGdbFinished(int, QProcess::ExitStatus)));
connect(&m_gdbProc, SIGNAL(readyReadStandardOutput()),
SLOT(readGdbStandardOutput()));
connect(&m_gdbProc, SIGNAL(readyReadStandardError()),
SLOT(readGdbStandardError()));
debugMessage(_("GDB STARTED, INITIALIZING IT"));
postCommand(_("show version"), CB(handleShowVersion));
postCommand(_("help bb"), CB(handleIsSynchroneous));
@@ -4185,12 +4265,69 @@ void GdbEngine::handleAdapterStarted()
}
}
return true;
}
void GdbEngine::handleGdbError(QProcess::ProcessError error)
{
debugMessage(_("HANDLE GDB ERROR"));
switch (error) {
case QProcess::Crashed:
break; // will get a processExited() as well
// impossible case QProcess::FailedToStart:
case QProcess::ReadError:
case QProcess::WriteError:
case QProcess::Timedout:
default:
m_gdbProc.terminate();
setState(EngineShuttingDown, true);
showMessageBox(QMessageBox::Critical, tr("Gdb I/O Error"),
errorMessage(error));
break;
}
}
void GdbEngine::handleGdbFinished(int code, QProcess::ExitStatus type)
{
debugMessage(_("GDB PROCESS FINISHED, status %1, code %2").arg(type).arg(code));
if (state() == EngineShuttingDown) {
m_gdbAdapter->shutdown();
} else if (state() != AdapterStartFailed) {
showMessageBox(QMessageBox::Critical, tr("Unexpected Gdb Exit"),
tr("The gdb process exited unexpectedly (%1).")
.arg((type == QProcess::CrashExit)
? tr("crashed") : tr("code %1").arg(code)));
m_gdbAdapter->shutdown();
}
initializeVariables();
setState(DebuggerNotReady, true);
}
void GdbEngine::handleAdapterStartFailed(const QString &msg, const QString &settingsIdHint)
{
setState(AdapterStartFailed);
debugMessage(_("ADAPTER START FAILED"));
Core::ICore::instance()->showWarningWithOptions(
tr("Adapter start failed"), msg, QString(),
_(Debugger::Constants::DEBUGGER_SETTINGS_CATEGORY), settingsIdHint);
shutdown();
}
void GdbEngine::handleAdapterStarted()
{
setState(AdapterStarted);
debugMessage(_("ADAPTER SUCCESSFULLY STARTED"));
// Initial attempt to set breakpoints
showStatusMessage(tr("Setting breakpoints..."));
attemptBreakpointSynchronization();
QTC_ASSERT(m_commandsDoneCallback == 0, /**/);
m_commandsDoneCallback = &GdbEngine::startInferior;
if (m_cookieForToken.isEmpty()) {
startInferior();
} else {
QTC_ASSERT(m_commandsDoneCallback == 0, /**/);
m_commandsDoneCallback = &GdbEngine::startInferior;
}
}
void GdbEngine::startInferior()
@@ -4209,48 +4346,23 @@ void GdbEngine::handleInferiorStartFailed(const QString &msg)
shutdown();
}
void GdbEngine::handleInferiorShutDown()
{
debugMessage(_("INFERIOR SUCCESSFULLY SHUT DOWN"));
}
void GdbEngine::handleInferiorShutdownFailed(const QString &msg)
{
debugMessage(_("INFERIOR SHUTDOWN FAILED"));
showMessageBox(QMessageBox::Critical, tr("Inferior shutdown failed"), msg);
shutdown(); // continue with adapter shutdown
}
void GdbEngine::handleAdapterCrashed(const QString &msg)
{
debugMessage(_("ADAPTER CRASHED"));
switch (state()) {
// All fall-through.
case InferiorRunning:
setState(InferiorShuttingDown);
case InferiorShuttingDown:
setState(InferiorShutDown);
case InferiorShutDown:
setState(AdapterShuttingDown);
default:
setState(DebuggerNotReady);
}
// The adapter is expected to have cleaned up after itself when we get here,
// so the effect is about the same as AdapterStartFailed => use it.
// Don't bother with state transitions - this can happen in any state and
// the end result is always the same, so it makes little sense to find a
// "path" which does not assert.
setState(AdapterStartFailed, true);
// No point in being friendly here ...
m_gdbProc.terminate();
showMessageBox(QMessageBox::Critical, tr("Adapter crashed"), msg);
}
void GdbEngine::handleAdapterShutDown()
{
debugMessage(_("ADAPTER SUCCESSFULLY SHUT DOWN"));
setState(DebuggerNotReady);
}
void GdbEngine::handleAdapterShutdownFailed(const QString &msg)
{
debugMessage(_("ADAPTER SHUTDOWN FAILED"));
showMessageBox(QMessageBox::Critical, tr("Adapter shutdown failed"), msg);
setState(DebuggerNotReady);
}
void GdbEngine::addOptionPages(QList<Core::IOptionsPage*> *opts) const
{
opts->push_back(new GdbOptionsPage);

View File

@@ -125,14 +125,20 @@ private: ////////// Gdb Process Management //////////
AbstractGdbAdapter *createAdapter(const DebuggerStartParametersPtr &dp);
void connectAdapter();
bool startGdb(const QStringList &args = QStringList(), const QString &gdb = QString());
void startInferior();
void handleInferiorShutdown(const GdbResponse &response);
void handleGdbExit(const GdbResponse &response);
void gdbInputAvailable(int channel, const QString &msg)
{ m_manager->showDebuggerInput(channel, msg); }
void gdbOutputAvailable(int channel, const QString &msg)
{ m_manager->showDebuggerOutput(channel, msg); }
private slots:
void handleGdbFinished(int, QProcess::ExitStatus status);
void handleGdbError(QProcess::ProcessError error);
void readGdbStandardOutput();
void readGdbStandardError();
void readDebugeeOutput(const QByteArray &data);
@@ -141,12 +147,8 @@ private slots:
void handleAdapterStartFailed(const QString &msg, const QString &settingsIdHint = QString());
void handleInferiorStartFailed(const QString &msg);
void handleInferiorShutDown();
void handleInferiorShutdownFailed(const QString &msg);
void handleAdapterCrashed(const QString &msg);
void handleAdapterShutDown();
void handleAdapterShutdownFailed(const QString &msg);
private:
QTextCodec *m_outputCodec;
@@ -154,6 +156,7 @@ private:
QByteArray m_inbuffer;
QProcess m_gdbProc;
AbstractGdbAdapter *m_gdbAdapter;
private: ////////// Gdb Command Management //////////

View File

@@ -58,8 +58,6 @@ namespace Internal {
PlainGdbAdapter::PlainGdbAdapter(GdbEngine *engine, QObject *parent)
: AbstractGdbAdapter(engine, parent)
{
commonInit();
// Output
connect(&m_outputCollector, SIGNAL(byteDelivery(QByteArray)),
engine, SLOT(readDebugeeOutput(QByteArray)));
@@ -72,36 +70,27 @@ void PlainGdbAdapter::startAdapter()
debugMessage(_("TRYING TO START ADAPTER"));
QStringList gdbArgs;
gdbArgs.prepend(_("mi"));
gdbArgs.prepend(_("-i"));
if (!m_outputCollector.listen()) {
emit adapterStartFailed(tr("Cannot set up communication with child process: %1")
.arg(m_outputCollector.errorString()), QString());
return;
}
gdbArgs.prepend(_("--tty=") + m_outputCollector.serverName());
gdbArgs.append(_("--tty=") + m_outputCollector.serverName());
if (!startParameters().workingDir.isEmpty())
m_gdbProc.setWorkingDirectory(startParameters().workingDir);
m_engine->m_gdbProc.setWorkingDirectory(startParameters().workingDir);
if (!startParameters().environment.isEmpty())
m_gdbProc.setEnvironment(startParameters().environment);
m_engine->m_gdbProc.setEnvironment(startParameters().environment);
m_gdbProc.start(theDebuggerStringSetting(GdbLocation), gdbArgs);
}
if (!m_engine->startGdb(gdbArgs)) {
m_outputCollector.shutdown();
return;
}
void PlainGdbAdapter::handleGdbStarted()
{
QTC_ASSERT(state() == AdapterStarting, qDebug() << state());
emit adapterStarted();
}
void PlainGdbAdapter::handleGdbError(QProcess::ProcessError error)
{
debugMessage(_("PLAIN ADAPTER, HANDLE GDB ERROR"));
emit adapterCrashed(m_engine->errorMessage(error));
}
void PlainGdbAdapter::startInferior()
{
QTC_ASSERT(state() == InferiorStarting, qDebug() << state());
@@ -159,74 +148,6 @@ void PlainGdbAdapter::shutdown()
{
debugMessage(_("PLAIN ADAPTER SHUTDOWN %1").arg(state()));
m_outputCollector.shutdown();
switch (state()) {
case InferiorRunningRequested:
case InferiorRunning:
case InferiorStopping:
case InferiorStopped:
setState(InferiorShuttingDown);
m_engine->postCommand(_("kill"), CB(handleKill));
return;
case InferiorShuttingDown:
// FIXME: How can we end up here?
QTC_ASSERT(false, qDebug() << state());
// Fall through.
case InferiorShutDown:
setState(AdapterShuttingDown);
m_engine->postCommand(_("-gdb-exit"), GdbEngine::ExitRequest, CB(handleExit));
return;
/*
case InferiorShutdownFailed:
m_gdbProc.terminate();
// 20s can easily happen when loading webkit debug information
m_gdbProc.waitForFinished(20000);
setState(AdapterShuttingDown);
debugMessage(_("FORCING TERMINATION: %1").arg(state()));
if (state() != QProcess::NotRunning) {
debugMessage(_("PROBLEM STOPPING DEBUGGER: STATE %1")
.arg(state()));
m_gdbProc.kill();
}
m_engine->postCommand(_("-gdb-exit"), GdbEngine::ExitRequest, CB(handleExit));
return;
*/
default:
QTC_ASSERT(false, qDebug() << state());
}
}
void PlainGdbAdapter::handleKill(const GdbResponse &response)
{
debugMessage(_("PLAIN ADAPTER HANDLE KILL " + response.toString()));
if (response.resultClass == GdbResultDone) {
setState(InferiorShutDown);
emit inferiorShutDown();
shutdown(); // re-iterate...
} else {
const QString msg = msgInferiorStopFailed(__(response.data.findChild("msg").data()));
setState(InferiorShutdownFailed);
emit inferiorShutdownFailed(msg);
}
}
void PlainGdbAdapter::handleExit(const GdbResponse &response)
{
if (response.resultClass == GdbResultDone) {
// don't set state here, this will be handled in handleGdbFinished()
} else {
const QString msg = msgGdbStopFailed(__(response.data.findChild("msg").data()));
emit adapterShutdownFailed(msg);
}
}
void PlainGdbAdapter::handleGdbFinished(int, QProcess::ExitStatus)
{
debugMessage(_("GDB PROCESS FINISHED"));
emit adapterShutDown();
}
} // namespace Internal

View File

@@ -59,17 +59,12 @@ public:
void startInferior();
void interruptInferior();
void shutdown();
const char *inferiorShutdownCommand() const { return "kill"; }
private:
void handleFileExecAndSymbols(const GdbResponse &response);
void handleKill(const GdbResponse &response);
void handleExit(const GdbResponse &response);
void handleExecRun(const GdbResponse &response);
Q_SLOT void handleGdbFinished(int, QProcess::ExitStatus status);
Q_SLOT void handleGdbError(QProcess::ProcessError error);
Q_SLOT void handleGdbStarted();
OutputCollector m_outputCollector;
};

View File

@@ -54,8 +54,6 @@ namespace Internal {
RemoteGdbAdapter::RemoteGdbAdapter(GdbEngine *engine, QObject *parent)
: AbstractGdbAdapter(engine, parent)
{
commonInit();
connect(&m_uploadProc, SIGNAL(error(QProcess::ProcessError)),
this, SLOT(uploadProcError(QProcess::ProcessError)));
connect(&m_uploadProc, SIGNAL(readyReadStandardOutput()),
@@ -70,12 +68,6 @@ void RemoteGdbAdapter::startAdapter()
setState(AdapterStarting);
debugMessage(_("TRYING TO START ADAPTER"));
QStringList gdbArgs;
gdbArgs.prepend(_("mi"));
gdbArgs.prepend(_("-i"));
QString location = theDebuggerStringSetting(GdbLocation);
// FIXME: make asynchroneous
// Start the remote server
if (startParameters().serverStartScript.isEmpty()) {
@@ -86,23 +78,13 @@ void RemoteGdbAdapter::startAdapter()
m_uploadProc.waitForStarted();
}
// Start the debugger
m_gdbProc.start(location, gdbArgs);
}
if (!m_engine->startGdb())
// FIXME: cleanup missing
return;
void RemoteGdbAdapter::handleGdbStarted()
{
QTC_ASSERT(state() == AdapterStarting, qDebug() << state());
emit adapterStarted();
}
void RemoteGdbAdapter::handleGdbError(QProcess::ProcessError error)
{
debugMessage(_("ADAPTER, HANDLE GDB ERROR"));
emit adapterCrashed(m_engine->errorMessage(error));
shutdown();
}
void RemoteGdbAdapter::uploadProcError(QProcess::ProcessError error)
{
QString msg;
@@ -232,55 +214,7 @@ void RemoteGdbAdapter::interruptInferior()
void RemoteGdbAdapter::shutdown()
{
switch (state()) {
case InferiorRunning:
case InferiorStopped:
setState(InferiorShuttingDown);
m_engine->postCommand(_("kill"), CB(handleKill));
return;
default:
QTC_ASSERT(false, qDebug() << state());
// fall through
case InferiorStartFailed:
case InferiorShutDown:
setState(AdapterShuttingDown);
m_engine->postCommand(_("-gdb-exit"), GdbEngine::ExitRequest, CB(handleExit));
return;
}
}
void RemoteGdbAdapter::handleKill(const GdbResponse &response)
{
QTC_ASSERT(state() == InferiorShuttingDown, qDebug() << state());
if (response.resultClass == GdbResultDone) {
setState(InferiorShutDown);
emit inferiorShutDown();
shutdown(); // re-iterate...
} else {
QString msg = msgInferiorStopFailed(__(response.data.findChild("msg").data()));
setState(InferiorShutdownFailed);
emit inferiorShutdownFailed(msg);
}
}
void RemoteGdbAdapter::handleExit(const GdbResponse &response)
{
if (response.resultClass == GdbResultDone) {
// don't set state here, this will be handled in handleGdbFinished()
} else {
QString msg = msgGdbStopFailed(__(response.data.findChild("msg").data()));
emit adapterShutdownFailed(msg);
}
}
void RemoteGdbAdapter::handleGdbFinished(int, QProcess::ExitStatus)
{
debugMessage(_("GDB PROESS FINISHED"));
emit adapterShutDown();
// FIXME: cleanup missing
}
} // namespace Internal

View File

@@ -69,12 +69,6 @@ private:
#endif
void handleFileExecAndSymbols(const GdbResponse &response);
void handleTargetRemote(const GdbResponse &response);
void handleKill(const GdbResponse &response);
void handleExit(const GdbResponse &response);
Q_SLOT void handleGdbStarted();
Q_SLOT void handleGdbError(QProcess::ProcessError error);
Q_SLOT void handleGdbFinished(int, QProcess::ExitStatus);
QProcess m_uploadProc;
};

View File

@@ -204,10 +204,6 @@ TrkGdbAdapter::TrkGdbAdapter(GdbEngine *engine, const TrkOptionsPtr &options) :
#endif
m_gdbServerName = _("127.0.0.1:%1").arg(2222 + portOffset);
commonInit();
connect(&m_gdbProc, SIGNAL(stateChanged(QProcess::ProcessState)),
this, SLOT(handleGdbStateChanged(QProcess::ProcessState)));
connect(&m_rfcommProc, SIGNAL(readyReadStandardError()),
this, SLOT(handleRfcommReadyReadStandardError()));
connect(&m_rfcommProc, SIGNAL(readyReadStandardOutput()),
@@ -380,17 +376,6 @@ QByteArray TrkGdbAdapter::trkInterruptMessage()
return ba;
}
void TrkGdbAdapter::emitDelayedAdapterStartFailed(const QString &msg)
{
m_adapterFailMessage = msg;
QTimer::singleShot(0, this, SLOT(slotEmitDelayedAdapterStartFailed()));
}
void TrkGdbAdapter::slotEmitDelayedAdapterStartFailed()
{
emit adapterStartFailed(m_adapterFailMessage, TrkOptionsPage::settingsId());
}
void TrkGdbAdapter::emitDelayedInferiorStartFailed(const QString &msg)
{
m_adapterFailMessage = msg;
@@ -437,7 +422,7 @@ void TrkGdbAdapter::waitForTrkConnect()
// "10 " + formatString("C:\\data\\usingdlls.sisx")); // Open File
//sendTrkMessage(0x4B, 0, "00 00 00 01 73 1C 3A C8"); // Close File
maybeAdapterStarted();
emit adapterStarted();
}
void TrkGdbAdapter::logMessage(const QString &msg)
@@ -1527,50 +1512,6 @@ void TrkGdbAdapter::interruptInferior()
sendTrkMessage(0x1a, TrkCallback(), trkInterruptMessage(), "Interrupting...");
}
void TrkGdbAdapter::handleGdbError(QProcess::ProcessError error)
{
if (error == QProcess::FailedToStart) {
const QString msg = QString::fromLatin1("GDB: Cannot start '%1': %2. Please check the settings.").arg(m_options->gdb).arg(m_gdbProc.errorString());
emitDelayedAdapterStartFailed(msg); // Emitted from QProcess::start() on Windows
} else {
// Others should trigger handleGdbFinished
const QString msg = QString::fromLatin1("GDB: Process error %1: %2").arg(error).arg(m_gdbProc.errorString());
logMessage(msg);
}
}
void TrkGdbAdapter::handleGdbFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
const QString msg = exitStatus == QProcess::NormalExit ?
QString::fromLatin1("GDB: Process finished (exit code: %1).").arg(exitCode) :
QString::fromLatin1("GDB: Process crashed: %1").arg(m_gdbProc.errorString());
if (state() == AdapterStarting) {
emitDelayedAdapterStartFailed(msg);// Potentially emitted from QProcess::start() on Windows
} else {
logMessage(msg);
emit adapterShutDown();
}
}
void TrkGdbAdapter::handleGdbStarted()
{
logMessage(QString("GDB: Process Started"));
maybeAdapterStarted();
}
void TrkGdbAdapter::maybeAdapterStarted()
{
QTC_ASSERT(state() == AdapterStarting, qDebug() << state());
if (m_gdbProc.state() == QProcess::Running && m_trkDevice.isOpen()) {
emit adapterStarted();
}
}
void TrkGdbAdapter::handleGdbStateChanged(QProcess::ProcessState newState)
{
logMessage(_("GDB: Process State %1").arg(newState));
}
void TrkGdbAdapter::startAdapter()
{
// Retrieve parameters
@@ -1632,13 +1573,12 @@ void TrkGdbAdapter::startAdapter()
connect(m_gdbServer, SIGNAL(newConnection()),
this, SLOT(handleGdbConnection()));
logMessage("STARTING GDB");
logMessage(_("### Starting gdb %1").arg(m_options->gdb));
QStringList gdbArgs;
gdbArgs.append(QLatin1String("--nx")); // Do not read .gdbinit file
gdbArgs.append(QLatin1String("-i"));
gdbArgs.append(QLatin1String("mi"));
m_gdbProc.start(m_options->gdb, gdbArgs);
if (!m_engine->startGdb(gdbArgs, m_options->gdb)) {
cleanup();
return;
}
waitForTrkConnect();
}
@@ -1792,7 +1732,7 @@ void TrkGdbAdapter::write(const QByteArray &data)
trkReadMemoryMessage(m_session.dataseg, 12));
return;
}
m_gdbProc.write(data);
m_engine->m_gdbProc.write(data);
}
uint oldPC;
@@ -1990,79 +1930,7 @@ void TrkGdbAdapter::cleanup()
void TrkGdbAdapter::shutdown()
{
switch (state()) {
case AdapterStarting:
case AdapterStartFailed:
cleanup();
setState(DebuggerNotReady);
return;
case InferiorStopping:
case InferiorRunningRequested:
case InferiorRunning:
//sendTrkMessage(0x1a, TrkCallback(), trkInterruptMessage(), "Interrupting...");
// Fall through.
case InferiorStopped:
//sendTrkMessage(0x41, TrkCallback(), trkDeleteProcessMessage(), "Delete process");
//sendTrkMessage(0x02, TrkCB(handleDisconnect));
setState(InferiorShuttingDown);
m_engine->postCommand(_("kill"), CB(handleKill));
return;
case InferiorShutDown:
setState(AdapterShuttingDown);
cleanup();
m_engine->postCommand(_("-gdb-exit"), GdbEngine::ExitRequest, CB(handleExit));
return;
/*
if (m_options->mode == TrkOptions::BlueTooth
&& m_rfcommProc.state() == QProcess::Running)
m_rfcommProc.kill();
m_rfcommProc.terminate();
m_rfcommProc.write(ba);
m_rfcommProc.terminate();
m_rfcommProc.waitForFinished();
m_gdbProc.kill();
m_gdbProc.terminate();
QByteArray ba;
ba.append(0x03);
QProcess proc;
proc.start("rfcomm release " + m_options->blueToothDevice);
proc.waitForFinished();
m_gdbProc.waitForFinished(msecs);
*/
default:
QTC_ASSERT(false, qDebug() << state());
}
}
void TrkGdbAdapter::handleKill(const GdbResponse &response)
{
if (response.resultClass == GdbResultDone) {
setState(InferiorShutDown);
emit inferiorShutDown();
shutdown(); // re-iterate...
} else {
const QString msg = msgInferiorStopFailed(__(response.data.findChild("msg").data()));
setState(InferiorShutdownFailed);
emit inferiorShutdownFailed(msg);
}
}
void TrkGdbAdapter::handleExit(const GdbResponse &response)
{
if (response.resultClass == GdbResultDone) {
qDebug() << "EXITED, NO MESSAGE...";
// don't set state here, this will be handled in handleGdbFinished()
} else {
const QString msg = msgGdbStopFailed(__(response.data.findChild("msg").data()));
emit adapterShutdownFailed(msg);
}
cleanup();
}
} // namespace Internal

View File

@@ -163,8 +163,6 @@ public:
//
void start(const QString &program, const QStringList &args,
QIODevice::OpenMode mode = QIODevice::ReadWrite);
QByteArray readAllStandardError();
QByteArray readAllStandardOutput();
void write(const QByteArray &data);
bool isTrkAdapter() const { return true; }
bool dumpersAvailable() const { return false; }
@@ -174,15 +172,12 @@ private:
void startInferior();
void interruptInferior();
void shutdown();
void cleanup();
void emitDelayedAdapterStartFailed(const QString &msg);
Q_SLOT void slotEmitDelayedAdapterStartFailed();
void emitDelayedInferiorStartFailed(const QString &msg);
Q_SLOT void slotEmitDelayedInferiorStartFailed();
Q_SLOT void waitForTrkConnect();
void handleKill(const GdbResponse &response);
void handleExit(const GdbResponse &response);
void handleTargetRemote(const GdbResponse &response);
void handleFirstContinue(const GdbResponse &response);
@@ -285,13 +280,6 @@ private:
bool sendGdbServerPacket(const QByteArray &packet, bool doFlush);
void tryAnswerGdbMemoryRequest(bool buffered);
Q_SLOT void handleGdbError(QProcess::ProcessError error);
Q_SLOT void handleGdbFinished(int exitCode, QProcess::ExitStatus exitStatus);
Q_SLOT void handleGdbStarted();
Q_SLOT void handleGdbStateChanged(QProcess::ProcessState newState);
void maybeAdapterStarted();
void logMessage(const QString &msg); // triggers output() if m_verbose
Q_SLOT void trkLogMessage(const QString &msg);

View File

@@ -123,7 +123,7 @@ public:
protected:
void showStatusMessage(const QString &msg, int timeout = -1);
DebuggerState state() const;
void setState(DebuggerState state);
void setState(DebuggerState state, bool forced = false);
DebuggerManager *manager() const { return m_manager; }
DebuggerManager *m_manager;