aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--qbs/imports/QtcProduct.qbs9
-rw-r--r--src/plugins/android/androidrunnerworker.cpp95
-rw-r--r--src/plugins/android/androidrunnerworker.h6
-rw-r--r--src/plugins/autotest/testresultmodel.cpp2
-rw-r--r--src/plugins/debugger/gdb/gdbengine.cpp2
-rw-r--r--src/plugins/help/textbrowserhelpviewer.cpp3
-rw-r--r--src/plugins/qmljseditor/qmljsautocompleter.cpp2
7 files changed, 86 insertions, 33 deletions
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
diff --git a/src/plugins/android/androidrunnerworker.cpp b/src/plugins/android/androidrunnerworker.cpp
index 0b4021e9511..6497f50d627 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;
@@ -248,19 +249,60 @@ bool AndroidRunnerWorker::runAdb(const QStringList &args, QString *stdOut,
return result.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<QString, decltype (cleanUp)>
+ 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();
- QString output;
- const bool res = runAdb({"shell", "run-as", m_packageName, QString("sh -c 'base64 -d > %1'").arg(to)},
- &output, data.toBase64());
- if (!res || output.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)
+{
+ QString output;
+ const bool success = runAdb({"shell", "ls", filePath, "2>/dev/null"}, &output);
+ return success && !output.trimmed().isEmpty();
+}
+
+bool AndroidRunnerWorker::packageFileExists(const QString &filePath)
+{
+ QString output;
+ const bool success = runAdb({"shell", "run-as", m_packageName, "ls", filePath, "2>/dev/null"}, &output);
+ return success && !output.trimmed().isEmpty();
}
void AndroidRunnerWorker::adbKill(qint64 pid)
@@ -403,26 +445,28 @@ void AndroidRunnerWorker::asyncStartHelper()
// e.g. on Android 8 with NDK 10e
runAdb({"shell", "run-as", m_packageName, "chmod", "a+x", packageDir.trimmed()});
- QString gdbServerExecutable;
+ QString gdbServerExecutable = "gdbserver";
QString gdbServerPrefix = "./lib/";
- if (m_gdbserverPath.isEmpty() || !uploadFile(m_gdbserverPath, "gdbserver")) {
- // upload failed - check for old devices
- QString output;
- if (runAdb({"shell", "run-as", m_packageName, "ls", "lib/"}, &output)) {
- for (const auto &line: output.split('\n')) {
- if (line.indexOf("gdbserver") != -1/* || line.indexOf("lldb-server") != -1*/) {
- gdbServerExecutable = 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 debuggerServerErr;
@@ -484,7 +528,6 @@ bool AndroidRunnerWorker::startDebuggerServer(const QString &packageDir,
QString *errorStr)
{
QString gdbServerSocket = packageDir + "/debug-socket";
- runAdb({"shell", "run-as", m_packageName, "killall", gdbServerExecutable});
runAdb({"shell", "run-as", m_packageName, "rm", gdbServerSocket});
QString gdbProcessErr;
diff --git a/src/plugins/android/androidrunnerworker.h b/src/plugins/android/androidrunnerworker.h
index 5e5e51cd752..30da68fc2df 100644
--- a/src/plugins/android/androidrunnerworker.h
+++ b/src/plugins/android/androidrunnerworker.h
@@ -47,7 +47,6 @@ public:
AndroidRunnerWorker(ProjectExplorer::RunWorker *runner, const QString &packageName);
~AndroidRunnerWorker() override;
- bool uploadFile(const QString &from, const QString &to, const QString &flags = QString("+x"));
bool runAdb(const QStringList &args, QString *stdOut = nullptr, const QByteArray &writeData = {});
void adbKill(qint64 pid);
QStringList selector() const;
@@ -71,10 +70,13 @@ signals:
void remoteOutput(const QString &output);
void remoteErrorOutput(const QString &output);
-protected:
+private:
void asyncStartHelper();
bool startDebuggerServer(const QString &packageDir, const QString &gdbServerPrefix,
const QString &gdbServerExecutable, QString *errorStr = nullptr);
+ bool deviceFileExists(const QString &filePath);
+ bool packageFileExists(const QString& filePath);
+ bool uploadGdbServer();
enum class JDBState {
Idle,
diff --git a/src/plugins/autotest/testresultmodel.cpp b/src/plugins/autotest/testresultmodel.cpp
index c1d86342f00..6cabd39cbcf 100644
--- a/src/plugins/autotest/testresultmodel.cpp
+++ b/src/plugins/autotest/testresultmodel.cpp
@@ -145,7 +145,7 @@ void TestResultItem::updateResult(bool &changed, Result::Type addedChildType)
? Result::MessageTestCaseSuccess : old;
break;
default:
- return;
+ break;
}
changed = old != newResult;
if (changed)
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index b51afe098e5..8d2af5008a7 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -1714,7 +1714,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();
diff --git a/src/plugins/help/textbrowserhelpviewer.cpp b/src/plugins/help/textbrowserhelpviewer.cpp
index e0f151c30b1..d729535fa38 100644
--- a/src/plugins/help/textbrowserhelpviewer.cpp
+++ b/src/plugins/help/textbrowserhelpviewer.cpp
@@ -430,7 +430,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;
}
diff --git a/src/plugins/qmljseditor/qmljsautocompleter.cpp b/src/plugins/qmljseditor/qmljsautocompleter.cpp
index 281c80d860f..5c8dc78b68c 100644
--- a/src/plugins/qmljseditor/qmljsautocompleter.cpp
+++ b/src/plugins/qmljseditor/qmljsautocompleter.cpp
@@ -230,7 +230,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))