From 91882497952ebf33a76888b79125ce9cd56994d3 Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Mon, 1 Jun 2015 11:25:31 +0200 Subject: [PATCH 01/18] Parse additional config files Some runtime settings need to be applied to the environment. Additional config files may be located in /tmp/b2qt/appcontroller.config.d or /var/lib/b2qt/appcontroller.config.d Task-number: QTEE-931 Change-Id: Id6c8c5695e6ca74351c7f81a66aa9a75a948792a Reviewed-by: Ulf Hermann --- main.cpp | 58 ++++++++++++++++++++++++++++++++++++------------------- process.h | 2 +- 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/main.cpp b/main.cpp index fb52564..0f3486e 100644 --- a/main.cpp +++ b/main.cpp @@ -20,6 +20,7 @@ #include "portlist.h" #include "perfprocesshandler.h" #include +#include #include #include #include @@ -160,21 +161,13 @@ static int findFirstFreePort(Utils::PortList &range) return openServer(&s, range); } -static Config parseConfigFile() +static bool parseConfigFile(Config *config, const QString &fileName) { - Config config; - config.base = config.platform = QLatin1String("unknown"); - config.debugInterface = Config::LocalDebugInterface; - -#ifdef Q_OS_ANDROID - QFile f("/system/bin/appcontroller.conf"); -#else - QFile f("/etc/appcontroller.conf"); -#endif + QFile f(fileName); if (!f.open(QFile::ReadOnly)) { - fprintf(stderr, "Could not read config file.\n"); - return config; + fprintf(stderr, "Could not read config file: %s\n", qPrintable(fileName)); + return false; } while (!f.atEnd()) { @@ -185,27 +178,44 @@ static Config parseConfigFile() if (index < 2) { // ignore } else - config.env[sub.left(index)] = sub.mid(index+1); + config->env[sub.left(index)] = sub.mid(index+1); } else if (line.startsWith("append=")) { - config.args += line.mid(7).simplified(); + config->args += line.mid(7).simplified(); } else if (line.startsWith("base=")) { - config.base = line.mid(5).simplified(); + config->base = line.mid(5).simplified(); } else if (line.startsWith("platform=")) { - config.platform = line.mid(9).simplified(); + config->platform = line.mid(9).simplified(); } else if (line.startsWith("debugInterface=")) { const QString value = line.mid(15).simplified(); if (value == "local") - config.debugInterface = Config::LocalDebugInterface; + config->debugInterface = Config::LocalDebugInterface; else if (value == "public") - config.debugInterface = Config::PublicDebugInterface; + config->debugInterface = Config::PublicDebugInterface; else qWarning() << "Unkonwn value for debuginterface:" << value; } } f.close(); - return config; + return true; } +static bool parseConfigFileDirectory(Config *config, const QString &dirName) +{ + QDir d(dirName); + if (d.exists()) { + foreach (const QString &fileName, d.entryList(QDir::Files)) { + const QString file(d.absoluteFilePath(fileName)); + + if (!parseConfigFile(config, file)) { + fprintf(stderr, "Failed to parse config file: %s\n", qPrintable(file)); + return false; + } + } + } + return true; +} + + static bool removeDefault() { if (QFile::exists(B2QT_PREFIX)) { @@ -283,7 +293,15 @@ int main(int argc, char **argv) return 1; } - Config config = parseConfigFile(); + Config config; + if (!parseConfigFile(&config, "/etc/appcontroller.conf")) { + fprintf(stderr, "Failed to parse config file.\n"); + return 1; + } + + // Parse temporary config files + parseConfigFileDirectory(&config, "/var/lib/b2qt/appcontroller.conf.d"); + parseConfigFileDirectory(&config, "/tmp/b2qt/appcontroller.conf.d"); while (!args.isEmpty()) { const QString arg(args.takeFirst()); diff --git a/process.h b/process.h index bf67d96..d175dd3 100644 --- a/process.h +++ b/process.h @@ -37,7 +37,7 @@ struct Config { PublicDebugInterface }; - Config() : flags(0) { } + Config() : platform("unknown"), flags(0), debugInterface(LocalDebugInterface) { } QString base; QString platform; From 281140ecdd07fbc48f0bf45d395eedaf6a59fb2f Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Wed, 3 Jun 2015 09:38:16 +0200 Subject: [PATCH 02/18] Fix compile warnings Change-Id: I05fb9bca47f5bcfc3f127eb9a60e6be8bda8193a Reviewed-by: Ulf Hermann --- main.cpp | 3 ++- process.cpp | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/main.cpp b/main.cpp index 0f3486e..5c47dcf 100644 --- a/main.cpp +++ b/main.cpp @@ -433,7 +433,8 @@ int main(int argc, char **argv) } setsid(); - chdir("/"); + if (chdir("/") != 0) + return -1; signal(SIGHUP, SIG_IGN); // child diff --git a/process.cpp b/process.cpp index 1fe811b..7842deb 100644 --- a/process.cpp +++ b/process.cpp @@ -129,8 +129,9 @@ void Process::forwardProcessOutput(qintptr fd, const QByteArray &data) fd_set inputFdSet; FD_ZERO(&inputFdSet); FD_SET(pipefd[0], &inputFdSet); - if (select(qMax(fd, pipefd[0]) + 1, &inputFdSet, &outputFdSet, NULL, NULL) > 0 && - !FD_ISSET(pipefd[0], &inputFdSet)) + if (select(qMax(fd, static_cast(pipefd[0])) + 1, + &inputFdSet, &outputFdSet, NULL, NULL) > 0 && + !FD_ISSET(pipefd[0], &inputFdSet)) continue; // else fprintf below will output the appropriate errno } From f055f3c9fe5825f09af54ef4ccc2b24ae0181c22 Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Wed, 3 Jun 2015 09:38:51 +0200 Subject: [PATCH 03/18] Ignore missing default config file Change-Id: Ieb219833bba906bdca1c8bd1dce18185d86ded86 Reviewed-by: Ulf Hermann --- main.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/main.cpp b/main.cpp index 5c47dcf..1e64c55 100644 --- a/main.cpp +++ b/main.cpp @@ -294,10 +294,8 @@ int main(int argc, char **argv) } Config config; - if (!parseConfigFile(&config, "/etc/appcontroller.conf")) { + if (!parseConfigFile(&config, "/etc/appcontroller.conf")) fprintf(stderr, "Failed to parse config file.\n"); - return 1; - } // Parse temporary config files parseConfigFileDirectory(&config, "/var/lib/b2qt/appcontroller.conf.d"); From 866aa6f727c096feada0f1d39cce44ca660ad787 Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Wed, 3 Jun 2015 09:37:54 +0200 Subject: [PATCH 04/18] Send command string between appcontroller instances Task-number: QTEE-931 Change-Id: If0efdafdd5e39523d315be86cda07f69e2387e16 Reviewed-by: Ulf Hermann --- main.cpp | 50 +++++++++++++++++++++++++++++++------------------- process.cpp | 30 ++++++++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 21 deletions(-) diff --git a/main.cpp b/main.cpp index 1e64c55..06bf501 100644 --- a/main.cpp +++ b/main.cpp @@ -21,6 +21,7 @@ #include "perfprocesshandler.h" #include #include +#include #include #include #include @@ -73,28 +74,39 @@ static void setupAddressStruct(struct sockaddr_un &address) address.sun_path[0] = 0; } -static int connectSocket() +static int connectSocket(const QByteArray &command) { - int create_socket; - struct sockaddr_un address; + int fd = 0; + struct sockaddr_un address; - if ((create_socket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { - perror("Could not create socket"); - return -1; - } + if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { + perror("Could not create socket"); + return -1; + } - if (fcntl(create_socket, F_SETFD, FD_CLOEXEC) == -1) { - perror("Unable to set CLOEXEC"); - } + if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) + perror("Unable to set CLOEXEC"); - setupAddressStruct(address); + setupAddressStruct(address); - if (connect(create_socket, (struct sockaddr *) &address, sizeof (address)) != 0) { - perror("Could not connect"); - return -1; - } - close(create_socket); - return 0; + if (connect(fd, (struct sockaddr *) &address, sizeof (address)) != 0) { + perror("Could not connect"); + return -1; + } + + QLocalSocket localSocket; + if (!localSocket.setSocketDescriptor(fd)) { + fprintf(stderr, "Unable to initialize local socket from descriptor.\n"); + close(fd); + return -1; + } + + if (localSocket.write(command) != command.size()) { + fprintf(stderr, "Could not send command"); + return -1; + } + localSocket.waitForBytesWritten(); + return 0; } static int createServerSocket() @@ -122,7 +134,7 @@ static int createServerSocket() return -1; } - if (connectSocket() != 0) { + if (connectSocket("stop") != 0) { fprintf(stderr, "Failed to connect to process\n"); } @@ -143,7 +155,7 @@ static int createServerSocket() static void stop() { - connectSocket(); + connectSocket("stop"); } static int openServer(QTcpServer *s, Utils::PortList &range) diff --git a/process.cpp b/process.cpp index 7842deb..ce699c0 100644 --- a/process.cpp +++ b/process.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -261,8 +262,33 @@ void Process::stop() void Process::incomingConnection(int i) { - accept(i, NULL, NULL); - stop(); + int fd = accept(i, NULL, NULL); + if (fd < 0 ) { + perror("Could not accept connection"); + stop(); + return; + } + + QLocalSocket localSocket; + if (!localSocket.setSocketDescriptor(fd)) { + fprintf(stderr, "Could not initialize local socket from descriptor.\n"); + close(fd); + stop(); + return; + } + + if (!localSocket.waitForReadyRead()) { + fprintf(stderr, "No command received.\n"); + stop(); // default + return; + } + + QByteArray command = localSocket.readAll(); + + if (command == "stop") + stop(); + else + stop(); } void Process::setSocketNotifier(QSocketNotifier *s) From 2631768b484176836694ec4afdb81ef31886c142 Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Wed, 3 Jun 2015 09:39:13 +0200 Subject: [PATCH 05/18] Add command to restart current application Task-number: QTEE-931 Change-Id: I0ad4246750142289cca2a4cbf853211a60538362 Reviewed-by: Laszlo Agocs --- main.cpp | 18 +++++++++++------- process.cpp | 50 ++++++++++++++++++++++++++++++++++++++------------ process.h | 5 ++++- 3 files changed, 53 insertions(+), 20 deletions(-) diff --git a/main.cpp b/main.cpp index 06bf501..08be98c 100644 --- a/main.cpp +++ b/main.cpp @@ -62,6 +62,7 @@ static void usage() "--print-debug Print debug messages to stdout on Android\n" "--version Print version information\n" "--detach Start application as usual, then go into background\n" + "--restart Restart the current running application\n" "--help, -h, -help Show this help\n" ); } @@ -158,6 +159,11 @@ static void stop() connectSocket("stop"); } +static void restart() +{ + connectSocket("restart"); +} + static int openServer(QTcpServer *s, Utils::PortList &range) { while (range.hasMore()) { @@ -173,7 +179,7 @@ static int findFirstFreePort(Utils::PortList &range) return openServer(&s, range); } -static bool parseConfigFile(Config *config, const QString &fileName) +bool parseConfigFile(Config *config, const QString &fileName) { QFile f(fileName); @@ -211,7 +217,7 @@ static bool parseConfigFile(Config *config, const QString &fileName) return true; } -static bool parseConfigFileDirectory(Config *config, const QString &dirName) +bool parseConfigFileDirectory(Config *config, const QString &dirName) { QDir d(dirName); if (d.exists()) { @@ -227,7 +233,6 @@ static bool parseConfigFileDirectory(Config *config, const QString &dirName) return true; } - static bool removeDefault() { if (QFile::exists(B2QT_PREFIX)) { @@ -309,10 +314,6 @@ int main(int argc, char **argv) if (!parseConfigFile(&config, "/etc/appcontroller.conf")) fprintf(stderr, "Failed to parse config file.\n"); - // Parse temporary config files - parseConfigFileDirectory(&config, "/var/lib/b2qt/appcontroller.conf.d"); - parseConfigFileDirectory(&config, "/tmp/b2qt/appcontroller.conf.d"); - while (!args.isEmpty()) { const QString arg(args.takeFirst()); @@ -371,6 +372,9 @@ int main(int argc, char **argv) return 0; } else if (arg == "--detach") { detach = true; + } else if (arg == "--restart") { + restart(); + return 0; } else if (arg == "--help" || arg == "-help" || arg == "-h") { usage(); return 0; diff --git a/process.cpp b/process.cpp index ce699c0..64bbc13 100644 --- a/process.cpp +++ b/process.cpp @@ -30,6 +30,7 @@ #include #include +bool parseConfigFileDirectory(Config *config, const QString &dirName); static int pipefd[2]; static void signalhandler(int) @@ -90,13 +91,13 @@ Process::Process() , mDebuggee(0) , mDebug(false) , mStdoutFd(1) + , mBeingRestarted(false) { mProcess->setProcessChannelMode(QProcess::SeparateChannels); connect(mProcess, &QProcess::readyReadStandardError, this, &Process::readyReadStandardError); connect(mProcess, &QProcess::readyReadStandardOutput, this, &Process::readyReadStandardOutput); connect(mProcess, (void (QProcess::*)(int, QProcess::ExitStatus))&QProcess::finished, this, &Process::finished); connect(mProcess, (void (QProcess::*)(QProcess::ProcessError))&QProcess::error, this, &Process::error); - connect(mProcess, (void (QProcess::*)(int, QProcess::ExitStatus))&QProcess::finished, qApp, &QCoreApplication::quit); if (pipe2(pipefd, O_CLOEXEC) != 0) qWarning("Could not create pipe"); @@ -195,7 +196,8 @@ void Process::error(QProcess::ProcessError error) printf("Unknown error\n"); break; } - qApp->quit(); + if (!mBeingRestarted) + qApp->quit(); } void Process::finished(int exitCode, QProcess::ExitStatus exitStatus) @@ -204,28 +206,41 @@ void Process::finished(int exitCode, QProcess::ExitStatus exitStatus) printf("Process exited with exit code %d\n", exitCode); else printf("Process stopped\n"); + if (!mBeingRestarted) { + qDebug() << "quit"; + qApp->quit(); + } } -void Process::startup(QStringList args) +void Process::startup() { #ifdef Q_OS_ANDROID QProcessEnvironment pe = interactiveProcessEnvironment(); #else QProcessEnvironment pe = QProcessEnvironment::systemEnvironment(); #endif + QStringList args = mStartupArguments; + mBeingRestarted = false; + + Config actualConfig = mConfig; + + // Parse temporary config files + // This needs to be done on every startup because those files are expected to change. + parseConfigFileDirectory(&actualConfig, "/var/lib/b2qt/appcontroller.conf.d"); + parseConfigFileDirectory(&actualConfig, "/tmp/b2qt/appcontroller.conf.d"); - foreach (const QString &key, mConfig.env.keys()) { + foreach (const QString &key, actualConfig.env.keys()) { if (!pe.contains(key)) { - qDebug() << key << mConfig.env.value(key); - pe.insert(key, mConfig.env.value(key)); + qDebug() << key << actualConfig.env.value(key); + pe.insert(key, actualConfig.env.value(key)); } } - if (!mConfig.base.isEmpty()) - pe.insert(QLatin1String("B2QT_BASE"), mConfig.base); - if (!mConfig.platform.isEmpty()) - pe.insert(QLatin1String("B2QT_PLATFORM"), mConfig.platform); + if (!actualConfig.base.isEmpty()) + pe.insert(QLatin1String("B2QT_BASE"), actualConfig.base); + if (!actualConfig.platform.isEmpty()) + pe.insert(QLatin1String("B2QT_PLATFORM"), actualConfig.platform); - args.append(mConfig.args); + args.append(actualConfig.args); mProcess->setProcessEnvironment(pe); mBinary = args.first(); @@ -236,7 +251,8 @@ void Process::startup(QStringList args) void Process::start(const QStringList &args) { - startup(args); + mStartupArguments = args; + startup(); } void Process::stop() @@ -260,6 +276,14 @@ void Process::stop() mProcess->kill(); } +void Process::restart() +{ + printf("Restarting application\n"); + mBeingRestarted = true; + stop(); + startup(); +} + void Process::incomingConnection(int i) { int fd = accept(i, NULL, NULL); @@ -287,6 +311,8 @@ void Process::incomingConnection(int i) if (command == "stop") stop(); + else if (command == "restart") + restart(); else stop(); } diff --git a/process.h b/process.h index d175dd3..105d051 100644 --- a/process.h +++ b/process.h @@ -60,6 +60,7 @@ class Process : public QObject void setStdoutFd(qintptr stdoutFd); public slots: void stop(); + void restart(); private slots: void readyReadStandardError(); void readyReadStandardOutput(); @@ -68,7 +69,7 @@ private slots: void incomingConnection(int); private: void forwardProcessOutput(qintptr fd, const QByteArray &data); - void startup(QStringList); + void startup(); QProcessEnvironment interactiveProcessEnvironment() const; QProcess *mProcess; int mDebuggee; @@ -76,6 +77,8 @@ private slots: Config mConfig; QString mBinary; qintptr mStdoutFd; + QStringList mStartupArguments; + bool mBeingRestarted; }; #endif // PROCESS_H From 3804f0dc00471a209bb5d85ba3816c09af877109 Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Tue, 9 Jun 2015 12:34:12 +0200 Subject: [PATCH 06/18] Make appcontroller a temporary daemon For a restart being successful the application has to be shut down with out terminating the appcontroller. Afterwards the appcontroller will be able to start the application again. Change-Id: I38fd0aded176a10dac40c419b6866ce70ec1fcef Reviewed-by: Laszlo Agocs --- main.cpp | 11 ++++++++++- process.cpp | 12 +++++++++++- process.h | 1 + 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/main.cpp b/main.cpp index 08be98c..63341fe 100644 --- a/main.cpp +++ b/main.cpp @@ -55,6 +55,7 @@ static void usage() "--debug-gdb Start GDB debugging\n" "--debug-qml Start QML debugging\n" "--stop Stop already running application\n" + "--stop-for-restart Stop already running application and prepare to restart it\n" "--launch Start application without stopping already running application\n" "--show-platform Show platform information\n" "--make-default Make this application the default on boot\n" @@ -62,7 +63,7 @@ static void usage() "--print-debug Print debug messages to stdout on Android\n" "--version Print version information\n" "--detach Start application as usual, then go into background\n" - "--restart Restart the current running application\n" + "--restart Restart the current running application or an application stopped with --stop-for-restart\n" "--help, -h, -help Show this help\n" ); } @@ -164,6 +165,11 @@ static void restart() connectSocket("restart"); } +static void stopForRestart() +{ + connectSocket("stopForRestart"); +} + static int openServer(QTcpServer *s, Utils::PortList &range) { while (range.hasMore()) { @@ -375,6 +381,9 @@ int main(int argc, char **argv) } else if (arg == "--restart") { restart(); return 0; + } else if (arg == "--stop-for-restart") { + stopForRestart(); + return 0; } else if (arg == "--help" || arg == "-help" || arg == "-h") { usage(); return 0; diff --git a/process.cpp b/process.cpp index 64bbc13..d3d8fdb 100644 --- a/process.cpp +++ b/process.cpp @@ -259,7 +259,8 @@ void Process::stop() { if (mProcess->state() == QProcess::QProcess::NotRunning) { printf("No process running\n"); - qApp->exit(); + if (!mBeingRestarted) + qApp->exit(); return; } @@ -276,6 +277,13 @@ void Process::stop() mProcess->kill(); } +void Process::stopForRestart() +{ + printf("Stopping application for restart\n"); + mBeingRestarted = true; + stop(); +} + void Process::restart() { printf("Restarting application\n"); @@ -313,6 +321,8 @@ void Process::incomingConnection(int i) stop(); else if (command == "restart") restart(); + else if (command == "stopForRestart") + stopForRestart(); else stop(); } diff --git a/process.h b/process.h index 105d051..10fc13b 100644 --- a/process.h +++ b/process.h @@ -60,6 +60,7 @@ class Process : public QObject void setStdoutFd(qintptr stdoutFd); public slots: void stop(); + void stopForRestart(); void restart(); private slots: void readyReadStandardError(); From 45d549fe274cd8f16578b2ff9a34af40fd9b98a9 Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Fri, 12 Jun 2015 09:51:57 +0200 Subject: [PATCH 07/18] Add feature info Change-Id: Ibc85618c0de0478a2fb2de45f19e2dc654109635 Reviewed-by: Laszlo Agocs --- main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main.cpp b/main.cpp index 63341fe..f4c2233 100644 --- a/main.cpp +++ b/main.cpp @@ -36,6 +36,7 @@ #include #define PID_FILE "/data/user/.appcontroller" +#define FEATURES "perf eglresize" #ifdef Q_OS_ANDROID #define B2QT_PREFIX "/data/user/b2qt" @@ -374,7 +375,7 @@ int main(int argc, char **argv) } else if (arg == "--print-debug") { config.flags |= Config::PrintDebugMessages; } else if (arg == "--version") { - printf("Appcontroller version: " GIT_VERSION "\nGit revision: " GIT_HASH "\n"); + printf("Appcontroller version: " GIT_VERSION "\nGit revision: " GIT_HASH "\nFeatures: " FEATURES "\n"); return 0; } else if (arg == "--detach") { detach = true; From 7ac47bee4c6bd55df8c0cad14ff11457fbf07158 Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Mon, 15 Jun 2015 10:41:30 +0200 Subject: [PATCH 08/18] Add restart to feature string Change-Id: Iee8d8a1eda473dbc4a4ec4efb3baf9cc2eb18a5a Reviewed-by: Laszlo Agocs --- main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.cpp b/main.cpp index f4c2233..3442954 100644 --- a/main.cpp +++ b/main.cpp @@ -36,7 +36,7 @@ #include #define PID_FILE "/data/user/.appcontroller" -#define FEATURES "perf eglresize" +#define FEATURES "restart perf eglresize" #ifdef Q_OS_ANDROID #define B2QT_PREFIX "/data/user/b2qt" From 26b255dd1a53a8f276c0e33bda896945600b404d Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Fri, 14 Aug 2015 11:16:06 +0200 Subject: [PATCH 09/18] Add --qml-debug-services argument We don't want to load the QML debugger and inspector services when profiling as the V4 debugger forces the QML engine into interpreter mode. By specifying the services we need we can avoid this. Change-Id: I8ec126155c43848f26d536a56c3a1da067864401 Reviewed-by: Rainer Keller --- main.cpp | 50 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/main.cpp b/main.cpp index 3442954..17862ad 100644 --- a/main.cpp +++ b/main.cpp @@ -36,7 +36,7 @@ #include #define PID_FILE "/data/user/.appcontroller" -#define FEATURES "restart perf eglresize" +#define FEATURES "restart perf eglresize qmldebugservices" #ifdef Q_OS_ANDROID #define B2QT_PREFIX "/data/user/b2qt" @@ -50,22 +50,28 @@ static const char socketPath[] = "#Boot2Qt_appcontroller"; static void usage() { - printf("appcontroller [--debug-gdb] [--debug-qml] [--port-range ] [--stop] [--launch] [--show-platfrom] [--make-default] [--remove-default] [--print-debug] [--version] [--detach] [executable] [arguments]\n" + printf("appcontroller [--debug-gdb] [--debug-qml] [--qml-debug-services ]" + " [--port-range ] [--stop] [--launch] [--show-platfrom] [--make-default]" + " [--remove-default] [--print-debug] [--version] [--detach] [executable] [arguments]\n" "\n" - "--port-range Port range to use for debugging connections\n" - "--debug-gdb Start GDB debugging\n" - "--debug-qml Start QML debugging\n" - "--stop Stop already running application\n" - "--stop-for-restart Stop already running application and prepare to restart it\n" - "--launch Start application without stopping already running application\n" - "--show-platform Show platform information\n" - "--make-default Make this application the default on boot\n" - "--remove-default Restore the default application\n" - "--print-debug Print debug messages to stdout on Android\n" - "--version Print version information\n" - "--detach Start application as usual, then go into background\n" - "--restart Restart the current running application or an application stopped with --stop-for-restart\n" - "--help, -h, -help Show this help\n" + "--port-range Port range to use for debugging connections\n" + "--debug-gdb Start GDB debugging\n" + "--debug-qml Start QML debugging or profiling\n" + "--qml-debug-services Specify services to use for QML debugging/profiling\n" + "--stop Stop already running application\n" + "--stop-for-restart Stop already running application and prepare to\n" + " restart it\n" + "--launch Start application without stopping already running\n" + " application\n" + "--show-platform Show platform information\n" + "--make-default Make this application the default on boot\n" + "--remove-default Restore the default application\n" + "--print-debug Print debug messages to stdout on Android\n" + "--version Print version information\n" + "--detach Start application as usual, then go into background\n" + "--restart Restart the current running application or an\n" + " application stopped with --stop-for-restart\n" + "--help, -h, -help Show this help\n" ); } @@ -307,6 +313,7 @@ int main(int argc, char **argv) quint16 gdbDebugPort = 0; bool useGDB = false; bool useQML = false; + QString qmlDebugServices; QStringList perfParams; bool fireAndForget = false; bool detach = false; @@ -340,6 +347,13 @@ int main(int argc, char **argv) setsid(); } else if (arg == "--debug-qml") { useQML = true; + } else if (arg == "--qml-debug-services") { + if (args.isEmpty()) { + fprintf(stderr, "--qml-debug-services requires a list of comma-separated service " + "names.\n"); + return 1; + } + qmlDebugServices = args.takeFirst(); } else if (arg == "--profile-perf") { if (args.isEmpty()) { fprintf(stderr, "--profile-perf requires comma-separated list of parameters that " @@ -423,7 +437,9 @@ int main(int argc, char **argv) fprintf(stderr, "Could not find an unused port in range\n"); return 1; } - defaultArgs.push_front("-qmljsdebugger=port:" + QString::number(port) + ",block"); + defaultArgs.push_front("-qmljsdebugger=port:" + QString::number(port) + ",block" + + (qmlDebugServices.isEmpty() ? + "" : (",services:" + qmlDebugServices))); printf("QML Debugger: Going to wait for connection on port %d...\n", port); } From 6b5ef93020d471fe21152e2428e2f0c5bc7dc24d Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Wed, 3 Jun 2015 10:55:29 +0200 Subject: [PATCH 10/18] Remove Android code Change-Id: I8a69405655483c6bbd9f402df4a06a1020b6bebe Reviewed-by: aavit --- main.cpp | 9 +------ process.cpp | 74 ----------------------------------------------------- process.h | 9 +------ 3 files changed, 2 insertions(+), 90 deletions(-) diff --git a/main.cpp b/main.cpp index 17862ad..a1188f0 100644 --- a/main.cpp +++ b/main.cpp @@ -38,11 +38,7 @@ #define PID_FILE "/data/user/.appcontroller" #define FEATURES "restart perf eglresize qmldebugservices" -#ifdef Q_OS_ANDROID - #define B2QT_PREFIX "/data/user/b2qt" -#else - #define B2QT_PREFIX "/usr/bin/b2qt" -#endif +#define B2QT_PREFIX "/usr/bin/b2qt" static int serverSocket = -1; @@ -66,7 +62,6 @@ static void usage() "--show-platform Show platform information\n" "--make-default Make this application the default on boot\n" "--remove-default Restore the default application\n" - "--print-debug Print debug messages to stdout on Android\n" "--version Print version information\n" "--detach Start application as usual, then go into background\n" "--restart Restart the current running application or an\n" @@ -386,8 +381,6 @@ int main(int argc, char **argv) return 0; else return 1; - } else if (arg == "--print-debug") { - config.flags |= Config::PrintDebugMessages; } else if (arg == "--version") { printf("Appcontroller version: " GIT_VERSION "\nGit revision: " GIT_HASH "\nFeatures: " FEATURES "\n"); return 0; diff --git a/process.cpp b/process.cpp index d3d8fdb..2ee9246 100644 --- a/process.cpp +++ b/process.cpp @@ -144,12 +144,8 @@ void Process::forwardProcessOutput(qintptr fd, const QByteArray &data) size -= written; constData += written; } - - if (mConfig.flags.testFlag(Config::PrintDebugMessages)) - qDebug() << data; } - void Process::readyReadStandardOutput() { forwardProcessOutput(mStdoutFd, mProcess->readAllStandardOutput()); @@ -214,11 +210,7 @@ void Process::finished(int exitCode, QProcess::ExitStatus exitStatus) void Process::startup() { -#ifdef Q_OS_ANDROID - QProcessEnvironment pe = interactiveProcessEnvironment(); -#else QProcessEnvironment pe = QProcessEnvironment::systemEnvironment(); -#endif QStringList args = mStartupArguments; mBeingRestarted = false; @@ -341,69 +333,3 @@ void Process::setStdoutFd(qintptr stdoutFd) { mStdoutFd = stdoutFd; } - -QProcessEnvironment Process::interactiveProcessEnvironment() const -{ - QProcessEnvironment env; - - QProcess process; - process.start("sh"); - if (!process.waitForStarted(3000)) { - printf("Could not start shell.\n"); - return env; - } - - process.write("source /system/etc/mkshrc\n"); - process.write("export -p\n"); - process.closeWriteChannel(); - - printf("waiting for process to finish\n"); - if (!process.waitForFinished(1000)) { - printf("did not finish: terminate\n"); - process.terminate(); - if (!process.waitForFinished(1000)) { - printf("did not terminate: kill\n"); - process.kill(); - if (!process.waitForFinished(1000)) { - printf("Could not stop process.\n"); - } - } - } - - QList list = process.readAllStandardOutput().split('\n'); - if (list.isEmpty()) - printf("Failed to read environment output\n"); - - foreach (QByteArray entry, list) { - if (entry.startsWith("export ")) { - entry = entry.mid(7); - } else if (entry.startsWith("declare -x ")) { - entry = entry.mid(11); - } else { - continue; - } - - QByteArray key; - QByteArray value; - int index = entry.indexOf('='); - - if (index > 0) { - key = entry.left(index); - value = entry.mid(index + 1); - } else { - key = entry; - // value is empty - } - - // Remove simple escaping. - // This is not complete. - if (value.startsWith('\'') and value.endsWith('\'')) - value = value.mid(1, value.size()-2); - else if (value.startsWith('"') and value.endsWith('"')) - value = value.mid(1, value.size()-2); - - env.insert(key, value); - } - - return env; -} diff --git a/process.h b/process.h index 10fc13b..46bea62 100644 --- a/process.h +++ b/process.h @@ -27,23 +27,17 @@ class QSocketNotifier; struct Config { - enum Flag { - PrintDebugMessages = 0x01 - }; - Q_DECLARE_FLAGS(Flags, Flag) - enum DebugInterface{ LocalDebugInterface, PublicDebugInterface }; - Config() : platform("unknown"), flags(0), debugInterface(LocalDebugInterface) { } + Config() : platform("unknown"), debugInterface(LocalDebugInterface) { } QString base; QString platform; QMap env; QStringList args; - Flags flags; DebugInterface debugInterface; }; @@ -71,7 +65,6 @@ private slots: private: void forwardProcessOutput(qintptr fd, const QByteArray &data); void startup(); - QProcessEnvironment interactiveProcessEnvironment() const; QProcess *mProcess; int mDebuggee; bool mDebug; From af3ab8ec0213a40d90f3d58a8a65a944b0cd753e Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Fri, 14 Aug 2015 11:18:40 +0200 Subject: [PATCH 11/18] Add note about --profile-perf to usage message Change-Id: I50163b3c5f085f12f102fb0eb455eaf6ebda6ffa Reviewed-by: Rainer Keller --- main.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/main.cpp b/main.cpp index a1188f0..7b8b7be 100644 --- a/main.cpp +++ b/main.cpp @@ -47,13 +47,15 @@ static const char socketPath[] = "#Boot2Qt_appcontroller"; static void usage() { printf("appcontroller [--debug-gdb] [--debug-qml] [--qml-debug-services ]" - " [--port-range ] [--stop] [--launch] [--show-platfrom] [--make-default]" - " [--remove-default] [--print-debug] [--version] [--detach] [executable] [arguments]\n" + " [--profile-perf ] [--port-range ] [--stop] [--launch] [--show-platfrom]" + " [--make-default] [--remove-default] [--print-debug] [--version] [--detach]" + " [executable] [arguments]\n" "\n" "--port-range Port range to use for debugging connections\n" "--debug-gdb Start GDB debugging\n" "--debug-qml Start QML debugging or profiling\n" "--qml-debug-services Specify services to use for QML debugging/profiling\n" + "--profile-perf Start perf profiling\n" "--stop Stop already running application\n" "--stop-for-restart Stop already running application and prepare to\n" " restart it\n" @@ -351,10 +353,10 @@ int main(int argc, char **argv) qmlDebugServices = args.takeFirst(); } else if (arg == "--profile-perf") { if (args.isEmpty()) { - fprintf(stderr, "--profile-perf requires comma-separated list of parameters that " - "get passed to \"perf record\". Arguments \"-o -\" are " - "automatically appended to capture the output as stream. " - "Escape commas by doubling them."); + fprintf(stderr, "--profile-perf requires comma-separated list of parameters that\n" + "get passed to \"perf record\". Arguments \"-o -\" are\n" + "automatically appended to capture the output as stream.\n" + "Escape commas by doubling them.\n"); return 1; } perfParams = extractPerfParams(args.takeFirst()); From 77a798298ffc8db5ecf6e40e8b371426fa025dcb Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 29 Feb 2016 16:48:00 +0100 Subject: [PATCH 12/18] Don't join application arguments when running in perf mode ... otherwise we get "command not found". Change-Id: I9f471d8b7021df83f0c09c3f06addb977f17353c Task-number: QCE-67 Reviewed-by: Rainer Keller --- main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.cpp b/main.cpp index 7b8b7be..854276e 100644 --- a/main.cpp +++ b/main.cpp @@ -501,7 +501,7 @@ int main(int argc, char **argv) QStringList allArgs; allArgs << QLatin1String("perf") << QLatin1String("record") << perfParams << QLatin1String("-o") << QLatin1String("-") - << QLatin1String("--") << defaultArgs.join(QLatin1Char(' ')); + << QLatin1String("--") << defaultArgs; PerfProcessHandler *server = new PerfProcessHandler(&process, allArgs); int port = openServer(server->server(), range); From 1e3c96e0e4f28a072c835775f7fdc310eb3b4f28 Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Wed, 9 Mar 2016 14:59:48 +0100 Subject: [PATCH 13/18] Do not kill the process group When restarting an application the process seems to kill itself. Task-number: QTEE-1085 Change-Id: I88598fe4bd6ed5423c1412036eaf1ea1572bc889 Reviewed-by: David Schulz Reviewed-by: Ulf Hermann --- process.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/process.cpp b/process.cpp index 2ee9246..451e1f8 100644 --- a/process.cpp +++ b/process.cpp @@ -261,8 +261,6 @@ void Process::stop() if (kill(mDebuggee, SIGKILL) != 0) perror("Could not kill debugee"); } - if (kill(-getpid(), SIGTERM) != 0) - perror("Could not kill process group"); mProcess->terminate(); if (!mProcess->waitForFinished()) From 271cf667d74a91acf3c203180526ac449ba0c49a Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Tue, 18 Oct 2016 10:03:04 +0200 Subject: [PATCH 14/18] Fix setting default application with invalid symlink Change-Id: Ia99140c0a8f8cf201eeaad352c36becbb1f6636f Reviewed-by: Karim Pinter Reviewed-by: Samuli Piippo --- main.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/main.cpp b/main.cpp index 854276e..db818e6 100644 --- a/main.cpp +++ b/main.cpp @@ -245,14 +245,32 @@ bool parseConfigFileDirectory(Config *config, const QString &dirName) static bool removeDefault() { - if (QFile::exists(B2QT_PREFIX)) { + QFileInfo fi(B2QT_PREFIX); + + if (fi.isSymLink()) { if (!QFile::remove(B2QT_PREFIX)) { fprintf(stderr, "Could not remove default application.\n"); return false; } sync(); + return true; } - return true; + + if (fi.isDir()) { + fprintf(stderr, "Could not remove default application because '" B2QT_PREFIX "' is a directory. It should be a symlink.\n"); + return false; + } + + if (fi.isFile()) { + fprintf(stderr, "Could not remove default application because '" B2QT_PREFIX "' is a file. It should be a symlink.\n"); + return false; + } + + if (!fi.exists()) { + return true; + } + + return false; } static bool makeDefault(const QString &filepath) From 384775293c03db5d25b57f112eaa1a01e380cbe6 Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Wed, 23 Nov 2016 13:15:28 +0100 Subject: [PATCH 15/18] Change license text Change-Id: I74e5115a032cd94d245e63d7d9e47f3d028e0110 Reviewed-by: Samuli Piippo --- main.cpp | 25 ++++++++++++++----------- perfprocesshandler.cpp | 25 ++++++++++++++----------- perfprocesshandler.h | 25 ++++++++++++++----------- portlist.cpp | 25 ++++++++++++++----------- portlist.h | 25 ++++++++++++++----------- process.cpp | 25 ++++++++++++++----------- process.h | 25 ++++++++++++++----------- 7 files changed, 98 insertions(+), 77 deletions(-) diff --git a/main.cpp b/main.cpp index 854276e..13bd85e 100644 --- a/main.cpp +++ b/main.cpp @@ -1,20 +1,23 @@ -/**************************************************************************** +/****************************************************************************** ** -** Copyright (C) 2014 Digia Plc -** All rights reserved. -** For any questions to Digia, please use contact form at http://www.qt.io +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** -** This file is part of Qt Enterprise Embedded. +** This file is part of Qt for Device Creation. ** -** Licensees holding valid Qt Enterprise licenses may use this file in -** accordance with the Qt Enterprise License Agreement provided with the +** $QT_BEGIN_LICENSE:COMM$ +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** If you have questions regarding the use of this file, please use -** contact form at http://www.qt.io +** $QT_END_LICENSE$ ** -****************************************************************************/ +******************************************************************************/ #include "process.h" #include "portlist.h" diff --git a/perfprocesshandler.cpp b/perfprocesshandler.cpp index 9b609ab..2f6000b 100644 --- a/perfprocesshandler.cpp +++ b/perfprocesshandler.cpp @@ -1,20 +1,23 @@ -/**************************************************************************** +/****************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd -** All rights reserved. -** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** -** This file is part of QtEnterprise Embedded. +** This file is part of Qt for Device Creation. ** -** Licensees holding valid Qt Enterprise licenses may use this file in -** accordance with the Qt Enterprise License Agreement provided with the +** $QT_BEGIN_LICENSE:COMM$ +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** If you have questions regarding the use of this file, please use -** contact form at http://www.qt.io/contact-us +** $QT_END_LICENSE$ ** -****************************************************************************/ +******************************************************************************/ #include "perfprocesshandler.h" #include diff --git a/perfprocesshandler.h b/perfprocesshandler.h index f10e8a6..b7867ce 100644 --- a/perfprocesshandler.h +++ b/perfprocesshandler.h @@ -1,20 +1,23 @@ -/**************************************************************************** +/****************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd -** All rights reserved. -** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** -** This file is part of QtEnterprise Embedded. +** This file is part of Qt for Device Creation. ** -** Licensees holding valid Qt Enterprise licenses may use this file in -** accordance with the Qt Enterprise License Agreement provided with the +** $QT_BEGIN_LICENSE:COMM$ +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** If you have questions regarding the use of this file, please use -** contact form at http://www.qt.io/contact-us +** $QT_END_LICENSE$ ** -****************************************************************************/ +******************************************************************************/ #ifndef PERFPROCESSHANDLER_H #define PERFPROCESSHANDLER_H diff --git a/portlist.cpp b/portlist.cpp index a93814e..6a3a0de 100644 --- a/portlist.cpp +++ b/portlist.cpp @@ -1,20 +1,23 @@ -/**************************************************************************** +/****************************************************************************** ** -** Copyright (C) 2014 Digia Plc -** All rights reserved. -** For any questions to Digia, please use contact form at http://www.qt.io +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** -** This file is part of Qt Enterprise Embedded. +** This file is part of Qt for Device Creation. ** -** Licensees holding valid Qt Enterprise licenses may use this file in -** accordance with the Qt Enterprise License Agreement provided with the +** $QT_BEGIN_LICENSE:COMM$ +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** If you have questions regarding the use of this file, please use -** contact form at http://www.qt.io +** $QT_END_LICENSE$ ** -****************************************************************************/ +******************************************************************************/ #include "portlist.h" diff --git a/portlist.h b/portlist.h index 171194c..5ad0954 100644 --- a/portlist.h +++ b/portlist.h @@ -1,20 +1,23 @@ -/**************************************************************************** +/****************************************************************************** ** -** Copyright (C) 2014 Digia Plc -** All rights reserved. -** For any questions to Digia, please use contact form at http://www.qt.io +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** -** This file is part of Qt Enterprise Embedded. +** This file is part of Qt for Device Creation. ** -** Licensees holding valid Qt Enterprise licenses may use this file in -** accordance with the Qt Enterprise License Agreement provided with the +** $QT_BEGIN_LICENSE:COMM$ +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** If you have questions regarding the use of this file, please use -** contact form at http://www.qt.io +** $QT_END_LICENSE$ ** -****************************************************************************/ +******************************************************************************/ #ifndef PORTLIST_H #define PORTLIST_H diff --git a/process.cpp b/process.cpp index 451e1f8..954cc12 100644 --- a/process.cpp +++ b/process.cpp @@ -1,20 +1,23 @@ -/**************************************************************************** +/****************************************************************************** ** -** Copyright (C) 2014 Digia Plc -** All rights reserved. -** For any questions to Digia, please use contact form at http://www.qt.io +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** -** This file is part of Qt Enterprise Embedded. +** This file is part of Qt for Device Creation. ** -** Licensees holding valid Qt Enterprise licenses may use this file in -** accordance with the Qt Enterprise License Agreement provided with the +** $QT_BEGIN_LICENSE:COMM$ +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** If you have questions regarding the use of this file, please use -** contact form at http://www.qt.io +** $QT_END_LICENSE$ ** -****************************************************************************/ +******************************************************************************/ #include "process.h" #include diff --git a/process.h b/process.h index 46bea62..d820707 100644 --- a/process.h +++ b/process.h @@ -1,20 +1,23 @@ -/**************************************************************************** +/****************************************************************************** ** -** Copyright (C) 2014 Digia Plc -** All rights reserved. -** For any questions to Digia, please use contact form at http://www.qt.io +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ ** -** This file is part of Qt Enterprise Embedded. +** This file is part of Qt for Device Creation. ** -** Licensees holding valid Qt Enterprise licenses may use this file in -** accordance with the Qt Enterprise License Agreement provided with the +** $QT_BEGIN_LICENSE:COMM$ +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. ** -** If you have questions regarding the use of this file, please use -** contact form at http://www.qt.io +** $QT_END_LICENSE$ ** -****************************************************************************/ +******************************************************************************/ #ifndef PROCESS_H #define PROCESS_H From d58e21abe213b727d56b5ab869def70204ff01ec Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Wed, 23 Aug 2017 10:33:10 +0200 Subject: [PATCH 16/18] Fix error message Message does not match the parameter names. Change-Id: Ie9d3c52487f596dc43c7b36e4a5bc3ee5fbdaa47 Reviewed-by: hjk --- main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.cpp b/main.cpp index c1d5391..ef1626f 100644 --- a/main.cpp +++ b/main.cpp @@ -435,7 +435,7 @@ int main(int argc, char **argv) } if (detach && (useGDB || useQML)) { - fprintf(stderr, "Detached debugging not possible. --detach and one of --useGDB, --useQML must not be used together.\n"); + fprintf(stderr, "Detached debugging not possible. --detach and one of --debug-gdb, --debug-qml must not be used together.\n"); return 1; } From 5ab7fdbf0845c40418272bafa565295511055d3b Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Wed, 23 Aug 2017 10:35:56 +0200 Subject: [PATCH 17/18] Allow to set used debugging port via commandline Change-Id: I6f99e2bf77aed2503119959d46c48e359940600a Reviewed-by: hjk Reviewed-by: Mikko Gronoff Reviewed-by: Samuli Piippo --- main.cpp | 57 +++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 11 deletions(-) diff --git a/main.cpp b/main.cpp index ef1626f..421aae1 100644 --- a/main.cpp +++ b/main.cpp @@ -39,7 +39,7 @@ #include #define PID_FILE "/data/user/.appcontroller" -#define FEATURES "restart perf eglresize qmldebugservices" +#define FEATURES "restart perf eglresize qmldebugservices explicitdebugports" #define B2QT_PREFIX "/usr/bin/b2qt" @@ -49,14 +49,17 @@ static const char socketPath[] = "#Boot2Qt_appcontroller"; static void usage() { - printf("appcontroller [--debug-gdb] [--debug-qml] [--qml-debug-services ]" + printf("appcontroller [--debug-gdb] [--debug-gdb-port ]" + " [--debug-qml] [--debug-qml-port ] [--qml-debug-services ]" " [--profile-perf ] [--port-range ] [--stop] [--launch] [--show-platfrom]" " [--make-default] [--remove-default] [--print-debug] [--version] [--detach]" " [executable] [arguments]\n" "\n" "--port-range Port range to use for debugging connections\n" "--debug-gdb Start GDB debugging\n" + "--debug-gdb-port Port to be used for GDB debugging\n" "--debug-qml Start QML debugging or profiling\n" + "--debug-qml-port Port to be used for QML debugging\n" "--qml-debug-services Specify services to use for QML debugging/profiling\n" "--profile-perf Start perf profiling\n" "--stop Stop already running application\n" @@ -329,6 +332,7 @@ int main(int argc, char **argv) QStringList defaultArgs; quint16 gdbDebugPort = 0; + quint16 qmlDebugPort = 0; bool useGDB = false; bool useQML = false; QString qmlDebugServices; @@ -363,8 +367,28 @@ int main(int argc, char **argv) useGDB = true; setpgid(0,0); // must be called before setsid() setsid(); + } else if (arg == "--debug-gdb-port") { + if (args.isEmpty()) { + fprintf(stderr, "--debug-gdb-port requires a port number\n"); + return 1; + } + gdbDebugPort = args.takeFirst().toUInt(); + if (gdbDebugPort < 1) { + fprintf(stderr, "--debug-gdb-port has invalid port number\n"); + return 1; + } } else if (arg == "--debug-qml") { useQML = true; + } else if (arg == "--debug-qml-port") { + if (args.isEmpty()) { + fprintf(stderr, "--debug-qml-port requires a port number\n"); + return 1; + } + qmlDebugPort = args.takeFirst().toUInt(); + if (qmlDebugPort < 1) { + fprintf(stderr, "--debug-qml-port has invalid port number\n"); + return 1; + } } else if (arg == "--qml-debug-services") { if (args.isEmpty()) { fprintf(stderr, "--qml-debug-services requires a list of comma-separated service " @@ -429,8 +453,13 @@ int main(int argc, char **argv) return 1; } - if ((useGDB || useQML) && !range.hasMore()) { - fprintf(stderr, "--port-range is mandatory\n"); + if (useGDB && !(gdbDebugPort || range.hasMore())) { + fprintf(stderr, "--debug-gdb requires --port-range or --debug-gdb-port\n"); + return 1; + } + + if (useQML && !(qmlDebugPort || range.hasMore())) { + fprintf(stderr, "--debug-qml requires --port-range or --debug-qml-port\n"); return 1; } @@ -439,7 +468,10 @@ int main(int argc, char **argv) return 1; } - if (useGDB) { + if (gdbDebugPort && !useGDB) + gdbDebugPort = 0; + + if (useGDB && !gdbDebugPort) { int port = findFirstFreePort(range); if (port < 0) { fprintf(stderr, "Could not find an unused port in range\n"); @@ -448,15 +480,18 @@ int main(int argc, char **argv) gdbDebugPort = port; } if (useQML) { - int port = findFirstFreePort(range); - if (port < 0) { - fprintf(stderr, "Could not find an unused port in range\n"); - return 1; + if (!qmlDebugPort) { + int port = findFirstFreePort(range); + if (port < 0) { + fprintf(stderr, "Could not find an unused port in range\n"); + return 1; + } + qmlDebugPort = port; } - defaultArgs.push_front("-qmljsdebugger=port:" + QString::number(port) + ",block" + + defaultArgs.push_front("-qmljsdebugger=port:" + QString::number(qmlDebugPort) + ",block" + (qmlDebugServices.isEmpty() ? "" : (",services:" + qmlDebugServices))); - printf("QML Debugger: Going to wait for connection on port %d...\n", port); + printf("QML Debugger: Going to wait for connection on port %d...\n", qmlDebugPort); } defaultArgs.push_front(args.takeFirst()); From 474fa4b7aee62e704158d213d9e67eba74c69401 Mon Sep 17 00:00:00 2001 From: Samuli Piippo Date: Tue, 27 Aug 2019 10:07:44 +0300 Subject: [PATCH 18/18] Add option to read environment variables from a file Add option "environmentFile=..." that can be point to a separate file containing environment variables in ENV=VALUE pairs, which is normally used in /etc/default/ config files. Change-Id: If21d6c260d93f1ada309eb4e917b30e9c2daa877 Reviewed-by: Kari Oikarinen --- main.cpp | 23 +++++++++++++++++++++++ process.h | 1 + 2 files changed, 24 insertions(+) diff --git a/main.cpp b/main.cpp index 421aae1..8f6d214 100644 --- a/main.cpp +++ b/main.cpp @@ -195,6 +195,25 @@ static int findFirstFreePort(Utils::PortList &range) return openServer(&s, range); } +bool readEnvs(Config *config) +{ + QFile f(config->envFile); + if (!f.open(QFile::ReadOnly)) { + fprintf(stderr, "Could not read environment file: %s\n", qPrintable(config->envFile)); + return false; + } + + while (!f.atEnd()) { + const auto line = f.readLine().simplified(); + if (!line.startsWith("#")) { + const auto index = line.indexOf('='); + config->env[line.left(index)] = line.mid(index + 1); + } + } + f.close(); + return true; +} + bool parseConfigFile(Config *config, const QString &fileName) { QFile f(fileName); @@ -227,6 +246,8 @@ bool parseConfigFile(Config *config, const QString &fileName) config->debugInterface = Config::PublicDebugInterface; else qWarning() << "Unkonwn value for debuginterface:" << value; + } else if (line.startsWith("environmentFile=")) { + config->envFile = line.mid(16).simplified(); } } f.close(); @@ -349,6 +370,8 @@ int main(int argc, char **argv) Config config; if (!parseConfigFile(&config, "/etc/appcontroller.conf")) fprintf(stderr, "Failed to parse config file.\n"); + if (!config.envFile.isEmpty()) + readEnvs(&config); while (!args.isEmpty()) { const QString arg(args.takeFirst()); diff --git a/process.h b/process.h index d820707..8b84779 100644 --- a/process.h +++ b/process.h @@ -42,6 +42,7 @@ struct Config { QMap env; QStringList args; DebugInterface debugInterface; + QString envFile; }; class Process : public QObject