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;
|
||||
}
|
||||
if (process.state() != QProcess::NotRunning) {
|
||||
process.terminate();
|
||||
process.write("k\n\r");
|
||||
process.closeWriteChannel();
|
||||
killTimer.start(1500);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user