diff options
author | Fawzi Mohamed <fawzi.mohamed@digia.com> | 2014-12-01 15:26:13 +0100 |
---|---|---|
committer | Fawzi Mohamed <fawzi.mohamed@theqtcompany.com> | 2014-12-03 13:39:29 +0100 |
commit | a1076c209ace16c6d87f450d876221905a449ad5 (patch) | |
tree | d3b29b8247bee6e7e75a1a1a80d2495f6353f53e | |
parent | 6b894b50e62961e2ecaa0601eadb36740e87dd53 (diff) | |
download | qt-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.cpp | 3 | ||||
-rw-r--r-- | src/tools/iostool/iosdevicemanager.cpp | 37 | ||||
-rw-r--r-- | src/tools/iostool/iosdevicemanager.h | 1 | ||||
-rw-r--r-- | src/tools/iostool/main.cpp | 67 |
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" |