forked from qt-creator/qt-creator
ios: fix kill when running on device
Change-Id: I2bd9a461c055ef8aa5f5ed9facc879def0078f6f Task-number: QTCREATORBUG-13259 Reviewed-by: Eike Ziller <eike.ziller@theqtcompany.com> Reviewed-by: Christian Stenger <christian.stenger@theqtcompany.com> Reviewed-by: Fawzi Mohamed <fawzi.mohamed@theqtcompany.com>
This commit is contained in:
committed by
Fawzi Mohamed
parent
6b894b50e6
commit
a1076c209a
@@ -286,7 +286,8 @@ void IosToolHandlerPrivate::stop(int errorCode)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (process.state() != QProcess::NotRunning) {
|
if (process.state() != QProcess::NotRunning) {
|
||||||
process.terminate();
|
process.write("k\n\r");
|
||||||
|
process.closeWriteChannel();
|
||||||
killTimer.start(1500);
|
killTimer.start(1500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -311,8 +311,10 @@ public:
|
|||||||
const QString &info);
|
const QString &info);
|
||||||
void deviceWithId(QString deviceId, int timeout, DeviceAvailableCallback callback, void *userData);
|
void deviceWithId(QString deviceId, int timeout, DeviceAvailableCallback callback, void *userData);
|
||||||
int processGdbServer(int fd);
|
int processGdbServer(int fd);
|
||||||
|
void stopGdbServer(int fd, int phase);
|
||||||
private:
|
private:
|
||||||
IosDeviceManager *q;
|
IosDeviceManager *q;
|
||||||
|
QMutex m_sendMutex;
|
||||||
QHash<QString, AMDeviceRef> m_devices;
|
QHash<QString, AMDeviceRef> m_devices;
|
||||||
QMultiHash<QString, PendingDeviceLookup *> m_pendingLookups;
|
QMultiHash<QString, PendingDeviceLookup *> m_pendingLookups;
|
||||||
AMDeviceNotificationRef m_notification;
|
AMDeviceNotificationRef m_notification;
|
||||||
@@ -631,7 +633,10 @@ enum GdbServerStatus {
|
|||||||
int IosDeviceManagerPrivate::processGdbServer(int fd)
|
int IosDeviceManagerPrivate::processGdbServer(int fd)
|
||||||
{
|
{
|
||||||
CommandSession session((QString()));
|
CommandSession session((QString()));
|
||||||
session.sendGdbCommand(fd, "vCont;c"); // resume all threads
|
{
|
||||||
|
QMutexLocker l(&m_sendMutex);
|
||||||
|
session.sendGdbCommand(fd, "vCont;c"); // resume all threads
|
||||||
|
}
|
||||||
GdbServerStatus state = NORMAL_PROCESS;
|
GdbServerStatus state = NORMAL_PROCESS;
|
||||||
int maxRetry = 10;
|
int maxRetry = 10;
|
||||||
int maxSignal = 5;
|
int maxSignal = 5;
|
||||||
@@ -711,10 +716,17 @@ int IosDeviceManagerPrivate::processGdbServer(int fd)
|
|||||||
addError(QLatin1String("hit maximum number of consecutive signals, stopping"));
|
addError(QLatin1String("hit maximum number of consecutive signals, stopping"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (session.sendGdbCommand(fd, "vCont;c"))
|
{
|
||||||
state = NORMAL_PROCESS;
|
if (signal == 17) {
|
||||||
else
|
state = NORMAL_PROCESS; // Ctrl-C to kill the process
|
||||||
break;
|
} else {
|
||||||
|
QMutexLocker l(&m_sendMutex);
|
||||||
|
if (session.sendGdbCommand(fd, "vCont;c"))
|
||||||
|
state = NORMAL_PROCESS;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
maxSignal = 5;
|
maxSignal = 5;
|
||||||
}
|
}
|
||||||
@@ -727,6 +739,16 @@ int IosDeviceManagerPrivate::processGdbServer(int fd)
|
|||||||
return state != INFERIOR_EXITED;
|
return state != INFERIOR_EXITED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IosDeviceManagerPrivate::stopGdbServer(int fd, int phase)
|
||||||
|
{
|
||||||
|
CommandSession session((QString()));
|
||||||
|
QMutexLocker l(&m_sendMutex);
|
||||||
|
if (phase == 0)
|
||||||
|
session.writeAll(fd,"\x03",1);
|
||||||
|
else
|
||||||
|
session.sendGdbCommand(fd, "k", 1);
|
||||||
|
}
|
||||||
|
|
||||||
// ------- ConnectSession implementation --------
|
// ------- ConnectSession implementation --------
|
||||||
|
|
||||||
CommandSession::CommandSession(const QString &deviceId) : DeviceSession(deviceId), device(0),
|
CommandSession::CommandSession(const QString &deviceId) : DeviceSession(deviceId), device(0),
|
||||||
@@ -1686,6 +1708,11 @@ int IosDeviceManager::processGdbServer(int fd)
|
|||||||
return d->processGdbServer(fd);
|
return d->processGdbServer(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IosDeviceManager::stopGdbServer(int fd, int phase)
|
||||||
|
{
|
||||||
|
return d->stopGdbServer(fd, phase);
|
||||||
|
}
|
||||||
|
|
||||||
QStringList IosDeviceManager::errors() {
|
QStringList IosDeviceManager::errors() {
|
||||||
return d->errors();
|
return d->errors();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ public:
|
|||||||
const QString &deviceId, int timeout = 1000);
|
const QString &deviceId, int timeout = 1000);
|
||||||
void requestDeviceInfo(const QString &deviceId, int timeout = 1000);
|
void requestDeviceInfo(const QString &deviceId, int timeout = 1000);
|
||||||
int processGdbServer(int fd);
|
int processGdbServer(int fd);
|
||||||
|
void stopGdbServer(int fd, int phase);
|
||||||
QStringList errors();
|
QStringList errors();
|
||||||
signals:
|
signals:
|
||||||
void deviceAdded(const QString &deviceId);
|
void deviceAdded(const QString &deviceId);
|
||||||
|
|||||||
@@ -55,6 +55,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
// avoid utils dependency
|
// avoid utils dependency
|
||||||
#define QTC_CHECK(cond) if (cond) {} else { qWarning() << "assert failed " << #cond << " " \
|
#define QTC_CHECK(cond) if (cond) {} else { qWarning() << "assert failed " << #cond << " " \
|
||||||
@@ -149,6 +150,7 @@ class GdbRunner: public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
GdbRunner(IosTool *iosTool, int gdbFd);
|
GdbRunner(IosTool *iosTool, int gdbFd);
|
||||||
|
void stop(int phase);
|
||||||
public slots:
|
public slots:
|
||||||
void run();
|
void run();
|
||||||
signals:
|
signals:
|
||||||
@@ -174,7 +176,9 @@ public:
|
|||||||
void writeMaybeBin(const QString &extraMsg, const char *msg, quintptr len);
|
void writeMaybeBin(const QString &extraMsg, const char *msg, quintptr len);
|
||||||
public slots:
|
public slots:
|
||||||
void errorMsg(const QString &msg);
|
void errorMsg(const QString &msg);
|
||||||
|
void stopGdbRunner();
|
||||||
private slots:
|
private slots:
|
||||||
|
void stopGdbRunner2();
|
||||||
void isTransferringApp(const QString &bundlePath, const QString &deviceId, int progress,
|
void isTransferringApp(const QString &bundlePath, const QString &deviceId, int progress,
|
||||||
const QString &info);
|
const QString &info);
|
||||||
void didTransferApp(const QString &bundlePath, const QString &deviceId,
|
void didTransferApp(const QString &bundlePath, const QString &deviceId,
|
||||||
@@ -185,6 +189,8 @@ private slots:
|
|||||||
void deviceInfo(const QString &deviceId, const Ios::IosDeviceManager::Dict &info);
|
void deviceInfo(const QString &deviceId, const Ios::IosDeviceManager::Dict &info);
|
||||||
void appOutput(const QString &output);
|
void appOutput(const QString &output);
|
||||||
private:
|
private:
|
||||||
|
void readStdin();
|
||||||
|
|
||||||
QMutex m_xmlMutex;
|
QMutex m_xmlMutex;
|
||||||
int maxProgress;
|
int maxProgress;
|
||||||
int opLeft;
|
int opLeft;
|
||||||
@@ -198,6 +204,7 @@ private:
|
|||||||
QXmlStreamWriter out;
|
QXmlStreamWriter out;
|
||||||
SingleRelayServer *gdbServer;
|
SingleRelayServer *gdbServer;
|
||||||
GenericRelayServer *qmlServer;
|
GenericRelayServer *qmlServer;
|
||||||
|
GdbRunner *gdbRunner;
|
||||||
friend class GdbRunner;
|
friend class GdbRunner;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -738,20 +745,17 @@ void IosTool::didStartApp(const QString &bundlePath, const QString &deviceId,
|
|||||||
outFile.flush();
|
outFile.flush();
|
||||||
}
|
}
|
||||||
if (!debug) {
|
if (!debug) {
|
||||||
GdbRunner *gdbRunner = new GdbRunner(this, gdbFd);
|
gdbRunner = new GdbRunner(this, gdbFd);
|
||||||
if (qmlServer) {
|
// we should not stop the event handling of the main thread
|
||||||
// we should not stop the event handling of the main thread
|
// all output moves to the new thread (other option would be to signal it back)
|
||||||
// all output moves to the new thread (other option would be to signal it back)
|
QThread *gdbProcessThread = new QThread();
|
||||||
QThread *gdbProcessThread = new QThread();
|
gdbRunner->moveToThread(gdbProcessThread);
|
||||||
gdbRunner->moveToThread(gdbProcessThread);
|
QObject::connect(gdbProcessThread, SIGNAL(started()), gdbRunner, SLOT(run()));
|
||||||
QObject::connect(gdbProcessThread, SIGNAL(started()), gdbRunner, SLOT(run()));
|
QObject::connect(gdbRunner, SIGNAL(finished()), gdbProcessThread, SLOT(quit()));
|
||||||
QObject::connect(gdbRunner, SIGNAL(finished()), gdbProcessThread, SLOT(quit()));
|
QObject::connect(gdbProcessThread, SIGNAL(finished()), gdbProcessThread, SLOT(deleteLater()));
|
||||||
QObject::connect(gdbProcessThread, SIGNAL(finished()), gdbProcessThread, SLOT(deleteLater()));
|
gdbProcessThread->start();
|
||||||
gdbProcessThread->start();
|
|
||||||
} else {
|
new std::thread([this]() -> void { readStdin();});
|
||||||
gdbRunner->setParent(this);
|
|
||||||
gdbRunner->run();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -849,11 +853,36 @@ void IosTool::appOutput(const QString &output)
|
|||||||
outFile.flush();
|
outFile.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IosTool::readStdin()
|
||||||
|
{
|
||||||
|
int c = getchar();
|
||||||
|
if (c == 'k') {
|
||||||
|
QMetaObject::invokeMethod(this, "stopGdbRunner");
|
||||||
|
errorMsg(QLatin1String("iostool: Killing inferior.\n"));
|
||||||
|
} else if (c != EOF) {
|
||||||
|
errorMsg(QLatin1String("iostool: Unexpected character in stdin, stop listening.\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void IosTool::errorMsg(const QString &msg)
|
void IosTool::errorMsg(const QString &msg)
|
||||||
{
|
{
|
||||||
writeMsg(msg);
|
writeMsg(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IosTool::stopGdbRunner()
|
||||||
|
{
|
||||||
|
if (gdbRunner) {
|
||||||
|
gdbRunner->stop(0);
|
||||||
|
QTimer::singleShot(100, this, SLOT(stopGdbRunner2()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IosTool::stopGdbRunner2()
|
||||||
|
{
|
||||||
|
if (gdbRunner)
|
||||||
|
gdbRunner->stop(1);
|
||||||
|
}
|
||||||
|
|
||||||
void IosTool::stopRelayServers(int errorCode)
|
void IosTool::stopRelayServers(int errorCode)
|
||||||
{
|
{
|
||||||
if (echoRelays)
|
if (echoRelays)
|
||||||
@@ -886,9 +915,6 @@ int main(int argc, char *argv[])
|
|||||||
exit(res);
|
exit(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "main.moc"
|
|
||||||
|
|
||||||
|
|
||||||
GdbRunner::GdbRunner(IosTool *iosTool, int gdbFd) :
|
GdbRunner::GdbRunner(IosTool *iosTool, int gdbFd) :
|
||||||
QObject(0), m_iosTool(iosTool), m_gdbFd(gdbFd)
|
QObject(0), m_iosTool(iosTool), m_gdbFd(gdbFd)
|
||||||
{
|
{
|
||||||
@@ -917,3 +943,10 @@ void GdbRunner::run()
|
|||||||
m_iosTool->doExit();
|
m_iosTool->doExit();
|
||||||
emit finished();
|
emit finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GdbRunner::stop(int phase)
|
||||||
|
{
|
||||||
|
Ios::IosDeviceManager::instance()->stopGdbServer(m_gdbFd, phase);
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "main.moc"
|
||||||
|
|||||||
Reference in New Issue
Block a user