summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFawzi Mohamed <fawzi.mohamed@digia.com>2014-12-01 15:26:13 +0100
committerFawzi Mohamed <fawzi.mohamed@theqtcompany.com>2014-12-03 13:39:29 +0100
commita1076c209ace16c6d87f450d876221905a449ad5 (patch)
treed3b29b8247bee6e7e75a1a1a80d2495f6353f53e
parent6b894b50e62961e2ecaa0601eadb36740e87dd53 (diff)
downloadqt-creator-a1076c209ace16c6d87f450d876221905a449ad5.tar.gz
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>
-rw-r--r--src/plugins/ios/iostoolhandler.cpp3
-rw-r--r--src/tools/iostool/iosdevicemanager.cpp37
-rw-r--r--src/tools/iostool/iosdevicemanager.h1
-rw-r--r--src/tools/iostool/main.cpp67
4 files changed, 85 insertions, 23 deletions
diff --git a/src/plugins/ios/iostoolhandler.cpp b/src/plugins/ios/iostoolhandler.cpp
index cd640edc99..aab7106cc1 100644
--- a/src/plugins/ios/iostoolhandler.cpp
+++ b/src/plugins/ios/iostoolhandler.cpp
@@ -286,7 +286,8 @@ void IosToolHandlerPrivate::stop(int errorCode)
return;
}
if (process.state() != QProcess::NotRunning) {
- process.terminate();
+ process.write("k\n\r");
+ process.closeWriteChannel();
killTimer.start(1500);
}
}
diff --git a/src/tools/iostool/iosdevicemanager.cpp b/src/tools/iostool/iosdevicemanager.cpp
index bb9aed2bac..36b7005555 100644
--- a/src/tools/iostool/iosdevicemanager.cpp
+++ b/src/tools/iostool/iosdevicemanager.cpp
@@ -311,8 +311,10 @@ public:
const QString &info);
void deviceWithId(QString deviceId, int timeout, DeviceAvailableCallback callback, void *userData);
int processGdbServer(int fd);
+ void stopGdbServer(int fd, int phase);
private:
IosDeviceManager *q;
+ QMutex m_sendMutex;
QHash<QString, AMDeviceRef> m_devices;
QMultiHash<QString, PendingDeviceLookup *> m_pendingLookups;
AMDeviceNotificationRef m_notification;
@@ -631,7 +633,10 @@ enum GdbServerStatus {
int IosDeviceManagerPrivate::processGdbServer(int fd)
{
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;
int maxRetry = 10;
int maxSignal = 5;
@@ -711,10 +716,17 @@ int IosDeviceManagerPrivate::processGdbServer(int fd)
addError(QLatin1String("hit maximum number of consecutive signals, stopping"));
break;
}
- if (session.sendGdbCommand(fd, "vCont;c"))
- state = NORMAL_PROCESS;
- else
- break;
+ {
+ if (signal == 17) {
+ state = NORMAL_PROCESS; // Ctrl-C to kill the process
+ } else {
+ QMutexLocker l(&m_sendMutex);
+ if (session.sendGdbCommand(fd, "vCont;c"))
+ state = NORMAL_PROCESS;
+ else
+ break;
+ }
+ }
} else {
maxSignal = 5;
}
@@ -727,6 +739,16 @@ int IosDeviceManagerPrivate::processGdbServer(int fd)
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 --------
CommandSession::CommandSession(const QString &deviceId) : DeviceSession(deviceId), device(0),
@@ -1686,6 +1708,11 @@ int IosDeviceManager::processGdbServer(int fd)
return d->processGdbServer(fd);
}
+void IosDeviceManager::stopGdbServer(int fd, int phase)
+{
+ return d->stopGdbServer(fd, phase);
+}
+
QStringList IosDeviceManager::errors() {
return d->errors();
}
diff --git a/src/tools/iostool/iosdevicemanager.h b/src/tools/iostool/iosdevicemanager.h
index 45f29dad77..260f0d49d3 100644
--- a/src/tools/iostool/iosdevicemanager.h
+++ b/src/tools/iostool/iosdevicemanager.h
@@ -75,6 +75,7 @@ public:
const QString &deviceId, int timeout = 1000);
void requestDeviceInfo(const QString &deviceId, int timeout = 1000);
int processGdbServer(int fd);
+ void stopGdbServer(int fd, int phase);
QStringList errors();
signals:
void deviceAdded(const QString &deviceId);
diff --git a/src/tools/iostool/main.cpp b/src/tools/iostool/main.cpp
index c2d037802d..30d0bb907f 100644
--- a/src/tools/iostool/main.cpp
+++ b/src/tools/iostool/main.cpp
@@ -55,6 +55,7 @@
#include <unistd.h>
#include <fcntl.h>
#endif
+#include <thread>
// avoid utils dependency
#define QTC_CHECK(cond) if (cond) {} else { qWarning() << "assert failed " << #cond << " " \
@@ -149,6 +150,7 @@ class GdbRunner: public QObject
Q_OBJECT
public:
GdbRunner(IosTool *iosTool, int gdbFd);
+ void stop(int phase);
public slots:
void run();
signals:
@@ -174,7 +176,9 @@ public:
void writeMaybeBin(const QString &extraMsg, const char *msg, quintptr len);
public slots:
void errorMsg(const QString &msg);
+ void stopGdbRunner();
private slots:
+ void stopGdbRunner2();
void isTransferringApp(const QString &bundlePath, const QString &deviceId, int progress,
const QString &info);
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 appOutput(const QString &output);
private:
+ void readStdin();
+
QMutex m_xmlMutex;
int maxProgress;
int opLeft;
@@ -198,6 +204,7 @@ private:
QXmlStreamWriter out;
SingleRelayServer *gdbServer;
GenericRelayServer *qmlServer;
+ GdbRunner *gdbRunner;
friend class GdbRunner;
};
@@ -738,20 +745,17 @@ void IosTool::didStartApp(const QString &bundlePath, const QString &deviceId,
outFile.flush();
}
if (!debug) {
- GdbRunner *gdbRunner = new GdbRunner(this, gdbFd);
- if (qmlServer) {
- // 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)
- QThread *gdbProcessThread = new QThread();
- gdbRunner->moveToThread(gdbProcessThread);
- QObject::connect(gdbProcessThread, SIGNAL(started()), gdbRunner, SLOT(run()));
- QObject::connect(gdbRunner, SIGNAL(finished()), gdbProcessThread, SLOT(quit()));
- QObject::connect(gdbProcessThread, SIGNAL(finished()), gdbProcessThread, SLOT(deleteLater()));
- gdbProcessThread->start();
- } else {
- gdbRunner->setParent(this);
- gdbRunner->run();
- }
+ gdbRunner = new GdbRunner(this, gdbFd);
+ // 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)
+ QThread *gdbProcessThread = new QThread();
+ gdbRunner->moveToThread(gdbProcessThread);
+ QObject::connect(gdbProcessThread, SIGNAL(started()), gdbRunner, SLOT(run()));
+ QObject::connect(gdbRunner, SIGNAL(finished()), gdbProcessThread, SLOT(quit()));
+ QObject::connect(gdbProcessThread, SIGNAL(finished()), gdbProcessThread, SLOT(deleteLater()));
+ gdbProcessThread->start();
+
+ new std::thread([this]() -> void { readStdin();});
}
}
@@ -849,11 +853,36 @@ void IosTool::appOutput(const QString &output)
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)
{
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)
{
if (echoRelays)
@@ -886,9 +915,6 @@ int main(int argc, char *argv[])
exit(res);
}
-#include "main.moc"
-
-
GdbRunner::GdbRunner(IosTool *iosTool, int gdbFd) :
QObject(0), m_iosTool(iosTool), m_gdbFd(gdbFd)
{
@@ -917,3 +943,10 @@ void GdbRunner::run()
m_iosTool->doExit();
emit finished();
}
+
+void GdbRunner::stop(int phase)
+{
+ Ios::IosDeviceManager::instance()->stopGdbServer(m_gdbFd, phase);
+}
+
+#include "main.moc"