diff options
author | Michael Kopp <kopp.michael@yahoo.de> | 2018-11-20 22:31:27 +0100 |
---|---|---|
committer | Michael Kopp <kopp.michael@yahoo.de> | 2018-12-13 21:35:28 +0000 |
commit | 7e45ccc99b18ba7448e2f3833c6abefb81a251f3 (patch) | |
tree | 4d6d7ae6a3e9f5a2b0b0457e797bb840936dd308 /src/plugins/debugger/debuggeritem.cpp | |
parent | be4bd1dc06444dc44072ac3812a63dc02dab54e5 (diff) | |
download | qt-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.cpp | 73 |
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")) { |