Fix Trk error handling

Do not close a trk device from its read handler, wire messages
correctly. TrkDevice: Terminate threads before closing.
This commit is contained in:
Friedemann Kleint
2009-10-05 15:07:47 +02:00
parent db9a390ef6
commit d38f654d53
5 changed files with 48 additions and 22 deletions

View File

@@ -143,7 +143,7 @@ TrkGdbAdapter::TrkGdbAdapter(GdbEngine *engine, const TrkOptionsPtr &options) :
TrkGdbAdapter::~TrkGdbAdapter() TrkGdbAdapter::~TrkGdbAdapter()
{ {
delete m_gdbServer; cleanup();
logMessage("Shutting down.\n"); logMessage("Shutting down.\n");
} }
@@ -283,6 +283,17 @@ 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);
}
void TrkGdbAdapter::startInferiorEarly() void TrkGdbAdapter::startInferiorEarly()
{ {
QTC_ASSERT(state() == AdapterStarting, qDebug() << state()); QTC_ASSERT(state() == AdapterStarting, qDebug() << state());
@@ -1063,8 +1074,9 @@ void TrkGdbAdapter::handleCreateProcess(const TrkResult &result)
logMessage("ERROR: " + result.errorString()); logMessage("ERROR: " + result.errorString());
QString msg = _("Cannot start executable \"%1\" on the device:\n%2") QString msg = _("Cannot start executable \"%1\" on the device:\n%2")
.arg(m_remoteExecutable).arg(result.errorString()); .arg(m_remoteExecutable).arg(result.errorString());
//m_trkDevice.close(); // Delay cleanup as not to close a trk device from its read handler,
emit adapterStartFailed(msg); // which blocks.
emitDelayedAdapterStartFailed(msg);
return; return;
} }
const char *data = result.data.data(); const char *data = result.data.data();
@@ -1470,7 +1482,7 @@ void TrkGdbAdapter::startAdapter()
m_remoteExecutable = parameters.executable; m_remoteExecutable = parameters.executable;
m_symbolFile = parameters.symbolFileName; m_symbolFile = parameters.symbolFileName;
// FIXME: testing hack, remove! // FIXME: testing hack, remove!
if (parameters.processArgs.at(0) == _("@sym@")) { if (parameters.processArgs.size() == 3 && parameters.processArgs.at(0) == _("@sym@")) {
m_remoteExecutable = parameters.processArgs.at(1); m_remoteExecutable = parameters.processArgs.at(1);
m_symbolFile = parameters.processArgs.at(2); m_symbolFile = parameters.processArgs.at(2);
} }
@@ -1593,7 +1605,9 @@ void TrkGdbAdapter::startGdb()
QString msg = QString("Unable to start the gdb server at %1: %2.") QString msg = QString("Unable to start the gdb server at %1: %2.")
.arg(m_gdbServerName).arg(m_gdbServer->errorString()); .arg(m_gdbServerName).arg(m_gdbServer->errorString());
logMessage(msg); logMessage(msg);
emit adapterStartFailed(msg); // Delay cleanup as not to close a trk device from its read handler,
// which blocks.
emitDelayedAdapterStartFailed(msg);
return; return;
} }
@@ -1908,11 +1922,19 @@ void TrkGdbAdapter::setEnvironment(const QStringList &env)
m_gdbProc.setEnvironment(env); m_gdbProc.setEnvironment(env);
} }
void TrkGdbAdapter::cleanup()
{
if (m_trkDevice.isOpen())
m_trkDevice.close();
if (m_gdbServer)
delete m_gdbServer;
}
void TrkGdbAdapter::shutdown() void TrkGdbAdapter::shutdown()
{ {
switch (state()) { switch (state()) {
case AdapterStarting: case AdapterStarting:
cleanup();
setState(DebuggerNotReady); setState(DebuggerNotReady);
return; return;
@@ -1931,10 +1953,7 @@ void TrkGdbAdapter::shutdown()
case InferiorShutDown: case InferiorShutDown:
setState(AdapterShuttingDown); setState(AdapterShuttingDown);
//sendTrkMessage(0x02, TrkCB(handleDisconnect)); cleanup();
m_trkDevice.close();
delete m_gdbServer;
m_gdbServer = 0;
m_engine->postCommand(_("-gdb-exit"), CB(handleExit)); m_engine->postCommand(_("-gdb-exit"), CB(handleExit));
return; return;

View File

@@ -90,8 +90,6 @@ signals:
void output(const QString &msg); void output(const QString &msg);
private: private:
friend class RunnerGui;
const TrkOptionsPtr m_options; const TrkOptionsPtr m_options;
QString m_overrideTrkDevice; QString m_overrideTrkDevice;
@@ -115,11 +113,15 @@ public:
bool isTrkAdapter() const { return true; } bool isTrkAdapter() const { return true; }
bool dumpersAvailable() const { return false; } bool dumpersAvailable() const { return false; }
private:
void startAdapter(); void startAdapter();
void prepareInferior(); void prepareInferior();
void startInferior(); void startInferior();
void interruptInferior(); void interruptInferior();
void shutdown(); void shutdown();
void cleanup();
void emitDelayedAdapterStartFailed(const QString &msg);
Q_SLOT void slotEmitDelayedAdapterStartFailed();
Q_SLOT void startInferiorEarly(); Q_SLOT void startInferiorEarly();
void handleKill(const GdbResponse &response); void handleKill(const GdbResponse &response);
@@ -196,6 +198,7 @@ public:
QByteArray trkInterruptMessage(); QByteArray trkInterruptMessage();
trk::TrkDevice m_trkDevice; trk::TrkDevice m_trkDevice;
QString m_adapterFailMessage;
// //
// Gdb // Gdb

View File

@@ -695,6 +695,11 @@ void S60DeviceRunControlBase::processFailed(const QString &program, QProcess::Pr
emit finished(); emit finished();
} }
void S60DeviceRunControlBase::printApplicationOutput(const QString &output)
{
emit addToOutputWindowInline(this, output);
}
// =============== S60DeviceRunControl // =============== S60DeviceRunControl
S60DeviceRunControl::S60DeviceRunControl(const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration) : S60DeviceRunControl::S60DeviceRunControl(const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration) :
S60DeviceRunControlBase(runConfiguration) S60DeviceRunControlBase(runConfiguration)
@@ -730,11 +735,6 @@ void S60DeviceRunControl::printRunFailNotice(const QString &errorMessage) {
emit addToOutputWindow(this, tr("Could not start application: %1").arg(errorMessage)); emit addToOutputWindow(this, tr("Could not start application: %1").arg(errorMessage));
} }
void S60DeviceRunControl::printApplicationOutput(const QString &output)
{
emit addToOutputWindowInline(this, output);
}
// ======== S60DeviceDebugRunControl // ======== S60DeviceDebugRunControl
S60DeviceDebugRunControl::S60DeviceDebugRunControl(const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration) : S60DeviceDebugRunControl::S60DeviceDebugRunControl(const QSharedPointer<ProjectExplorer::RunConfiguration> &runConfiguration) :
@@ -748,7 +748,7 @@ S60DeviceDebugRunControl::S60DeviceDebugRunControl(const QSharedPointer<ProjectE
connect(dm, SIGNAL(debuggingFinished()), connect(dm, SIGNAL(debuggingFinished()),
this, SLOT(debuggingFinished()), Qt::QueuedConnection); this, SLOT(debuggingFinished()), Qt::QueuedConnection);
connect(dm, SIGNAL(applicationOutputAvailable(QString)), connect(dm, SIGNAL(applicationOutputAvailable(QString)),
this, SLOT(slotAddToOutputWindow(QString)), this, SLOT(printApplicationOutput(QString)),
Qt::QueuedConnection); Qt::QueuedConnection);
m_startParams->remoteChannel = rc->serialPortName(); m_startParams->remoteChannel = rc->serialPortName();

View File

@@ -160,6 +160,9 @@ protected:
virtual void handleLauncherFinished() = 0; virtual void handleLauncherFinished() = 0;
void processFailed(const QString &program, QProcess::ProcessError errorCode); void processFailed(const QString &program, QProcess::ProcessError errorCode);
protected slots:
void printApplicationOutput(const QString &output);
private slots: private slots:
void readStandardError(); void readStandardError();
void readStandardOutput(); void readStandardOutput();
@@ -208,7 +211,6 @@ private slots:
void printStartingNotice(); void printStartingNotice();
void printRunNotice(uint pid); void printRunNotice(uint pid);
void printRunFailNotice(const QString &errorMessage); void printRunFailNotice(const QString &errorMessage);
void printApplicationOutput(const QString &output);
private: private:
}; };

View File

@@ -836,6 +836,8 @@ TrkDevice::~TrkDevice()
bool TrkDevice::open(const QString &port, QString *errorMessage) bool TrkDevice::open(const QString &port, QString *errorMessage)
{ {
if (d->verbose)
qDebug() << "Opening" << port << "is open: " << isOpen();
close(); close();
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
d->deviceContext->device = CreateFile(port.toStdWString().c_str(), d->deviceContext->device = CreateFile(port.toStdWString().c_str(),
@@ -908,6 +910,8 @@ void TrkDevice::close()
{ {
if (!isOpen()) if (!isOpen())
return; return;
d->readerThread->terminate();
d->writerThread->terminate();
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
CloseHandle(d->deviceContext->device); CloseHandle(d->deviceContext->device);
d->deviceContext->device = INVALID_HANDLE_VALUE; d->deviceContext->device = INVALID_HANDLE_VALUE;
@@ -917,8 +921,6 @@ void TrkDevice::close()
#else #else
d->deviceContext->file.close(); d->deviceContext->file.close();
#endif #endif
d->readerThread->terminate();
d->writerThread->terminate();
if (d->verbose) if (d->verbose)
emitLogMessage("Close"); emitLogMessage("Close");
} }