From 3d34ccf4d9afb9d0b1e5557e018c76d1106dcc1b Mon Sep 17 00:00:00 2001
From: hjk <hjk@theqtcompany.com>
Date: Tue, 19 Apr 2016 14:01:44 +0200
Subject: [PATCH] Debugger: Enforce use of target-async for Android gdbserver

Since NDK r11 this seems to be needed to get breakpoints set
correctly on Linux and Mac.

Change-Id: I54281feecc0a915d4761228c612b72889756aecf
Reviewed-by: BogDan Vatra <bogdan@kdab.com>
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
---
 src/plugins/android/androiddebugsupport.cpp         | 4 ++++
 src/plugins/debugger/debuggerstartparameters.h      | 1 +
 src/plugins/debugger/gdb/gdbengine.cpp              | 7 ++++++-
 src/plugins/debugger/gdb/gdbengine.h                | 1 +
 src/plugins/debugger/gdb/remotegdbserveradapter.cpp | 4 ++--
 5 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/src/plugins/android/androiddebugsupport.cpp b/src/plugins/android/androiddebugsupport.cpp
index 1cc8737a48d..12a523afe11 100644
--- a/src/plugins/android/androiddebugsupport.cpp
+++ b/src/plugins/android/androiddebugsupport.cpp
@@ -42,6 +42,8 @@
 
 #include <qtsupport/qtkitinformation.h>
 
+#include <utils/hostosinfo.h>
+
 #include <QDirIterator>
 #include <QTcpServer>
 
@@ -93,6 +95,8 @@ RunControl *AndroidDebugSupport::createDebugRunControl(AndroidRunConfiguration *
     params.displayName = AndroidManager::packageName(target);
     params.remoteSetupNeeded = true;
     params.useContinueInsteadOfRun = true;
+    if (!Utils::HostOsInfo::isWindowsHost()) // Workaround for NDK 11c(b?)
+        params.useTargetAsync = true;
 
     auto aspect = runConfig->extraAspect<DebuggerRunConfigurationAspect>();
     if (aspect->useCppDebugger()) {
diff --git a/src/plugins/debugger/debuggerstartparameters.h b/src/plugins/debugger/debuggerstartparameters.h
index adbbb8f4d7d..06183117a7c 100644
--- a/src/plugins/debugger/debuggerstartparameters.h
+++ b/src/plugins/debugger/debuggerstartparameters.h
@@ -98,6 +98,7 @@ public:
 
     // Used by Android to avoid false positives on warnOnRelease
     bool skipExecutableValidation = false;
+    bool useTargetAsync = false;
     QStringList additionalSearchDirectories;
 
     // Used by iOS.
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index 2251a0d3ab3..d950f41b245 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -4436,7 +4436,12 @@ bool GdbEngine::usesExecInterrupt() const
 {
     DebuggerStartMode mode = runParameters().startMode;
     return (mode == AttachToRemoteServer || mode == AttachToRemoteProcess)
-        && boolSetting(TargetAsync);
+            && usesTargetAsync();
+}
+
+bool GdbEngine::usesTargetAsync() const
+{
+    return runParameters().useTargetAsync || boolSetting(TargetAsync);
 }
 
 void GdbEngine::scheduleTestResponse(int testCase, const QByteArray &response)
diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h
index 20464d00c67..ad4ead27116 100644
--- a/src/plugins/debugger/gdb/gdbengine.h
+++ b/src/plugins/debugger/gdb/gdbengine.h
@@ -423,6 +423,7 @@ protected:
     bool m_terminalTrap;
     bool m_temporaryStopPending;
     bool usesExecInterrupt() const;
+    bool usesTargetAsync() const;
 
     QHash<int, QByteArray> m_scheduledTestResponses;
     QSet<int> m_testCases;
diff --git a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp
index 739973fd709..6c4e9621725 100644
--- a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp
+++ b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp
@@ -205,7 +205,7 @@ void GdbRemoteServerEngine::setupInferior()
     // gdb/mi/mi-main.c:1958: internal-error:
     // mi_execute_async_cli_command: Assertion `is_running (inferior_ptid)'
     // failed.\nA problem internal to GDB has been detected,[...]
-    if (boolSetting(TargetAsync))
+    if (usesTargetAsync())
         runCommand({"set target-async on", NoFlags, CB(handleSetTargetAsync)});
 
     if (symbolFile.isEmpty()) {
@@ -429,7 +429,7 @@ void GdbRemoteServerEngine::handleExecRun(const DebuggerResponse &response)
 void GdbRemoteServerEngine::interruptInferior2()
 {
     QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state());
-    if (boolSetting(TargetAsync)) {
+    if (usesTargetAsync()) {
         runCommand({"-exec-interrupt", NoFlags, CB(handleInterruptInferior)});
     } else if (m_isQnxGdb && HostOsInfo::isWindowsHost()) {
         m_gdbProc.interrupt();
-- 
GitLab