2010-05-05 12:49:08 +02:00
|
|
|
/**************************************************************************
|
|
|
|
|
**
|
|
|
|
|
** This file is part of Qt Creator
|
|
|
|
|
**
|
2011-01-11 16:28:15 +01:00
|
|
|
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
2010-05-05 12:49:08 +02:00
|
|
|
**
|
|
|
|
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
|
|
|
|
**
|
2010-12-17 16:01:08 +01:00
|
|
|
** No Commercial Usage
|
2010-05-05 12:49:08 +02:00
|
|
|
**
|
2010-12-17 16:01:08 +01:00
|
|
|
** This file contains pre-release code and may not be distributed.
|
|
|
|
|
** You may use this file in accordance with the terms and conditions
|
|
|
|
|
** contained in the Technology Preview License Agreement accompanying
|
|
|
|
|
** this package.
|
2010-05-05 12:49:08 +02:00
|
|
|
**
|
|
|
|
|
** GNU Lesser General Public License Usage
|
|
|
|
|
**
|
|
|
|
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
|
|
|
** General Public License version 2.1 as published by the Free Software
|
|
|
|
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
|
|
|
|
** packaging of this file. Please review the following information to
|
|
|
|
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
|
|
|
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|
|
|
|
**
|
2010-12-17 16:01:08 +01:00
|
|
|
** In addition, as a special exception, Nokia gives you certain additional
|
|
|
|
|
** rights. These rights are described in the Nokia Qt LGPL Exception
|
|
|
|
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
|
|
|
**
|
|
|
|
|
** If you have questions regarding the use of this file, please contact
|
|
|
|
|
** Nokia at qt-info@nokia.com.
|
2010-05-05 12:49:08 +02:00
|
|
|
**
|
|
|
|
|
**************************************************************************/
|
|
|
|
|
|
|
|
|
|
#include "remotegdbprocess.h"
|
|
|
|
|
|
|
|
|
|
#include "remoteplaingdbadapter.h"
|
|
|
|
|
|
2010-10-08 18:32:13 +02:00
|
|
|
#include <utils/qtcassert.h>
|
2010-10-19 11:14:03 +02:00
|
|
|
#include <utils/qtcprocess.h>
|
2010-10-08 18:32:13 +02:00
|
|
|
|
2010-11-02 15:08:30 +01:00
|
|
|
#include <QtCore/QFileInfo>
|
|
|
|
|
|
2010-05-31 11:12:58 +02:00
|
|
|
#include <ctype.h>
|
|
|
|
|
|
2010-07-12 09:33:22 +02:00
|
|
|
using namespace Core;
|
|
|
|
|
|
2010-05-05 12:49:08 +02:00
|
|
|
namespace Debugger {
|
|
|
|
|
namespace Internal {
|
|
|
|
|
|
2011-02-14 16:34:17 +01:00
|
|
|
RemoteGdbProcess::RemoteGdbProcess(const Utils::SshConnectionParameters &connParams,
|
2010-05-05 12:49:08 +02:00
|
|
|
RemotePlainGdbAdapter *adapter, QObject *parent)
|
2010-11-04 10:23:48 +01:00
|
|
|
: AbstractGdbProcess(parent), m_connParams(connParams),
|
|
|
|
|
m_state(Inactive), m_adapter(adapter)
|
2010-05-05 12:49:08 +02:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QByteArray RemoteGdbProcess::readAllStandardOutput()
|
|
|
|
|
{
|
|
|
|
|
QByteArray output = m_gdbOutput;
|
|
|
|
|
m_gdbOutput.clear();
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QByteArray RemoteGdbProcess::readAllStandardError()
|
|
|
|
|
{
|
|
|
|
|
QByteArray errorOutput = m_errorOutput;
|
|
|
|
|
m_errorOutput.clear();
|
|
|
|
|
return errorOutput;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RemoteGdbProcess::start(const QString &cmd, const QStringList &args)
|
2010-10-08 18:32:13 +02:00
|
|
|
{
|
|
|
|
|
Q_UNUSED(cmd);
|
|
|
|
|
Q_UNUSED(args);
|
2010-11-04 10:23:48 +01:00
|
|
|
QTC_ASSERT(m_state == RunningGdb, return);
|
2010-10-08 18:32:13 +02:00
|
|
|
}
|
|
|
|
|
|
2010-11-02 15:08:30 +01:00
|
|
|
void RemoteGdbProcess::realStart(const QString &cmd, const QStringList &args,
|
|
|
|
|
const QString &executableFilePath)
|
2010-05-05 12:49:08 +02:00
|
|
|
{
|
2010-11-04 10:23:48 +01:00
|
|
|
QTC_ASSERT(m_state == Inactive, return);
|
|
|
|
|
setState(Connecting);
|
|
|
|
|
|
2010-05-05 12:49:08 +02:00
|
|
|
m_command = cmd;
|
|
|
|
|
m_cmdArgs = args;
|
2010-11-02 15:08:30 +01:00
|
|
|
m_appOutputFileName = "app_output_"
|
|
|
|
|
+ QFileInfo(executableFilePath).fileName().toUtf8();
|
2010-07-12 09:33:22 +02:00
|
|
|
m_error.clear();
|
2010-11-11 12:31:32 +01:00
|
|
|
m_lastSeqNr.clear();
|
|
|
|
|
m_currentGdbOutput.clear();
|
|
|
|
|
m_gdbOutput.clear();
|
|
|
|
|
m_errorOutput.clear();
|
|
|
|
|
m_inputToSend.clear();
|
2011-02-14 16:34:17 +01:00
|
|
|
m_conn = Utils::SshConnection::create();
|
2010-07-12 09:33:22 +02:00
|
|
|
connect(m_conn.data(), SIGNAL(connected()), this, SLOT(handleConnected()));
|
2011-02-14 16:34:17 +01:00
|
|
|
connect(m_conn.data(), SIGNAL(error(Utils::SshError)), this,
|
2010-07-12 09:33:22 +02:00
|
|
|
SLOT(handleConnectionError()));
|
|
|
|
|
m_conn->connectToHost(m_connParams);
|
|
|
|
|
}
|
2010-05-05 12:49:08 +02:00
|
|
|
|
2010-07-12 09:33:22 +02:00
|
|
|
void RemoteGdbProcess::handleConnected()
|
2010-05-05 12:49:08 +02:00
|
|
|
{
|
2010-11-04 10:23:48 +01:00
|
|
|
if (m_state == Inactive)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
QTC_ASSERT(m_state == Connecting, return);
|
|
|
|
|
setState(CreatingFifo);
|
|
|
|
|
|
2010-07-12 09:33:22 +02:00
|
|
|
m_fifoCreator = m_conn->createRemoteProcess( "rm -f "
|
2010-11-02 15:08:30 +01:00
|
|
|
+ m_appOutputFileName + " && mkfifo " + m_appOutputFileName);
|
2010-07-12 09:33:22 +02:00
|
|
|
connect(m_fifoCreator.data(), SIGNAL(closed(int)), this,
|
|
|
|
|
SLOT(handleFifoCreationFinished(int)));
|
|
|
|
|
m_fifoCreator->start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RemoteGdbProcess::handleConnectionError()
|
|
|
|
|
{
|
2010-11-04 10:23:48 +01:00
|
|
|
if (m_state != Inactive)
|
|
|
|
|
emitErrorExit(tr("Connection failure: %1.").arg(m_conn->errorString()));
|
2010-07-12 09:33:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RemoteGdbProcess::handleFifoCreationFinished(int exitStatus)
|
|
|
|
|
{
|
2010-11-04 10:23:48 +01:00
|
|
|
if (m_state == Inactive)
|
|
|
|
|
return;
|
|
|
|
|
QTC_ASSERT(m_state == CreatingFifo, return);
|
|
|
|
|
|
2011-02-14 16:34:17 +01:00
|
|
|
if (exitStatus != Utils::SshRemoteProcess::ExitedNormally) {
|
2010-07-12 09:33:22 +02:00
|
|
|
emitErrorExit(tr("Could not create FIFO."));
|
|
|
|
|
} else {
|
2010-11-04 10:23:48 +01:00
|
|
|
setState(StartingFifoReader);
|
2010-11-02 15:08:30 +01:00
|
|
|
m_appOutputReader = m_conn->createRemoteProcess("cat "
|
|
|
|
|
+ m_appOutputFileName + " && rm -f " + m_appOutputFileName);
|
2010-07-12 09:33:22 +02:00
|
|
|
connect(m_appOutputReader.data(), SIGNAL(started()), this,
|
|
|
|
|
SLOT(handleAppOutputReaderStarted()));
|
|
|
|
|
connect(m_appOutputReader.data(), SIGNAL(closed(int)), this,
|
|
|
|
|
SLOT(handleAppOutputReaderFinished(int)));
|
|
|
|
|
m_appOutputReader->start();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RemoteGdbProcess::handleAppOutputReaderStarted()
|
|
|
|
|
{
|
2010-11-04 10:23:48 +01:00
|
|
|
if (m_state == Inactive)
|
|
|
|
|
return;
|
|
|
|
|
QTC_ASSERT(m_state == StartingFifoReader, return);
|
|
|
|
|
setState(StartingGdb);
|
|
|
|
|
|
2010-07-12 09:33:22 +02:00
|
|
|
connect(m_appOutputReader.data(), SIGNAL(outputAvailable(QByteArray)),
|
|
|
|
|
this, SLOT(handleAppOutput(QByteArray)));
|
2010-12-15 16:50:57 +01:00
|
|
|
QByteArray cmdLine = "DISPLAY=:0.0 " + m_command.toUtf8() + ' '
|
2010-10-19 11:14:03 +02:00
|
|
|
+ Utils::QtcProcess::joinArgsUnix(m_cmdArgs).toUtf8()
|
2010-11-02 15:08:30 +01:00
|
|
|
+ " -tty=" + m_appOutputFileName;
|
2010-05-10 14:26:41 +02:00
|
|
|
if (!m_wd.isEmpty())
|
2010-10-19 11:14:03 +02:00
|
|
|
cmdLine.prepend("cd " + Utils::QtcProcess::quoteArgUnix(m_wd).toUtf8() + " && ");
|
2010-07-12 09:33:22 +02:00
|
|
|
m_gdbProc = m_conn->createRemoteProcess(cmdLine);
|
|
|
|
|
connect(m_gdbProc.data(), SIGNAL(started()), this,
|
|
|
|
|
SLOT(handleGdbStarted()));
|
|
|
|
|
connect(m_gdbProc.data(), SIGNAL(closed(int)), this,
|
|
|
|
|
SLOT(handleGdbFinished(int)));
|
|
|
|
|
connect(m_gdbProc.data(), SIGNAL(outputAvailable(QByteArray)), this,
|
|
|
|
|
SLOT(handleGdbOutput(QByteArray)));
|
|
|
|
|
connect(m_gdbProc.data(), SIGNAL(errorOutputAvailable(QByteArray)), this,
|
|
|
|
|
SLOT(handleErrOutput(QByteArray)));
|
|
|
|
|
m_gdbProc->start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RemoteGdbProcess::handleAppOutputReaderFinished(int exitStatus)
|
|
|
|
|
{
|
2011-02-14 16:34:17 +01:00
|
|
|
if (exitStatus != Utils::SshRemoteProcess::ExitedNormally)
|
2010-07-12 09:33:22 +02:00
|
|
|
emitErrorExit(tr("Application output reader unexpectedly finished."));
|
|
|
|
|
}
|
2010-05-10 14:26:41 +02:00
|
|
|
|
2010-07-12 09:33:22 +02:00
|
|
|
void RemoteGdbProcess::handleGdbStarted()
|
|
|
|
|
{
|
2010-11-04 10:23:48 +01:00
|
|
|
if (m_state == Inactive)
|
|
|
|
|
return;
|
|
|
|
|
QTC_ASSERT(m_state == StartingGdb, return);
|
|
|
|
|
setState(RunningGdb);
|
2010-10-08 18:32:13 +02:00
|
|
|
emit started();
|
2010-07-12 09:33:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RemoteGdbProcess::handleGdbFinished(int exitStatus)
|
|
|
|
|
{
|
2010-11-04 10:23:48 +01:00
|
|
|
if (m_state == Inactive)
|
|
|
|
|
return;
|
|
|
|
|
QTC_ASSERT(m_state == RunningGdb, return);
|
|
|
|
|
|
2010-07-12 09:33:22 +02:00
|
|
|
switch (exitStatus) {
|
2011-02-14 16:34:17 +01:00
|
|
|
case Utils::SshRemoteProcess::FailedToStart:
|
2010-10-08 18:32:13 +02:00
|
|
|
m_error = tr("Remote gdb failed to start.");
|
2010-11-04 10:23:48 +01:00
|
|
|
setState(Inactive);
|
2010-10-08 18:32:13 +02:00
|
|
|
emit startFailed();
|
2010-07-12 09:33:22 +02:00
|
|
|
break;
|
2011-02-14 16:34:17 +01:00
|
|
|
case Utils::SshRemoteProcess::KilledBySignal:
|
2010-07-12 09:33:22 +02:00
|
|
|
emitErrorExit(tr("Remote gdb crashed."));
|
|
|
|
|
break;
|
2011-02-14 16:34:17 +01:00
|
|
|
case Utils::SshRemoteProcess::ExitedNormally:
|
2010-11-04 10:23:48 +01:00
|
|
|
const int exitCode = m_gdbProc->exitCode();
|
|
|
|
|
setState(Inactive);
|
|
|
|
|
emit finished(exitCode, QProcess::NormalExit);
|
2010-07-12 09:33:22 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool RemoteGdbProcess::waitForStarted()
|
|
|
|
|
{
|
2010-11-04 10:23:48 +01:00
|
|
|
if (m_state == Inactive)
|
|
|
|
|
return false;
|
|
|
|
|
QTC_ASSERT(m_state == RunningGdb, return false);
|
|
|
|
|
return true;
|
2010-05-05 12:49:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
qint64 RemoteGdbProcess::write(const QByteArray &data)
|
|
|
|
|
{
|
2010-11-04 10:23:48 +01:00
|
|
|
if (m_state != RunningGdb || !m_inputToSend.isEmpty()
|
|
|
|
|
|| !m_lastSeqNr.isEmpty())
|
2010-05-05 12:49:08 +02:00
|
|
|
m_inputToSend.enqueue(data);
|
2010-07-12 09:33:22 +02:00
|
|
|
else
|
|
|
|
|
sendInput(data);
|
|
|
|
|
return data.size();
|
2010-05-05 12:49:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RemoteGdbProcess::kill()
|
|
|
|
|
{
|
2010-11-04 10:23:48 +01:00
|
|
|
if (m_state == RunningGdb) {
|
2011-02-14 16:34:17 +01:00
|
|
|
Utils::SshRemoteProcess::Ptr killProc
|
2010-11-04 10:23:48 +01:00
|
|
|
= m_conn->createRemoteProcess("pkill -SIGKILL -x gdb");
|
|
|
|
|
killProc->start();
|
|
|
|
|
} else {
|
|
|
|
|
setState(Inactive);
|
|
|
|
|
}
|
2010-07-12 09:33:22 +02:00
|
|
|
}
|
2010-05-05 12:49:08 +02:00
|
|
|
|
2010-07-12 09:33:22 +02:00
|
|
|
void RemoteGdbProcess::interruptInferior()
|
|
|
|
|
{
|
2010-11-04 10:23:48 +01:00
|
|
|
QTC_ASSERT(m_state == RunningGdb, return);
|
|
|
|
|
|
2011-02-14 16:34:17 +01:00
|
|
|
Utils::SshRemoteProcess::Ptr intProc
|
2010-07-12 09:33:22 +02:00
|
|
|
= m_conn->createRemoteProcess("pkill -x -SIGINT gdb");
|
|
|
|
|
intProc->start();
|
2010-05-05 12:49:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QProcess::ProcessState RemoteGdbProcess::state() const
|
|
|
|
|
{
|
2010-11-04 10:23:48 +01:00
|
|
|
switch (m_state) {
|
|
|
|
|
case RunningGdb: return QProcess::Running;
|
|
|
|
|
case Inactive: return QProcess::NotRunning;
|
|
|
|
|
default: return QProcess::Starting;
|
|
|
|
|
}
|
2010-05-05 12:49:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString RemoteGdbProcess::errorString() const
|
|
|
|
|
{
|
2010-07-12 09:33:22 +02:00
|
|
|
return m_error;
|
2010-05-05 12:49:08 +02:00
|
|
|
}
|
|
|
|
|
|
2010-07-12 09:33:22 +02:00
|
|
|
void RemoteGdbProcess::handleGdbOutput(const QByteArray &output)
|
2010-05-05 12:49:08 +02:00
|
|
|
{
|
2010-11-04 10:23:48 +01:00
|
|
|
if (m_state == Inactive)
|
|
|
|
|
return;
|
|
|
|
|
QTC_ASSERT(m_state == RunningGdb, return);
|
|
|
|
|
|
2010-07-12 09:33:22 +02:00
|
|
|
// TODO: Carriage return removal still necessary?
|
|
|
|
|
m_currentGdbOutput += removeCarriageReturn(output);
|
2010-05-05 12:49:08 +02:00
|
|
|
#if 0
|
2010-05-10 14:26:41 +02:00
|
|
|
qDebug("%s: complete unread output is '%s'", Q_FUNC_INFO, m_currentGdbOutput.data());
|
2010-05-05 12:49:08 +02:00
|
|
|
#endif
|
|
|
|
|
if (!m_currentGdbOutput.endsWith('\n'))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (m_currentGdbOutput.contains(m_lastSeqNr + '^'))
|
|
|
|
|
m_lastSeqNr.clear();
|
|
|
|
|
|
|
|
|
|
if (m_lastSeqNr.isEmpty() && !m_inputToSend.isEmpty()) {
|
|
|
|
|
#if 0
|
|
|
|
|
qDebug("Sending queued command: %s", m_inputToSend.head().data());
|
|
|
|
|
#endif
|
|
|
|
|
sendInput(m_inputToSend.dequeue());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!m_currentGdbOutput.isEmpty()) {
|
|
|
|
|
const int startPos
|
|
|
|
|
= m_gdbOutput.isEmpty() ? findAnchor(m_currentGdbOutput) : 0;
|
|
|
|
|
if (startPos != -1) {
|
|
|
|
|
m_gdbOutput += m_currentGdbOutput.mid(startPos);
|
|
|
|
|
m_currentGdbOutput.clear();
|
|
|
|
|
emit readyReadStandardOutput();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QProcessEnvironment RemoteGdbProcess::processEnvironment() const
|
|
|
|
|
{
|
|
|
|
|
return QProcessEnvironment(); // TODO: Provide actual environment.
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-19 08:51:46 +02:00
|
|
|
void RemoteGdbProcess::setProcessEnvironment(const QProcessEnvironment & /* env */)
|
2010-05-05 12:49:08 +02:00
|
|
|
{
|
2010-07-12 09:33:22 +02:00
|
|
|
// TODO: Do something. (if remote process exists: set, otherwise queue)
|
2010-05-05 12:49:08 +02:00
|
|
|
}
|
|
|
|
|
|
2010-05-19 08:51:46 +02:00
|
|
|
void RemoteGdbProcess::setEnvironment(const QStringList & /* env */)
|
2010-05-05 12:49:08 +02:00
|
|
|
{
|
|
|
|
|
// TODO: Do something.
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RemoteGdbProcess::setWorkingDirectory(const QString &dir)
|
|
|
|
|
{
|
|
|
|
|
m_wd = dir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int RemoteGdbProcess::findAnchor(const QByteArray &data) const
|
|
|
|
|
{
|
|
|
|
|
for (int pos = 0; pos < data.count(); ++pos) {
|
|
|
|
|
const char c = data.at(pos);
|
|
|
|
|
if (isdigit(c) || c == '*' || c == '+' || c == '=' || c == '~'
|
|
|
|
|
|| c == '@' || c == '&' || c == '^')
|
|
|
|
|
return pos;
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-12 09:33:22 +02:00
|
|
|
void RemoteGdbProcess::sendInput(const QByteArray &data)
|
2010-05-05 12:49:08 +02:00
|
|
|
{
|
2010-11-04 10:23:48 +01:00
|
|
|
QTC_ASSERT(m_state == RunningGdb, return);
|
|
|
|
|
|
2010-05-05 12:49:08 +02:00
|
|
|
int pos;
|
|
|
|
|
for (pos = 0; pos < data.size(); ++pos)
|
|
|
|
|
if (!isdigit(data.at(pos)))
|
|
|
|
|
break;
|
|
|
|
|
m_lastSeqNr = data.left(pos);
|
2010-07-12 09:33:22 +02:00
|
|
|
m_gdbProc->sendInput(data);
|
2010-05-05 12:49:08 +02:00
|
|
|
}
|
|
|
|
|
|
2010-07-12 09:33:22 +02:00
|
|
|
void RemoteGdbProcess::handleAppOutput(const QByteArray &output)
|
2010-05-05 12:49:08 +02:00
|
|
|
{
|
2010-11-04 10:23:48 +01:00
|
|
|
if (m_state == RunningGdb)
|
|
|
|
|
m_adapter->handleApplicationOutput(output);
|
2010-05-05 12:49:08 +02:00
|
|
|
}
|
|
|
|
|
|
2010-07-12 09:33:22 +02:00
|
|
|
void RemoteGdbProcess::handleErrOutput(const QByteArray &output)
|
2010-05-05 12:49:08 +02:00
|
|
|
{
|
2010-11-04 10:23:48 +01:00
|
|
|
if (m_state == RunningGdb) {
|
|
|
|
|
m_errorOutput += output;
|
|
|
|
|
emit readyReadStandardError();
|
|
|
|
|
}
|
2010-05-05 12:49:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QByteArray RemoteGdbProcess::removeCarriageReturn(const QByteArray &data)
|
|
|
|
|
{
|
|
|
|
|
QByteArray output;
|
|
|
|
|
for (int i = 0; i < data.size(); ++i) {
|
|
|
|
|
const char c = data.at(i);
|
|
|
|
|
if (c != '\r')
|
|
|
|
|
output += c;
|
|
|
|
|
}
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-12 09:33:22 +02:00
|
|
|
void RemoteGdbProcess::emitErrorExit(const QString &error)
|
2010-05-05 12:49:08 +02:00
|
|
|
{
|
2010-07-12 09:33:22 +02:00
|
|
|
if (m_error.isEmpty()) {
|
|
|
|
|
m_error = error;
|
2010-11-04 10:23:48 +01:00
|
|
|
setState(Inactive);
|
2010-07-12 09:33:22 +02:00
|
|
|
emit finished(-1, QProcess::CrashExit);
|
2010-05-05 12:49:08 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-04 10:23:48 +01:00
|
|
|
void RemoteGdbProcess::setState(State newState)
|
|
|
|
|
{
|
|
|
|
|
if (m_state == newState)
|
|
|
|
|
return;
|
|
|
|
|
m_state = newState;
|
|
|
|
|
if (m_state == Inactive) {
|
|
|
|
|
if (m_gdbProc) {
|
|
|
|
|
disconnect(m_gdbProc.data(), 0, this, 0);
|
2011-02-14 16:34:17 +01:00
|
|
|
m_gdbProc = Utils::SshRemoteProcess::Ptr();
|
2010-11-04 10:23:48 +01:00
|
|
|
}
|
|
|
|
|
if (m_appOutputReader) {
|
|
|
|
|
disconnect(m_appOutputReader.data(), 0, this, 0);
|
2011-02-14 16:34:17 +01:00
|
|
|
m_appOutputReader = Utils::SshRemoteProcess::Ptr();
|
2010-11-04 10:23:48 +01:00
|
|
|
}
|
|
|
|
|
if (m_fifoCreator) {
|
|
|
|
|
disconnect(m_fifoCreator.data(), 0, this, 0);
|
2011-02-14 16:34:17 +01:00
|
|
|
m_fifoCreator = Utils::SshRemoteProcess::Ptr();
|
2010-11-04 10:23:48 +01:00
|
|
|
}
|
|
|
|
|
disconnect(m_conn.data(), 0, this, 0);
|
|
|
|
|
m_conn->disconnectFromHost();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-05 12:49:08 +02:00
|
|
|
const QByteArray RemoteGdbProcess::CtrlC = QByteArray(1, 0x3);
|
|
|
|
|
|
|
|
|
|
} // namespace Internal
|
|
|
|
|
} // namespace Debugger
|