From d886285ff0f9931b39a6069bc5260cf2148757eb Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Thu, 31 Jan 2019 15:45:28 +0100 Subject: [PATCH 1/6] AutoTest: Fix handling of empty tests If an item of type MessageCaseStart is going to be updated it might end up in still getting no icon if none of its children is enforcing a change. Change-Id: I7ec6d114c547189a02744f064d4c04cdf31a03d7 Reviewed-by: David Schulz --- src/plugins/autotest/testresultmodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/autotest/testresultmodel.cpp b/src/plugins/autotest/testresultmodel.cpp index a694ba8c228..cbd9d5db9af 100644 --- a/src/plugins/autotest/testresultmodel.cpp +++ b/src/plugins/autotest/testresultmodel.cpp @@ -141,7 +141,7 @@ void TestResultItem::updateResult(bool &changed, Result::Type addedChildType) ? Result::MessageTestCaseSuccess : old; break; default: - return; + break; } changed = old != newResult; if (changed) From 59de3fcb6416dc0387e85a1852d1226ae507b7fe Mon Sep 17 00:00:00 2001 From: Vikas Pachdha Date: Thu, 20 Dec 2018 18:40:34 +0100 Subject: [PATCH 2/6] Android: Fix gdbserver upload for Windows when using Armv8 arch The gdbserver is not uploaded to device for armv7 as lib symlink is available and we can use the gdbserver packaged with the apk Task-number: QTCREATORBUG-21317 Change-Id: I263eb48bbf3cf05b969db934a928185dba10373b Reviewed-by: Eike Ziller Reviewed-by: hjk --- src/plugins/android/androidrunnerworker.cpp | 90 +++++++++++++++------ src/plugins/android/androidrunnerworker.h | 6 +- 2 files changed, 71 insertions(+), 25 deletions(-) diff --git a/src/plugins/android/androidrunnerworker.cpp b/src/plugins/android/androidrunnerworker.cpp index a4b6772f610..37191848fdc 100644 --- a/src/plugins/android/androidrunnerworker.cpp +++ b/src/plugins/android/androidrunnerworker.cpp @@ -53,6 +53,7 @@ namespace { Q_LOGGING_CATEGORY(androidRunWorkerLog, "qtc.android.run.androidrunnerworker", QtWarningMsg) +static const int GdbTempFileMaxCounter = 20; } using namespace std; @@ -274,17 +275,58 @@ bool AndroidRunnerWorker::runAdb(const QStringList &args, int timeoutS, const QB return success; } -bool AndroidRunnerWorker::uploadFile(const QString &from, const QString &to, const QString &flags) +bool AndroidRunnerWorker::uploadGdbServer() { - QFile f(from); - if (!f.open(QIODevice::ReadOnly)) + // Push the gdbserver to temp location and then to package dir. + // the files can't be pushed directly to package because of permissions. + qCDebug(androidRunWorkerLog) << "Uploading GdbServer"; + + bool foundUnique = true; + auto cleanUp = [this, &foundUnique] (QString *p) { + if (foundUnique && !runAdb({"shell", "rm", "-f", *p})) + qCDebug(androidRunWorkerLog) << "Gdbserver cleanup failed."; + delete p; + }; + std::unique_ptr + tempGdbServerPath(new QString("/data/local/tmp/%1"), cleanUp); + + // Get a unique temp file name for gdbserver copy + int count = 0; + while (deviceFileExists(tempGdbServerPath->arg(++count))) { + if (count > GdbTempFileMaxCounter) { + qCDebug(androidRunWorkerLog) << "Can not get temporary file name"; + foundUnique = false; + return false; + } + } + *tempGdbServerPath = tempGdbServerPath->arg(count); + + // Copy gdbserver to temp location + if (!runAdb({"push", m_gdbserverPath , *tempGdbServerPath})) { + qCDebug(androidRunWorkerLog) << "Gdbserver upload to temp directory failed"; return false; - runAdb({"shell", "run-as", m_packageName, "rm", to}); - const QByteArray data = f.readAll(); - const bool res = runAdb({"shell", "run-as", m_packageName, QString("sh -c 'base64 -d > %1'").arg(to)}, 60, data.toBase64()); - if (!res || m_lastRunAdbRawOutput.contains("base64: not found")) + } + + // Copy gdbserver from temp location to app directory + if (!runAdb({"shell", "run-as", m_packageName, "cp" , *tempGdbServerPath, "./gdbserver"})) { + qCDebug(androidRunWorkerLog) << "Gdbserver copy from temp directory failed"; return false; - return runAdb({"shell", "run-as", m_packageName, "chmod", flags, to}); + } + QTC_ASSERT(runAdb({"shell", "run-as", m_packageName, "chmod", "+x", "./gdbserver"}), + qCDebug(androidRunWorkerLog) << "Gdbserver chmod +x failed."); + return true; +} + +bool AndroidRunnerWorker::deviceFileExists(const QString &filePath) +{ + return runAdb({"shell", "ls", filePath, "2>/dev/null"}) + && !m_lastRunAdbRawOutput.trimmed().isEmpty(); +} + +bool AndroidRunnerWorker::packageFileExists(const QString &filePath) +{ + return runAdb({"shell", "run-as", m_packageName, "ls", filePath, "2>/dev/null"}) + && !m_lastRunAdbRawOutput.trimmed().isEmpty(); } void AndroidRunnerWorker::adbKill(qint64 pid) @@ -428,29 +470,31 @@ void AndroidRunnerWorker::asyncStartHelper() // e.g. on Android 8 with NDK 10e runAdb({"shell", "run-as", m_packageName, "chmod", "a+x", packageDir}); - QString gdbServerExecutable; + QString gdbServerExecutable = "gdbserver"; QString gdbServerPrefix = "./lib/"; - if (m_gdbserverPath.isEmpty() || !uploadFile(m_gdbserverPath, "gdbserver")) { - // upload failed - check for old devices - if (runAdb({"shell", "run-as", m_packageName, "ls", "lib/"})) { - for (const auto &line: m_lastRunAdbRawOutput.split('\n')) { - if (line.indexOf("gdbserver") != -1/* || line.indexOf("lldb-server") != -1*/) { - gdbServerExecutable = QString::fromUtf8(line.trimmed()); - break; - } - } - } - if (gdbServerExecutable.isEmpty()) { + auto findGdbServer = [this, &gdbServerExecutable, gdbServerPrefix](const QString& gdbEx) { + if (!packageFileExists(gdbServerPrefix + gdbEx)) + return false; + gdbServerExecutable = gdbEx; + return true; + }; + + if (!findGdbServer("gdbserver") && !findGdbServer("libgdbserver.so")) { + // Armv8. symlink lib is not available. + // Kill the previous instances of gdbserver. Do this before copying the gdbserver. + runAdb({"shell", "run-as", m_packageName, "killall", gdbServerExecutable}); + if (!m_gdbserverPath.isEmpty() && uploadGdbServer()) { + gdbServerPrefix = "./"; + } else { emit remoteProcessFinished(tr("Cannot find/copy C++ debug server.")); return; } } else { - gdbServerPrefix = "./"; - gdbServerExecutable = "gdbserver"; + qCDebug(androidRunWorkerLog) << "Found GDB server under ./lib"; + runAdb({"shell", "run-as", m_packageName, "killall", gdbServerExecutable}); } QString gdbServerSocket = packageDir + "/debug-socket"; - runAdb({"shell", "run-as", m_packageName, "killall", gdbServerExecutable}); runAdb({"shell", "run-as", m_packageName, "rm", gdbServerSocket}); std::unique_ptr gdbServerProcess(new QProcess, deleter); diff --git a/src/plugins/android/androidrunnerworker.h b/src/plugins/android/androidrunnerworker.h index 18639683ae5..39b25a1a292 100644 --- a/src/plugins/android/androidrunnerworker.h +++ b/src/plugins/android/androidrunnerworker.h @@ -48,7 +48,6 @@ public: ~AndroidRunnerWorker() override; bool adbShellAmNeedsQuotes(); bool runAdb(const QStringList &args, int timeoutS = 10, const QByteArray &writeData = {}); - bool uploadFile(const QString &from, const QString &to, const QString &flags = QString("+x")); void adbKill(qint64 pid); QStringList selector() const; void forceStop(); @@ -71,8 +70,11 @@ signals: void remoteOutput(const QString &output); void remoteErrorOutput(const QString &output); -protected: +private: void asyncStartHelper(); + bool deviceFileExists(const QString &filePath); + bool packageFileExists(const QString& filePath); + bool uploadGdbServer(); enum class JDBState { Idle, From 5e054115ec61ad1ed7c70479323a38ad9e2af93b Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 1 Feb 2019 09:25:15 +0100 Subject: [PATCH 3/6] QML: Fix auto-insertion of single quote After inserting a matching single quote it should not add yet another single quote when typing one explicitly. Change-Id: I568f02e4edbb78ef11665bb7f4a9f3b91cf9b887 Reviewed-by: Ulf Hermann Reviewed-by: David Schulz --- src/plugins/qmljseditor/qmljsautocompleter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmljseditor/qmljsautocompleter.cpp b/src/plugins/qmljseditor/qmljsautocompleter.cpp index e50c268d2ca..ac39e98f900 100644 --- a/src/plugins/qmljseditor/qmljsautocompleter.cpp +++ b/src/plugins/qmljseditor/qmljsautocompleter.cpp @@ -232,7 +232,7 @@ bool AutoCompleter::contextAllowsAutoQuotes(const QTextCursor &cursor, } // never insert ' into string literals, it adds spurious ' when writing contractions - if (textToInsert.at(0) == QLatin1Char('\'')) + if (textToInsert.at(0) == QLatin1Char('\'') && quote != '\'') return false; if (textToInsert.at(0) != quote || isCompleteStringLiteral(tokenText)) From 0aa8a98afa964d9ebf819d157ed9d600bff3633f Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 22 Jan 2019 15:54:09 +0100 Subject: [PATCH 4/6] Help: Disable middle-mouse click outside of help mode Since only help mode supports it. Fixes: QTCREATORBUG-20554 Change-Id: Ida8cee01c0ab0c8fc5ffacf3c4521feeadf65995 Reviewed-by: David Schulz --- src/plugins/help/textbrowserhelpviewer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/help/textbrowserhelpviewer.cpp b/src/plugins/help/textbrowserhelpviewer.cpp index 930df58207b..6f47f000cbc 100644 --- a/src/plugins/help/textbrowserhelpviewer.cpp +++ b/src/plugins/help/textbrowserhelpviewer.cpp @@ -432,7 +432,8 @@ void TextBrowserHelpWidget::mouseReleaseEvent(QMouseEvent *e) bool controlPressed = e->modifiers() & Qt::ControlModifier; const QString link = linkAt(e->pos()); - if ((controlPressed || e->button() == Qt::MidButton) && !link.isEmpty()) { + if (m_parent->isActionVisible(HelpViewer::Action::NewPage) + && (controlPressed || e->button() == Qt::MidButton) && !link.isEmpty()) { emit m_parent->newPageRequested(QUrl(link)); return; } From 18f1a8d759073e4d8cddfaa99a77c72f21efa5c3 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 31 Jan 2019 12:31:08 +0100 Subject: [PATCH 5/6] Debugger: Fix gdb detaching Too much cleverness in python command detection: "attach" is parsed as possible Python command. Make it explicit that it is not. Task-number: QTCREATORBUG-21908 Change-Id: I68444bccfb485ef1befe81b4b6b13243c2c8a500 Reviewed-by: Eike Ziller Reviewed-by: Christian Stenger --- src/plugins/debugger/gdb/gdbengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 2ecbf285349..283850d2397 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -1736,7 +1736,7 @@ void GdbEngine::detachDebugger() { CHECK_STATE(InferiorStopOk); QTC_CHECK(runParameters().startMode != AttachCore); - DebuggerCommand cmd("detach", ExitRequest); + DebuggerCommand cmd("detach", NativeCommand | ExitRequest); cmd.callback = [this](const DebuggerResponse &) { CHECK_STATE(InferiorStopOk); notifyInferiorExited(); From ffa14187a1a6876cabe14a19513462117de68594 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 4 Feb 2019 09:29:22 +0100 Subject: [PATCH 6/6] qbs build: Fix regression with qbs 1.13 Don't fall back to pkg-config for non-existing dev headers products, as that becomes expensive. Change-Id: Ibf51a93950e04ee061ca16444fbc18349389d74a Reviewed-by: Christian Stenger --- qbs/imports/QtcProduct.qbs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/qbs/imports/QtcProduct.qbs b/qbs/imports/QtcProduct.qbs index 0dc1e9b3b1f..1caf073e988 100644 --- a/qbs/imports/QtcProduct.qbs +++ b/qbs/imports/QtcProduct.qbs @@ -19,7 +19,14 @@ Product { Depends { name: "cpp" } Depends { name: "qtc" } - Depends { name: product.name + " dev headers"; required: false } + Depends { + name: product.name + " dev headers"; + required: false + Properties { + condition: Utilities.versionCompare(qbs.version, "1.13") >= 0 + enableFallback: false + } + } Depends { name: "Qt.core"; versionAtLeast: "5.9.0" } // TODO: Should fall back to what came from Qt.core for Qt < 5.7, but we cannot express that