summaryrefslogtreecommitdiff
path: root/src/plugins/debugger/debuggeritem.cpp
diff options
context:
space:
mode:
authorMichael Kopp <kopp.michael@yahoo.de>2018-11-20 22:31:27 +0100
committerMichael Kopp <kopp.michael@yahoo.de>2018-12-13 21:35:28 +0000
commit7e45ccc99b18ba7448e2f3833c6abefb81a251f3 (patch)
tree4d6d7ae6a3e9f5a2b0b0457e797bb840936dd308 /src/plugins/debugger/debuggeritem.cpp
parentbe4bd1dc06444dc44072ac3812a63dc02dab54e5 (diff)
downloadqt-creator-7e45ccc99b18ba7448e2f3833c6abefb81a251f3.tar.gz
determine gdb target ABI by parsing 'gdb --configuration'
Currently, the gdb target ABI is determined by running `gdb -version`, which for recent gdb's does not reproduce the target ABI string -- yet this string is searched in the output. This obviously fails, and qtcreator uses a fallback behavior, that is not suitable when using gdb for debugging on targets (like avr microcontrollers). With this change, QtCreator calls `gdb --configuration` if that is supported by gdb and extracts `<string> from `--target=<string>` in the output. For older versions of gdb (which do not support the `--configuration` flag, but still have the target information in the output of `--version`, the output of `--version` is parsed. If both methods fail, no ABI is set for gdb. Change-Id: Ib406f6700b63e2cedb46bd4ec8cc0d215677ecdc Reviewed-by: Michael Kopp <kopp.michael@yahoo.de> Reviewed-by: hjk <hjk@qt.io> Reviewed-by: Orgad Shaneh <orgads@gmail.com>
Diffstat (limited to 'src/plugins/debugger/debuggeritem.cpp')
-rw-r--r--src/plugins/debugger/debuggeritem.cpp73
1 files changed, 57 insertions, 16 deletions
diff --git a/src/plugins/debugger/debuggeritem.cpp b/src/plugins/debugger/debuggeritem.cpp
index a46908923f..2c889a016b 100644
--- a/src/plugins/debugger/debuggeritem.cpp
+++ b/src/plugins/debugger/debuggeritem.cpp
@@ -31,6 +31,7 @@
#include <projectexplorer/abi.h>
+#include <utils/algorithm.h>
#include <utils/fileutils.h>
#include <utils/hostosinfo.h>
#include <utils/macroexpander.h>
@@ -61,6 +62,35 @@ const char DEBUGGER_INFORMATION_ABIS[] = "Abis";
const char DEBUGGER_INFORMATION_LASTMODIFIED[] = "LastModified";
const char DEBUGGER_INFORMATION_WORKINGDIRECTORY[] = "WorkingDirectory";
+
+//! Return the configuration of gdb as a list of --key=value
+//! \note That the list will also contain some output not in this format.
+static QString getConfigurationOfGdbCommand(const QString &command)
+{
+ // run gdb with the --configuration opion
+ Utils::SynchronousProcess gdbConfigurationCall;
+ Utils::SynchronousProcessResponse output =
+ gdbConfigurationCall.runBlocking(command, {QString("--configuration")});
+ return output.allOutput();
+}
+
+//! Extract the target ABI identifier from GDB output
+//! \return QString() (aka Null) if unable to find something
+static QString extractGdbTargetAbiStringFromGdbOutput(const QString &gdbOutput)
+{
+ const auto outputLines = gdbOutput.split('\n');
+ const auto whitespaceSeparatedTokens = outputLines.join(' ').split(' ', QString::SkipEmptyParts);
+
+ const QString targetKey{"--target="};
+ const QString targetValue = Utils::findOrDefault(whitespaceSeparatedTokens,
+ [&targetKey](const QString &token) { return token.startsWith(targetKey); });
+ if (!targetValue.isEmpty())
+ return targetValue.mid(targetKey.size());
+
+ return {};
+}
+
+
namespace Debugger {
// --------------------------------------------------------------------------
@@ -130,22 +160,6 @@ void DebuggerItem::reinitializeFromFile()
const QString output = response.allOutput().trimmed();
if (output.contains("gdb")) {
m_engineType = GdbEngineType;
- const char needle[] = "This GDB was configured as \"";
- // E.g. "--host=i686-pc-linux-gnu --target=arm-unknown-nto-qnx6.5.0".
- // or "i686-linux-gnu"
- int pos1 = output.indexOf(needle);
- if (pos1 != -1) {
- pos1 += int(strlen(needle));
- int pos2 = output.indexOf('"', pos1 + 1);
- QString target = output.mid(pos1, pos2 - pos1);
- int pos3 = target.indexOf("--target=");
- if (pos3 >= 0)
- target = target.mid(pos3 + 9);
- m_abis.append(Abi::abiFromTargetTriplet(target));
- } else {
- // Fallback.
- m_abis = Abi::abisOfBinary(m_command); // FIXME: Wrong.
- }
// Version
bool isMacGdb, isQnxGdb;
@@ -155,6 +169,33 @@ void DebuggerItem::reinitializeFromFile()
if (version)
m_version = QString::fromLatin1("%1.%2.%3")
.arg(version / 10000).arg((version / 100) % 100).arg(version % 100);
+
+ // ABI
+ const bool unableToFindAVersion = (0 == version);
+ const bool gdbSupportsConfigurationFlag = (version >= 70700);
+ if (gdbSupportsConfigurationFlag || unableToFindAVersion) {
+ const auto gdbConfiguration = getConfigurationOfGdbCommand(m_command.toString());
+ const auto gdbTargetAbiString =
+ extractGdbTargetAbiStringFromGdbOutput(gdbConfiguration);
+ if (!gdbTargetAbiString.isEmpty()) {
+ m_abis.append(Abi::abiFromTargetTriplet(gdbTargetAbiString));
+ return;
+ }
+ }
+
+ // ABI: legacy: the target was removed from the output of --version with
+ // https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commit;h=c61b06a19a34baab66e3809c7b41b0c31009ed9f
+ auto legacyGdbTargetAbiString = extractGdbTargetAbiStringFromGdbOutput(output);
+ if (!legacyGdbTargetAbiString.isEmpty()) {
+ // remove trailing "
+ legacyGdbTargetAbiString =
+ legacyGdbTargetAbiString.left(legacyGdbTargetAbiString.length() - 1);
+ m_abis.append(Abi::abiFromTargetTriplet(legacyGdbTargetAbiString));
+ return;
+ }
+
+ qWarning() << "Unable to determine gdb target ABI";
+ //! \note If unable to determine the GDB ABI, no ABI is appended to m_abis here.
return;
}
if (output.startsWith("lldb") || output.startsWith("LLDB")) {