forked from qt-creator/qt-creator
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:
@@ -824,6 +824,9 @@ void CdbDebugEnginePrivate::processCreatedAttached(ULONG64 processHandle, ULONG6
|
|||||||
void CdbDebugEngine::processTerminated(unsigned long exitCode)
|
void CdbDebugEngine::processTerminated(unsigned long exitCode)
|
||||||
{
|
{
|
||||||
manager()->showDebuggerOutput(LogMisc, tr("The process exited with exit code %1.").arg(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__);
|
setState(InferiorShuttingDown, Q_FUNC_INFO, __LINE__);
|
||||||
m_d->setDebuggeeHandles(0, 0);
|
m_d->setDebuggeeHandles(0, 0);
|
||||||
m_d->clearForRun();
|
m_d->clearForRun();
|
||||||
@@ -919,14 +922,11 @@ void CdbDebugEnginePrivate::endDebugging(EndDebuggingMode em)
|
|||||||
errorMessage.clear();
|
errorMessage.clear();
|
||||||
}
|
}
|
||||||
// Clean up resources (open files, etc.)
|
// Clean up resources (open files, etc.)
|
||||||
m_engine->setState(AdapterShuttingDown, Q_FUNC_INFO, __LINE__);
|
m_engine->setState(EngineShuttingDown, Q_FUNC_INFO, __LINE__);
|
||||||
clearForRun();
|
clearForRun();
|
||||||
const HRESULT hr = m_cif.debugClient->EndSession(DEBUG_END_PASSIVE);
|
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));
|
errorMessage = QString::fromLatin1("There were errors trying to end debugging: %1").arg(msgComFailed("EndSession", hr));
|
||||||
manager()->showDebuggerOutput(LogError, errorMessage);
|
manager()->showDebuggerOutput(LogError, errorMessage);
|
||||||
}
|
}
|
||||||
|
@@ -79,15 +79,13 @@ enum DebuggerState
|
|||||||
|
|
||||||
InferiorStopping, // Debuggee running, stop requested
|
InferiorStopping, // Debuggee running, stop requested
|
||||||
InferiorStopped, // Debuggee stopped
|
InferiorStopped, // Debuggee stopped
|
||||||
InferiorStopFailed, // Debuggee stopped
|
InferiorStopFailed, // Debuggee not stopped, will kill debugger
|
||||||
|
|
||||||
InferiorShuttingDown,
|
InferiorShuttingDown,
|
||||||
InferiorShutDown,
|
InferiorShutDown,
|
||||||
InferiorShutdownFailed,
|
InferiorShutdownFailed,
|
||||||
|
|
||||||
AdapterShuttingDown,
|
EngineShuttingDown
|
||||||
//AdapterShutDown, // Use DebuggerNotReady instead
|
|
||||||
AdapterShutdownFailed,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum DebuggerStartMode
|
enum DebuggerStartMode
|
||||||
|
@@ -107,37 +107,29 @@
|
|||||||
// |
|
// |
|
||||||
// AdapterStarting --> AdapterStartFailed --> 0
|
// AdapterStarting --> AdapterStartFailed --> 0
|
||||||
// |
|
// |
|
||||||
// AdapterStarted
|
// AdapterStarted ------------------------------------.
|
||||||
// |
|
// | v
|
||||||
// InferiorStarting --> InferiorStartFailed --> 0
|
// InferiorStarting ----> InferiorStartFailed -------->|
|
||||||
// |
|
|
||||||
// (core) | (attach) (remote)
|
|
||||||
// .-----------------<-|->--------------------.
|
|
||||||
// | v |
|
|
||||||
// InferiorUnrunnable | |
|
|
||||||
// | | v
|
|
||||||
// | | (plain)
|
|
||||||
// | | (trk)
|
|
||||||
// | |
|
// | |
|
||||||
// | | .------------------------------------.
|
// (core) | (attach) (term) (remote) |
|
||||||
// | | v |
|
// .-----------------<-|->------------------. |
|
||||||
// | InferiorRunningRequested v |
|
// | v | |
|
||||||
|
// InferiorUnrunnable | (plain) | |
|
||||||
|
// | | (trk) | |
|
||||||
// | | | |
|
// | | | |
|
||||||
// | .---- InferiorRunning | |
|
// | .--> InferiorRunningRequested | |
|
||||||
|
// | | | | |
|
||||||
|
// | | InferiorRunning | |
|
||||||
// | | | | |
|
// | | | | |
|
||||||
// | | InferiorStopping | |
|
// | | InferiorStopping | |
|
||||||
// | | | | |
|
// | | | | |
|
||||||
// | v v | |
|
// | '------ InferiorStopped <-----------' |
|
||||||
// | |<--- InferiorStopped <-----------' |
|
// | | v
|
||||||
// | | | |
|
// | InferiorShuttingDown -> InferiorShutdownFailed ---->|
|
||||||
// | | `---------------------------------------'
|
// | | |
|
||||||
// | |
|
// | InferiorShutDown |
|
||||||
// | '---> InferiorShuttingDown -> InferiorShutdownFailed
|
// | | |
|
||||||
// | |
|
// '--------> EngineShuttingDown <--------------------------------'
|
||||||
// | InferiorShutDown
|
|
||||||
// | |
|
|
||||||
// | v
|
|
||||||
// '------------> AdapterShuttingDown -> AdapterShutdownFailed --> 0
|
|
||||||
// |
|
// |
|
||||||
// 0
|
// 0
|
||||||
//
|
//
|
||||||
@@ -208,8 +200,7 @@ static const char *stateName(int s)
|
|||||||
SN(InferiorShuttingDown)
|
SN(InferiorShuttingDown)
|
||||||
SN(InferiorShutDown)
|
SN(InferiorShutDown)
|
||||||
SN(InferiorShutdownFailed)
|
SN(InferiorShutdownFailed)
|
||||||
SN(AdapterShuttingDown)
|
SN(EngineShuttingDown)
|
||||||
SN(AdapterShutdownFailed)
|
|
||||||
}
|
}
|
||||||
return "<unknown>";
|
return "<unknown>";
|
||||||
#undef SN
|
#undef SN
|
||||||
@@ -1574,7 +1565,7 @@ static bool isAllowedTransition(int from, int to)
|
|||||||
case AdapterStarting:
|
case AdapterStarting:
|
||||||
return to == AdapterStarted || to == AdapterStartFailed;
|
return to == AdapterStarted || to == AdapterStartFailed;
|
||||||
case AdapterStarted:
|
case AdapterStarted:
|
||||||
return to == InferiorStarting;
|
return to == InferiorStarting || to == EngineShuttingDown;
|
||||||
case AdapterStartFailed:
|
case AdapterStartFailed:
|
||||||
return to == DebuggerNotReady;
|
return to == DebuggerNotReady;
|
||||||
|
|
||||||
@@ -1582,37 +1573,38 @@ static bool isAllowedTransition(int from, int to)
|
|||||||
return to == InferiorRunningRequested || to == InferiorStopped
|
return to == InferiorRunningRequested || to == InferiorStopped
|
||||||
|| to == InferiorStartFailed || to == InferiorUnrunnable;
|
|| to == InferiorStartFailed || to == InferiorUnrunnable;
|
||||||
case InferiorStartFailed:
|
case InferiorStartFailed:
|
||||||
return to == DebuggerNotReady;
|
return to == EngineShuttingDown;
|
||||||
|
|
||||||
case InferiorRunningRequested:
|
case InferiorRunningRequested:
|
||||||
return to == InferiorRunning;
|
return to == InferiorRunning;
|
||||||
case InferiorRunning:
|
case InferiorRunning:
|
||||||
return to == InferiorStopping || to == InferiorShuttingDown;
|
return to == InferiorStopping;
|
||||||
|
|
||||||
case InferiorStopping:
|
case InferiorStopping:
|
||||||
return to == InferiorStopped || to == InferiorStopFailed;
|
return to == InferiorStopped || to == InferiorStopFailed;
|
||||||
case InferiorStopped:
|
case InferiorStopped:
|
||||||
return to == InferiorRunningRequested || to == InferiorShuttingDown;
|
return to == InferiorRunningRequested || to == InferiorShuttingDown;
|
||||||
case InferiorStopFailed:
|
case InferiorStopFailed:
|
||||||
return to == DebuggerNotReady;
|
return to == EngineShuttingDown;
|
||||||
|
|
||||||
case InferiorUnrunnable:
|
case InferiorUnrunnable:
|
||||||
return to == AdapterShuttingDown;
|
return to == EngineShuttingDown;
|
||||||
case InferiorShuttingDown:
|
case InferiorShuttingDown:
|
||||||
return to == InferiorShutDown || to == InferiorShutdownFailed;
|
return to == InferiorShutDown || to == InferiorShutdownFailed;
|
||||||
case InferiorShutDown:
|
case InferiorShutDown:
|
||||||
return to == AdapterShuttingDown;
|
return to == EngineShuttingDown;
|
||||||
|
case InferiorShutdownFailed:
|
||||||
|
return to == EngineShuttingDown;
|
||||||
|
|
||||||
case AdapterShuttingDown:
|
case EngineShuttingDown:
|
||||||
return to == DebuggerNotReady;
|
return to == DebuggerNotReady;
|
||||||
|
|
||||||
default:
|
|
||||||
qDebug() << "UNKNOWN STATE: " << from;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qDebug() << "UNKNOWN STATE:" << from;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerManager::setState(DebuggerState state)
|
void DebuggerManager::setState(DebuggerState state, bool forced)
|
||||||
{
|
{
|
||||||
//STATE_DEBUG("STATUS CHANGE: FROM " << stateName(d->m_state)
|
//STATE_DEBUG("STATUS CHANGE: FROM " << stateName(d->m_state)
|
||||||
// << " TO " << stateName(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);
|
.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)))
|
//if (!((d->m_state == -1 && state == 0) || (d->m_state == 0 && state == 0)))
|
||||||
// qDebug() << msg;
|
// qDebug() << msg;
|
||||||
if (!isAllowedTransition(d->m_state, state))
|
if (!forced && !isAllowedTransition(d->m_state, state))
|
||||||
qDebug() << "UNEXPECTED STATE TRANSITION: " << msg;
|
qDebug() << "UNEXPECTED STATE TRANSITION: " << msg;
|
||||||
|
|
||||||
showDebuggerOutput(LogDebug, msg);
|
showDebuggerOutput(LogDebug, msg);
|
||||||
@@ -1715,8 +1707,7 @@ bool DebuggerManager::debuggerActionsEnabled() const
|
|||||||
case InferiorShuttingDown:
|
case InferiorShuttingDown:
|
||||||
case InferiorShutDown:
|
case InferiorShutDown:
|
||||||
case InferiorShutdownFailed:
|
case InferiorShutdownFailed:
|
||||||
case AdapterShuttingDown:
|
case EngineShuttingDown:
|
||||||
case AdapterShutdownFailed:
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -1793,9 +1784,9 @@ DebuggerState IDebuggerEngine::state() const
|
|||||||
return m_manager->state();
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
@@ -285,7 +285,7 @@ private:
|
|||||||
|
|
||||||
void cleanupViews();
|
void cleanupViews();
|
||||||
|
|
||||||
void setState(DebuggerState state);
|
void setState(DebuggerState state, bool forced = false);
|
||||||
|
|
||||||
//
|
//
|
||||||
// internal implementation
|
// internal implementation
|
||||||
|
@@ -47,35 +47,18 @@ AbstractGdbAdapter::~AbstractGdbAdapter()
|
|||||||
disconnect();
|
disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This cannot be in the c'tor, as it would not connect the "virtual" slots
|
void AbstractGdbAdapter::shutdown()
|
||||||
void AbstractGdbAdapter::commonInit()
|
|
||||||
{
|
{
|
||||||
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();
|
return "kill";
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray AbstractGdbAdapter::readAllStandardError()
|
|
||||||
{
|
|
||||||
return m_gdbProc.readAllStandardError();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractGdbAdapter::write(const QByteArray &data)
|
void AbstractGdbAdapter::write(const QByteArray &data)
|
||||||
{
|
{
|
||||||
m_gdbProc.write(data);
|
m_engine->m_gdbProc.write(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AbstractGdbAdapter::isTrkAdapter() const
|
bool AbstractGdbAdapter::isTrkAdapter() const
|
||||||
|
@@ -42,7 +42,7 @@ namespace Internal {
|
|||||||
// debugging and TrkGdbAdapter used for on-device debugging.
|
// debugging and TrkGdbAdapter used for on-device debugging.
|
||||||
// In the PlainGdbAdapter case it's just a wrapper around a QProcess running
|
// 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
|
// 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
|
class AbstractGdbAdapter : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -51,34 +51,39 @@ public:
|
|||||||
AbstractGdbAdapter(GdbEngine *engine, QObject *parent = 0);
|
AbstractGdbAdapter(GdbEngine *engine, QObject *parent = 0);
|
||||||
virtual ~AbstractGdbAdapter();
|
virtual ~AbstractGdbAdapter();
|
||||||
|
|
||||||
QByteArray readAllStandardOutput();
|
|
||||||
QByteArray readAllStandardError();
|
|
||||||
virtual void write(const QByteArray &data);
|
virtual void write(const QByteArray &data);
|
||||||
virtual bool isTrkAdapter() const; // isUtterlyBrokenAdapter
|
virtual bool isTrkAdapter() const; // isUtterlyBrokenAdapter
|
||||||
|
|
||||||
virtual void startAdapter() = 0;
|
virtual void startAdapter() = 0;
|
||||||
virtual void startInferior() = 0;
|
virtual void startInferior() = 0;
|
||||||
virtual void interruptInferior() = 0;
|
virtual void interruptInferior() = 0;
|
||||||
virtual void shutdown() = 0;
|
virtual void shutdown();
|
||||||
|
virtual const char *inferiorShutdownCommand() const;
|
||||||
|
|
||||||
virtual bool dumpersAvailable() const = 0;
|
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:
|
signals:
|
||||||
void adapterStarted();
|
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 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);
|
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 inferiorStartFailed(const QString &msg);
|
||||||
void inferiorShutDown();
|
|
||||||
void inferiorShutdownFailed(const QString &msg);
|
|
||||||
|
|
||||||
void readyReadStandardOutput();
|
|
||||||
void readyReadStandardError();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void commonInit();
|
|
||||||
DebuggerState state() const
|
DebuggerState state() const
|
||||||
{ return m_engine->state(); }
|
{ return m_engine->state(); }
|
||||||
void setState(DebuggerState state)
|
void setState(DebuggerState state)
|
||||||
@@ -90,16 +95,7 @@ protected:
|
|||||||
void showStatusMessage(const QString &msg) const
|
void showStatusMessage(const QString &msg) const
|
||||||
{ m_engine->showStatusMessage(msg); }
|
{ 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;
|
GdbEngine * const m_engine;
|
||||||
|
|
||||||
QProcess m_gdbProc;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -53,7 +53,6 @@ namespace Internal {
|
|||||||
AttachGdbAdapter::AttachGdbAdapter(GdbEngine *engine, QObject *parent)
|
AttachGdbAdapter::AttachGdbAdapter(GdbEngine *engine, QObject *parent)
|
||||||
: AbstractGdbAdapter(engine, parent)
|
: AbstractGdbAdapter(engine, parent)
|
||||||
{
|
{
|
||||||
commonInit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttachGdbAdapter::startAdapter()
|
void AttachGdbAdapter::startAdapter()
|
||||||
@@ -62,27 +61,12 @@ void AttachGdbAdapter::startAdapter()
|
|||||||
setState(AdapterStarting);
|
setState(AdapterStarting);
|
||||||
debugMessage(_("TRYING TO START ADAPTER"));
|
debugMessage(_("TRYING TO START ADAPTER"));
|
||||||
|
|
||||||
QStringList gdbArgs;
|
if (!m_engine->startGdb())
|
||||||
gdbArgs.prepend(_("mi"));
|
return;
|
||||||
gdbArgs.prepend(_("-i"));
|
|
||||||
|
|
||||||
QString location = theDebuggerStringSetting(GdbLocation);
|
|
||||||
m_gdbProc.start(location, gdbArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AttachGdbAdapter::handleGdbStarted()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(state() == AdapterStarting, qDebug() << state());
|
|
||||||
emit adapterStarted();
|
emit adapterStarted();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttachGdbAdapter::handleGdbError(QProcess::ProcessError error)
|
|
||||||
{
|
|
||||||
debugMessage(_("PLAIN ADAPTER, HANDLE GDB ERROR"));
|
|
||||||
emit adapterCrashed(m_engine->errorMessage(error));
|
|
||||||
shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AttachGdbAdapter::startInferior()
|
void AttachGdbAdapter::startInferior()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == InferiorStarting, qDebug() << state());
|
QTC_ASSERT(state() == InferiorStarting, qDebug() << state());
|
||||||
@@ -113,58 +97,5 @@ void AttachGdbAdapter::interruptInferior()
|
|||||||
debugMessage(_("CANNOT INTERRUPT %1").arg(pid));
|
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 Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
@@ -57,16 +57,10 @@ public:
|
|||||||
void startAdapter();
|
void startAdapter();
|
||||||
void startInferior();
|
void startInferior();
|
||||||
void interruptInferior();
|
void interruptInferior();
|
||||||
void shutdown();
|
const char *inferiorShutdownCommand() const { return "detach"; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handleAttach(const GdbResponse &response);
|
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
|
} // namespace Internal
|
||||||
|
@@ -53,7 +53,6 @@ namespace Internal {
|
|||||||
CoreGdbAdapter::CoreGdbAdapter(GdbEngine *engine, QObject *parent)
|
CoreGdbAdapter::CoreGdbAdapter(GdbEngine *engine, QObject *parent)
|
||||||
: AbstractGdbAdapter(engine, parent)
|
: AbstractGdbAdapter(engine, parent)
|
||||||
{
|
{
|
||||||
commonInit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoreGdbAdapter::startAdapter()
|
void CoreGdbAdapter::startAdapter()
|
||||||
@@ -62,27 +61,12 @@ void CoreGdbAdapter::startAdapter()
|
|||||||
setState(AdapterStarting);
|
setState(AdapterStarting);
|
||||||
debugMessage(_("TRYING TO START ADAPTER"));
|
debugMessage(_("TRYING TO START ADAPTER"));
|
||||||
|
|
||||||
QStringList gdbArgs;
|
if (!m_engine->startGdb())
|
||||||
gdbArgs.prepend(_("mi"));
|
return;
|
||||||
gdbArgs.prepend(_("-i"));
|
|
||||||
|
|
||||||
QString location = theDebuggerStringSetting(GdbLocation);
|
|
||||||
m_gdbProc.start(location, gdbArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CoreGdbAdapter::handleGdbStarted()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(state() == AdapterStarting, qDebug() << state());
|
|
||||||
emit adapterStarted();
|
emit adapterStarted();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoreGdbAdapter::handleGdbError(QProcess::ProcessError error)
|
|
||||||
{
|
|
||||||
debugMessage(_("PLAIN ADAPTER, HANDLE GDB ERROR"));
|
|
||||||
emit adapterCrashed(m_engine->errorMessage(error));
|
|
||||||
shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CoreGdbAdapter::startInferior()
|
void CoreGdbAdapter::startInferior()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == InferiorStarting, qDebug() << state());
|
QTC_ASSERT(state() == InferiorStarting, qDebug() << state());
|
||||||
@@ -175,45 +159,12 @@ void CoreGdbAdapter::handleTargetCore2(const GdbResponse &response)
|
|||||||
// emit inferiorStartFailed(msg);
|
// emit inferiorStartFailed(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoreGdbAdapter::interruptInferior()
|
void CoreGdbAdapter::interruptInferior()
|
||||||
{
|
{
|
||||||
// A core should never 'run'
|
// A core should never 'run'
|
||||||
QTC_ASSERT(false, /**/);
|
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 Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
@@ -57,18 +57,12 @@ public:
|
|||||||
void startAdapter();
|
void startAdapter();
|
||||||
void startInferior();
|
void startInferior();
|
||||||
void interruptInferior();
|
void interruptInferior();
|
||||||
void shutdown();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handleTargetCore1(const GdbResponse &response);
|
void handleTargetCore1(const GdbResponse &response);
|
||||||
void handleDetach1(const GdbResponse &response);
|
void handleDetach1(const GdbResponse &response);
|
||||||
void handleFileExecAndSymbols(const GdbResponse &response);
|
void handleFileExecAndSymbols(const GdbResponse &response);
|
||||||
void handleTargetCore2(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;
|
QString m_executable;
|
||||||
};
|
};
|
||||||
|
@@ -105,17 +105,29 @@ namespace Internal {
|
|||||||
|
|
||||||
static bool stateAcceptsGdbCommands(DebuggerState state)
|
static bool stateAcceptsGdbCommands(DebuggerState state)
|
||||||
{
|
{
|
||||||
return state == AdapterStarted
|
switch (state) {
|
||||||
|| state == InferiorUnrunnable
|
case AdapterStarting:
|
||||||
|| state == InferiorStarting
|
case AdapterStarted:
|
||||||
|| state == InferiorRunningRequested
|
case AdapterStartFailed:
|
||||||
|| state == InferiorRunning
|
case InferiorUnrunnable:
|
||||||
|| state == InferiorStopping
|
case InferiorStarting:
|
||||||
|| state == InferiorStopped
|
case InferiorStartFailed:
|
||||||
|| state == InferiorShuttingDown
|
case InferiorRunningRequested:
|
||||||
|| state == InferiorShutDown
|
case InferiorRunning:
|
||||||
|| state == AdapterShuttingDown;
|
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 ¤tToken()
|
static int ¤tToken()
|
||||||
{
|
{
|
||||||
@@ -217,27 +229,13 @@ GdbEngine::~GdbEngine()
|
|||||||
|
|
||||||
void GdbEngine::connectAdapter()
|
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()),
|
connect(m_gdbAdapter, SIGNAL(adapterStarted()),
|
||||||
this, SLOT(handleAdapterStarted()));
|
this, SLOT(handleAdapterStarted()));
|
||||||
connect(m_gdbAdapter, SIGNAL(adapterStartFailed(QString,QString)),
|
connect(m_gdbAdapter, SIGNAL(adapterStartFailed(QString,QString)),
|
||||||
this, SLOT(handleAdapterStartFailed(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)),
|
connect(m_gdbAdapter, SIGNAL(inferiorStartFailed(QString)),
|
||||||
this, SLOT(handleInferiorStartFailed(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)),
|
connect(m_gdbAdapter, SIGNAL(adapterCrashed(QString)),
|
||||||
this, SLOT(handleAdapterCrashed(QString)));
|
this, SLOT(handleAdapterCrashed(QString)));
|
||||||
@@ -571,7 +569,7 @@ void GdbEngine::handleResponse(const QByteArray &buff)
|
|||||||
|
|
||||||
void GdbEngine::readGdbStandardError()
|
void GdbEngine::readGdbStandardError()
|
||||||
{
|
{
|
||||||
qWarning() << "Unexpected gdb stderr:" << m_gdbAdapter->readAllStandardError();
|
qWarning() << "Unexpected gdb stderr:" << m_gdbProc.readAllStandardError();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::readGdbStandardOutput()
|
void GdbEngine::readGdbStandardOutput()
|
||||||
@@ -579,7 +577,7 @@ void GdbEngine::readGdbStandardOutput()
|
|||||||
int newstart = 0;
|
int newstart = 0;
|
||||||
int scan = m_inbuffer.size();
|
int scan = m_inbuffer.size();
|
||||||
|
|
||||||
m_inbuffer.append(m_gdbAdapter->readAllStandardOutput());
|
m_inbuffer.append(m_gdbProc.readAllStandardOutput());
|
||||||
|
|
||||||
while (newstart < m_inbuffer.size()) {
|
while (newstart < m_inbuffer.size()) {
|
||||||
int start = newstart;
|
int start = newstart;
|
||||||
@@ -1366,8 +1364,73 @@ QString GdbEngine::fullName(const QStringList &candidates)
|
|||||||
void GdbEngine::shutdown()
|
void GdbEngine::shutdown()
|
||||||
{
|
{
|
||||||
debugMessage(_("INITIATE GDBENGINE SHUTDOWN"));
|
debugMessage(_("INITIATE GDBENGINE SHUTDOWN"));
|
||||||
initializeVariables();
|
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();
|
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()
|
void GdbEngine::detachDebugger()
|
||||||
@@ -1383,8 +1446,7 @@ void GdbEngine::detachDebugger()
|
|||||||
void GdbEngine::exitDebugger() // called from the manager
|
void GdbEngine::exitDebugger() // called from the manager
|
||||||
{
|
{
|
||||||
disconnectDebuggingHelperActions();
|
disconnectDebuggingHelperActions();
|
||||||
initializeVariables();
|
shutdown();
|
||||||
m_gdbAdapter->shutdown();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int GdbEngine::currentFrame() const
|
int GdbEngine::currentFrame() const
|
||||||
@@ -1445,17 +1507,17 @@ void GdbEngine::startDebugger(const DebuggerStartParametersPtr &sp)
|
|||||||
// initializeVariables());
|
// initializeVariables());
|
||||||
//QTC_ASSERT(m_gdbAdapter == 0, delete m_gdbAdapter; m_gdbAdapter = 0);
|
//QTC_ASSERT(m_gdbAdapter == 0, delete m_gdbAdapter; m_gdbAdapter = 0);
|
||||||
|
|
||||||
|
initializeVariables();
|
||||||
|
|
||||||
m_startParameters = sp;
|
m_startParameters = sp;
|
||||||
|
|
||||||
delete m_gdbAdapter;
|
delete m_gdbAdapter;
|
||||||
m_gdbAdapter = createAdapter(sp);
|
m_gdbAdapter = createAdapter(sp);
|
||||||
|
connectAdapter();
|
||||||
|
|
||||||
if (startModeAllowsDumpers())
|
if (startModeAllowsDumpers())
|
||||||
connectDebuggingHelperActions();
|
connectDebuggingHelperActions();
|
||||||
|
|
||||||
initializeVariables();
|
|
||||||
connectAdapter();
|
|
||||||
|
|
||||||
m_gdbAdapter->startAdapter();
|
m_gdbAdapter->startAdapter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4089,19 +4151,37 @@ void GdbEngine::gotoLocation(const StackFrame &frame, bool setMarker)
|
|||||||
// Starting up & shutting down
|
// 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(_("STARTING GDB ") + gdb);
|
||||||
debugMessage(_("ADAPTER START FAILED"));
|
|
||||||
Core::ICore::instance()->showWarningWithOptions(tr("Adapter start failed"), msg, QString(),
|
|
||||||
QLatin1String(Debugger::Constants::DEBUGGER_SETTINGS_CATEGORY), settingsIdHint);
|
|
||||||
shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GdbEngine::handleAdapterStarted()
|
m_gdbProc.disconnect(); // From any previous runs
|
||||||
{
|
|
||||||
setState(AdapterStarted);
|
QString location = gdb;
|
||||||
debugMessage(_("ADAPTER SUCCESSFULLY STARTED, INITIALIZING 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(_("show version"), CB(handleShowVersion));
|
||||||
postCommand(_("help bb"), CB(handleIsSynchroneous));
|
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
|
// Initial attempt to set breakpoints
|
||||||
showStatusMessage(tr("Setting breakpoints..."));
|
showStatusMessage(tr("Setting breakpoints..."));
|
||||||
attemptBreakpointSynchronization();
|
attemptBreakpointSynchronization();
|
||||||
|
|
||||||
|
if (m_cookieForToken.isEmpty()) {
|
||||||
|
startInferior();
|
||||||
|
} else {
|
||||||
QTC_ASSERT(m_commandsDoneCallback == 0, /**/);
|
QTC_ASSERT(m_commandsDoneCallback == 0, /**/);
|
||||||
m_commandsDoneCallback = &GdbEngine::startInferior;
|
m_commandsDoneCallback = &GdbEngine::startInferior;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::startInferior()
|
void GdbEngine::startInferior()
|
||||||
@@ -4209,48 +4346,23 @@ void GdbEngine::handleInferiorStartFailed(const QString &msg)
|
|||||||
shutdown();
|
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)
|
void GdbEngine::handleAdapterCrashed(const QString &msg)
|
||||||
{
|
{
|
||||||
debugMessage(_("ADAPTER CRASHED"));
|
debugMessage(_("ADAPTER CRASHED"));
|
||||||
switch (state()) {
|
|
||||||
// All fall-through.
|
// The adapter is expected to have cleaned up after itself when we get here,
|
||||||
case InferiorRunning:
|
// so the effect is about the same as AdapterStartFailed => use it.
|
||||||
setState(InferiorShuttingDown);
|
// Don't bother with state transitions - this can happen in any state and
|
||||||
case InferiorShuttingDown:
|
// the end result is always the same, so it makes little sense to find a
|
||||||
setState(InferiorShutDown);
|
// "path" which does not assert.
|
||||||
case InferiorShutDown:
|
setState(AdapterStartFailed, true);
|
||||||
setState(AdapterShuttingDown);
|
|
||||||
default:
|
// No point in being friendly here ...
|
||||||
setState(DebuggerNotReady);
|
m_gdbProc.terminate();
|
||||||
}
|
|
||||||
showMessageBox(QMessageBox::Critical, tr("Adapter crashed"), msg);
|
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
|
void GdbEngine::addOptionPages(QList<Core::IOptionsPage*> *opts) const
|
||||||
{
|
{
|
||||||
opts->push_back(new GdbOptionsPage);
|
opts->push_back(new GdbOptionsPage);
|
||||||
|
@@ -125,14 +125,20 @@ private: ////////// Gdb Process Management //////////
|
|||||||
|
|
||||||
AbstractGdbAdapter *createAdapter(const DebuggerStartParametersPtr &dp);
|
AbstractGdbAdapter *createAdapter(const DebuggerStartParametersPtr &dp);
|
||||||
void connectAdapter();
|
void connectAdapter();
|
||||||
|
bool startGdb(const QStringList &args = QStringList(), const QString &gdb = QString());
|
||||||
void startInferior();
|
void startInferior();
|
||||||
|
|
||||||
|
void handleInferiorShutdown(const GdbResponse &response);
|
||||||
|
void handleGdbExit(const GdbResponse &response);
|
||||||
|
|
||||||
void gdbInputAvailable(int channel, const QString &msg)
|
void gdbInputAvailable(int channel, const QString &msg)
|
||||||
{ m_manager->showDebuggerInput(channel, msg); }
|
{ m_manager->showDebuggerInput(channel, msg); }
|
||||||
void gdbOutputAvailable(int channel, const QString &msg)
|
void gdbOutputAvailable(int channel, const QString &msg)
|
||||||
{ m_manager->showDebuggerOutput(channel, msg); }
|
{ m_manager->showDebuggerOutput(channel, msg); }
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
void handleGdbFinished(int, QProcess::ExitStatus status);
|
||||||
|
void handleGdbError(QProcess::ProcessError error);
|
||||||
void readGdbStandardOutput();
|
void readGdbStandardOutput();
|
||||||
void readGdbStandardError();
|
void readGdbStandardError();
|
||||||
void readDebugeeOutput(const QByteArray &data);
|
void readDebugeeOutput(const QByteArray &data);
|
||||||
@@ -141,12 +147,8 @@ private slots:
|
|||||||
void handleAdapterStartFailed(const QString &msg, const QString &settingsIdHint = QString());
|
void handleAdapterStartFailed(const QString &msg, const QString &settingsIdHint = QString());
|
||||||
|
|
||||||
void handleInferiorStartFailed(const QString &msg);
|
void handleInferiorStartFailed(const QString &msg);
|
||||||
void handleInferiorShutDown();
|
|
||||||
void handleInferiorShutdownFailed(const QString &msg);
|
|
||||||
|
|
||||||
void handleAdapterCrashed(const QString &msg);
|
void handleAdapterCrashed(const QString &msg);
|
||||||
void handleAdapterShutDown();
|
|
||||||
void handleAdapterShutdownFailed(const QString &msg);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QTextCodec *m_outputCodec;
|
QTextCodec *m_outputCodec;
|
||||||
@@ -154,6 +156,7 @@ private:
|
|||||||
|
|
||||||
QByteArray m_inbuffer;
|
QByteArray m_inbuffer;
|
||||||
|
|
||||||
|
QProcess m_gdbProc;
|
||||||
AbstractGdbAdapter *m_gdbAdapter;
|
AbstractGdbAdapter *m_gdbAdapter;
|
||||||
|
|
||||||
private: ////////// Gdb Command Management //////////
|
private: ////////// Gdb Command Management //////////
|
||||||
|
@@ -58,8 +58,6 @@ namespace Internal {
|
|||||||
PlainGdbAdapter::PlainGdbAdapter(GdbEngine *engine, QObject *parent)
|
PlainGdbAdapter::PlainGdbAdapter(GdbEngine *engine, QObject *parent)
|
||||||
: AbstractGdbAdapter(engine, parent)
|
: AbstractGdbAdapter(engine, parent)
|
||||||
{
|
{
|
||||||
commonInit();
|
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
connect(&m_outputCollector, SIGNAL(byteDelivery(QByteArray)),
|
connect(&m_outputCollector, SIGNAL(byteDelivery(QByteArray)),
|
||||||
engine, SLOT(readDebugeeOutput(QByteArray)));
|
engine, SLOT(readDebugeeOutput(QByteArray)));
|
||||||
@@ -72,36 +70,27 @@ void PlainGdbAdapter::startAdapter()
|
|||||||
debugMessage(_("TRYING TO START ADAPTER"));
|
debugMessage(_("TRYING TO START ADAPTER"));
|
||||||
|
|
||||||
QStringList gdbArgs;
|
QStringList gdbArgs;
|
||||||
gdbArgs.prepend(_("mi"));
|
|
||||||
gdbArgs.prepend(_("-i"));
|
|
||||||
|
|
||||||
if (!m_outputCollector.listen()) {
|
if (!m_outputCollector.listen()) {
|
||||||
emit adapterStartFailed(tr("Cannot set up communication with child process: %1")
|
emit adapterStartFailed(tr("Cannot set up communication with child process: %1")
|
||||||
.arg(m_outputCollector.errorString()), QString());
|
.arg(m_outputCollector.errorString()), QString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gdbArgs.prepend(_("--tty=") + m_outputCollector.serverName());
|
gdbArgs.append(_("--tty=") + m_outputCollector.serverName());
|
||||||
|
|
||||||
if (!startParameters().workingDir.isEmpty())
|
if (!startParameters().workingDir.isEmpty())
|
||||||
m_gdbProc.setWorkingDirectory(startParameters().workingDir);
|
m_engine->m_gdbProc.setWorkingDirectory(startParameters().workingDir);
|
||||||
if (!startParameters().environment.isEmpty())
|
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();
|
emit adapterStarted();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlainGdbAdapter::handleGdbError(QProcess::ProcessError error)
|
|
||||||
{
|
|
||||||
debugMessage(_("PLAIN ADAPTER, HANDLE GDB ERROR"));
|
|
||||||
emit adapterCrashed(m_engine->errorMessage(error));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlainGdbAdapter::startInferior()
|
void PlainGdbAdapter::startInferior()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(state() == InferiorStarting, qDebug() << state());
|
QTC_ASSERT(state() == InferiorStarting, qDebug() << state());
|
||||||
@@ -159,74 +148,6 @@ void PlainGdbAdapter::shutdown()
|
|||||||
{
|
{
|
||||||
debugMessage(_("PLAIN ADAPTER SHUTDOWN %1").arg(state()));
|
debugMessage(_("PLAIN ADAPTER SHUTDOWN %1").arg(state()));
|
||||||
m_outputCollector.shutdown();
|
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
|
} // namespace Internal
|
||||||
|
@@ -59,17 +59,12 @@ public:
|
|||||||
void startInferior();
|
void startInferior();
|
||||||
void interruptInferior();
|
void interruptInferior();
|
||||||
void shutdown();
|
void shutdown();
|
||||||
|
const char *inferiorShutdownCommand() const { return "kill"; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void handleFileExecAndSymbols(const GdbResponse &response);
|
void handleFileExecAndSymbols(const GdbResponse &response);
|
||||||
void handleKill(const GdbResponse &response);
|
|
||||||
void handleExit(const GdbResponse &response);
|
|
||||||
void handleExecRun(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;
|
OutputCollector m_outputCollector;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -54,8 +54,6 @@ namespace Internal {
|
|||||||
RemoteGdbAdapter::RemoteGdbAdapter(GdbEngine *engine, QObject *parent)
|
RemoteGdbAdapter::RemoteGdbAdapter(GdbEngine *engine, QObject *parent)
|
||||||
: AbstractGdbAdapter(engine, parent)
|
: AbstractGdbAdapter(engine, parent)
|
||||||
{
|
{
|
||||||
commonInit();
|
|
||||||
|
|
||||||
connect(&m_uploadProc, SIGNAL(error(QProcess::ProcessError)),
|
connect(&m_uploadProc, SIGNAL(error(QProcess::ProcessError)),
|
||||||
this, SLOT(uploadProcError(QProcess::ProcessError)));
|
this, SLOT(uploadProcError(QProcess::ProcessError)));
|
||||||
connect(&m_uploadProc, SIGNAL(readyReadStandardOutput()),
|
connect(&m_uploadProc, SIGNAL(readyReadStandardOutput()),
|
||||||
@@ -70,12 +68,6 @@ void RemoteGdbAdapter::startAdapter()
|
|||||||
setState(AdapterStarting);
|
setState(AdapterStarting);
|
||||||
debugMessage(_("TRYING TO START ADAPTER"));
|
debugMessage(_("TRYING TO START ADAPTER"));
|
||||||
|
|
||||||
QStringList gdbArgs;
|
|
||||||
gdbArgs.prepend(_("mi"));
|
|
||||||
gdbArgs.prepend(_("-i"));
|
|
||||||
|
|
||||||
QString location = theDebuggerStringSetting(GdbLocation);
|
|
||||||
|
|
||||||
// FIXME: make asynchroneous
|
// FIXME: make asynchroneous
|
||||||
// Start the remote server
|
// Start the remote server
|
||||||
if (startParameters().serverStartScript.isEmpty()) {
|
if (startParameters().serverStartScript.isEmpty()) {
|
||||||
@@ -86,23 +78,13 @@ void RemoteGdbAdapter::startAdapter()
|
|||||||
m_uploadProc.waitForStarted();
|
m_uploadProc.waitForStarted();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start the debugger
|
if (!m_engine->startGdb())
|
||||||
m_gdbProc.start(location, gdbArgs);
|
// FIXME: cleanup missing
|
||||||
}
|
return;
|
||||||
|
|
||||||
void RemoteGdbAdapter::handleGdbStarted()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(state() == AdapterStarting, qDebug() << state());
|
|
||||||
emit adapterStarted();
|
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)
|
void RemoteGdbAdapter::uploadProcError(QProcess::ProcessError error)
|
||||||
{
|
{
|
||||||
QString msg;
|
QString msg;
|
||||||
@@ -232,55 +214,7 @@ void RemoteGdbAdapter::interruptInferior()
|
|||||||
|
|
||||||
void RemoteGdbAdapter::shutdown()
|
void RemoteGdbAdapter::shutdown()
|
||||||
{
|
{
|
||||||
switch (state()) {
|
// FIXME: cleanup missing
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -69,12 +69,6 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
void handleFileExecAndSymbols(const GdbResponse &response);
|
void handleFileExecAndSymbols(const GdbResponse &response);
|
||||||
void handleTargetRemote(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;
|
QProcess m_uploadProc;
|
||||||
};
|
};
|
||||||
|
@@ -204,10 +204,6 @@ TrkGdbAdapter::TrkGdbAdapter(GdbEngine *engine, const TrkOptionsPtr &options) :
|
|||||||
#endif
|
#endif
|
||||||
m_gdbServerName = _("127.0.0.1:%1").arg(2222 + portOffset);
|
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()),
|
connect(&m_rfcommProc, SIGNAL(readyReadStandardError()),
|
||||||
this, SLOT(handleRfcommReadyReadStandardError()));
|
this, SLOT(handleRfcommReadyReadStandardError()));
|
||||||
connect(&m_rfcommProc, SIGNAL(readyReadStandardOutput()),
|
connect(&m_rfcommProc, SIGNAL(readyReadStandardOutput()),
|
||||||
@@ -380,17 +376,6 @@ QByteArray TrkGdbAdapter::trkInterruptMessage()
|
|||||||
return ba;
|
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)
|
void TrkGdbAdapter::emitDelayedInferiorStartFailed(const QString &msg)
|
||||||
{
|
{
|
||||||
m_adapterFailMessage = msg;
|
m_adapterFailMessage = msg;
|
||||||
@@ -437,7 +422,7 @@ void TrkGdbAdapter::waitForTrkConnect()
|
|||||||
// "10 " + formatString("C:\\data\\usingdlls.sisx")); // Open File
|
// "10 " + formatString("C:\\data\\usingdlls.sisx")); // Open File
|
||||||
//sendTrkMessage(0x4B, 0, "00 00 00 01 73 1C 3A C8"); // Close File
|
//sendTrkMessage(0x4B, 0, "00 00 00 01 73 1C 3A C8"); // Close File
|
||||||
|
|
||||||
maybeAdapterStarted();
|
emit adapterStarted();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrkGdbAdapter::logMessage(const QString &msg)
|
void TrkGdbAdapter::logMessage(const QString &msg)
|
||||||
@@ -1527,50 +1512,6 @@ void TrkGdbAdapter::interruptInferior()
|
|||||||
sendTrkMessage(0x1a, TrkCallback(), trkInterruptMessage(), "Interrupting...");
|
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()
|
void TrkGdbAdapter::startAdapter()
|
||||||
{
|
{
|
||||||
// Retrieve parameters
|
// Retrieve parameters
|
||||||
@@ -1632,13 +1573,12 @@ void TrkGdbAdapter::startAdapter()
|
|||||||
connect(m_gdbServer, SIGNAL(newConnection()),
|
connect(m_gdbServer, SIGNAL(newConnection()),
|
||||||
this, SLOT(handleGdbConnection()));
|
this, SLOT(handleGdbConnection()));
|
||||||
|
|
||||||
logMessage("STARTING GDB");
|
|
||||||
logMessage(_("### Starting gdb %1").arg(m_options->gdb));
|
|
||||||
QStringList gdbArgs;
|
QStringList gdbArgs;
|
||||||
gdbArgs.append(QLatin1String("--nx")); // Do not read .gdbinit file
|
gdbArgs.append(QLatin1String("--nx")); // Do not read .gdbinit file
|
||||||
gdbArgs.append(QLatin1String("-i"));
|
if (!m_engine->startGdb(gdbArgs, m_options->gdb)) {
|
||||||
gdbArgs.append(QLatin1String("mi"));
|
cleanup();
|
||||||
m_gdbProc.start(m_options->gdb, gdbArgs);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
waitForTrkConnect();
|
waitForTrkConnect();
|
||||||
}
|
}
|
||||||
@@ -1792,7 +1732,7 @@ void TrkGdbAdapter::write(const QByteArray &data)
|
|||||||
trkReadMemoryMessage(m_session.dataseg, 12));
|
trkReadMemoryMessage(m_session.dataseg, 12));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_gdbProc.write(data);
|
m_engine->m_gdbProc.write(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint oldPC;
|
uint oldPC;
|
||||||
@@ -1990,79 +1930,7 @@ void TrkGdbAdapter::cleanup()
|
|||||||
|
|
||||||
void TrkGdbAdapter::shutdown()
|
void TrkGdbAdapter::shutdown()
|
||||||
{
|
{
|
||||||
switch (state()) {
|
|
||||||
case AdapterStarting:
|
|
||||||
case AdapterStartFailed:
|
|
||||||
cleanup();
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -163,8 +163,6 @@ public:
|
|||||||
//
|
//
|
||||||
void start(const QString &program, const QStringList &args,
|
void start(const QString &program, const QStringList &args,
|
||||||
QIODevice::OpenMode mode = QIODevice::ReadWrite);
|
QIODevice::OpenMode mode = QIODevice::ReadWrite);
|
||||||
QByteArray readAllStandardError();
|
|
||||||
QByteArray readAllStandardOutput();
|
|
||||||
void write(const QByteArray &data);
|
void write(const QByteArray &data);
|
||||||
bool isTrkAdapter() const { return true; }
|
bool isTrkAdapter() const { return true; }
|
||||||
bool dumpersAvailable() const { return false; }
|
bool dumpersAvailable() const { return false; }
|
||||||
@@ -174,15 +172,12 @@ private:
|
|||||||
void startInferior();
|
void startInferior();
|
||||||
void interruptInferior();
|
void interruptInferior();
|
||||||
void shutdown();
|
void shutdown();
|
||||||
|
|
||||||
void cleanup();
|
void cleanup();
|
||||||
void emitDelayedAdapterStartFailed(const QString &msg);
|
|
||||||
Q_SLOT void slotEmitDelayedAdapterStartFailed();
|
|
||||||
void emitDelayedInferiorStartFailed(const QString &msg);
|
void emitDelayedInferiorStartFailed(const QString &msg);
|
||||||
Q_SLOT void slotEmitDelayedInferiorStartFailed();
|
Q_SLOT void slotEmitDelayedInferiorStartFailed();
|
||||||
|
|
||||||
Q_SLOT void waitForTrkConnect();
|
Q_SLOT void waitForTrkConnect();
|
||||||
void handleKill(const GdbResponse &response);
|
|
||||||
void handleExit(const GdbResponse &response);
|
|
||||||
void handleTargetRemote(const GdbResponse &response);
|
void handleTargetRemote(const GdbResponse &response);
|
||||||
void handleFirstContinue(const GdbResponse &response);
|
void handleFirstContinue(const GdbResponse &response);
|
||||||
|
|
||||||
@@ -285,13 +280,6 @@ private:
|
|||||||
bool sendGdbServerPacket(const QByteArray &packet, bool doFlush);
|
bool sendGdbServerPacket(const QByteArray &packet, bool doFlush);
|
||||||
void tryAnswerGdbMemoryRequest(bool buffered);
|
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
|
void logMessage(const QString &msg); // triggers output() if m_verbose
|
||||||
Q_SLOT void trkLogMessage(const QString &msg);
|
Q_SLOT void trkLogMessage(const QString &msg);
|
||||||
|
|
||||||
|
@@ -123,7 +123,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
void showStatusMessage(const QString &msg, int timeout = -1);
|
void showStatusMessage(const QString &msg, int timeout = -1);
|
||||||
DebuggerState state() const;
|
DebuggerState state() const;
|
||||||
void setState(DebuggerState state);
|
void setState(DebuggerState state, bool forced = false);
|
||||||
DebuggerManager *manager() const { return m_manager; }
|
DebuggerManager *manager() const { return m_manager; }
|
||||||
DebuggerManager *m_manager;
|
DebuggerManager *m_manager;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user