diff options
Diffstat (limited to 'src')
47 files changed, 278 insertions, 3107 deletions
diff --git a/src/plugins/android/androidrunconfiguration.cpp b/src/plugins/android/androidrunconfiguration.cpp index 742bf77617..558777b041 100644 --- a/src/plugins/android/androidrunconfiguration.cpp +++ b/src/plugins/android/androidrunconfiguration.cpp @@ -150,14 +150,6 @@ const QString AndroidRunConfiguration::remoteChannel() const return QLatin1String(":5039"); } -const QString AndroidRunConfiguration::dumperLib() const -{ - QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(target()->kit()); - if (!version) - return QString(); - return version->gdbDebuggingHelperLibrary(); -} - QString AndroidRunConfiguration::proFilePath() const { return m_proFilePath; diff --git a/src/plugins/android/androidrunconfiguration.h b/src/plugins/android/androidrunconfiguration.h index a8bbb65e43..9efcdc345e 100644 --- a/src/plugins/android/androidrunconfiguration.h +++ b/src/plugins/android/androidrunconfiguration.h @@ -59,7 +59,6 @@ public: QString proFilePath() const; const QString remoteChannel() const; - const QString dumperLib() const; bool isEnabled() const; QString disabledReason() const; diff --git a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp index 1451813b09..9845a5477d 100644 --- a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp @@ -212,16 +212,6 @@ void CMakeRunConfiguration::setCommandLineArguments(const QString &newText) m_arguments = newText; } -QString CMakeRunConfiguration::dumperLibrary() const -{ - return QtSupport::QtKitInformation::dumperLibrary(target()->kit()); -} - -QStringList CMakeRunConfiguration::dumperLibraryLocations() const -{ - return QtSupport::QtKitInformation::dumperLibraryLocations(target()->kit()); -} - void CMakeRunConfiguration::setEnabled(bool b) { if (m_enabled == b) diff --git a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.h b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.h index 355a8ee4d1..d23c5c9fa3 100644 --- a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.h +++ b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.h @@ -70,9 +70,6 @@ public: QString title() const; - QString dumperLibrary() const; - QStringList dumperLibraryLocations() const; - QVariantMap toMap() const; void setEnabled(bool b); diff --git a/src/plugins/debugger/debugger.qbs b/src/plugins/debugger/debugger.qbs index 44a36b7588..290929db46 100644 --- a/src/plugins/debugger/debugger.qbs +++ b/src/plugins/debugger/debugger.qbs @@ -109,14 +109,12 @@ QtcPlugin { prefix: "gdb/" files: [ "attachgdbadapter.cpp", "attachgdbadapter.h", - "classicgdbengine.cpp", "coregdbadapter.cpp", "coregdbadapter.h", "gdb.qrc", "gdbengine.cpp", "gdbengine.h", "gdboptionspage.cpp", "gdboptionspage.h", "gdbprocess.cpp", "gdbprocess.h", "gdbplainengine.cpp", "gdbplainengine.h", - "pythongdbengine.cpp", "remotegdbserveradapter.cpp", "remotegdbserveradapter.h", "startgdbserverdialog.cpp", "startgdbserverdialog.h", "termgdbadapter.cpp", "termgdbadapter.h" diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 4ab37373c5..b42a5a6eaa 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -2585,10 +2585,6 @@ static QString formatStartParameters(DebuggerStartParameters &sp) } str << "Sysroot: " << sp.sysRoot << '\n'; str << "Debug Source Location: " << sp.debugSourceLocation.join(QLatin1String(":")) << '\n'; - str << "Dumper libraries: " << QDir::toNativeSeparators(sp.dumperLibrary); - foreach (const QString &dl, sp.dumperLibraryLocations) - str << ' ' << QDir::toNativeSeparators(dl); - str << '\n'; return rc; } diff --git a/src/plugins/debugger/debuggerrunner.cpp b/src/plugins/debugger/debuggerrunner.cpp index db2c5b7f5a..93a22fe8da 100644 --- a/src/plugins/debugger/debuggerrunner.cpp +++ b/src/plugins/debugger/debuggerrunner.cpp @@ -351,8 +351,6 @@ static DebuggerStartParameters localStartParameters(RunConfiguration *runConfigu sp.processArgs = rc->commandLineArguments(); sp.useTerminal = rc->runMode() == LocalApplicationRunConfiguration::Console; - sp.dumperLibrary = rc->dumperLibrary(); - sp.dumperLibraryLocations = rc->dumperLibraryLocations(); if (target) { if (const Project *project = target->project()) { @@ -396,11 +394,6 @@ static DebuggerStartParameters localStartParameters(RunConfiguration *runConfigu } sp.startMode = StartInternal; - - // FIXME: If it's not yet build this will be empty and not filled - // when rebuild as the runConfiguration is not stored and therefore - // cannot be used to retrieve the dumper location. - //qDebug() << "DUMPER: " << sp.dumperLibrary << sp.dumperLibraryLocations; sp.displayName = rc->displayName(); return sp; diff --git a/src/plugins/debugger/debuggerstartparameters.h b/src/plugins/debugger/debuggerstartparameters.h index f928fd40e3..59daa32853 100644 --- a/src/plugins/debugger/debuggerstartparameters.h +++ b/src/plugins/debugger/debuggerstartparameters.h @@ -133,9 +133,7 @@ public: bool useContinueInsteadOfRun; // if connected to a hw debugger run is not possible but continue is used QByteArray commandsAfterConnect; // additional commands to post after connection to debug target - QString dumperLibrary; QStringList solibSearchPath; - QStringList dumperLibraryLocations; DebuggerStartMode startMode; DebuggerCloseMode closeMode; diff --git a/src/plugins/debugger/dumper.pro b/src/plugins/debugger/dumper.pro deleted file mode 100644 index 80898b06b5..0000000000 --- a/src/plugins/debugger/dumper.pro +++ /dev/null @@ -1,24 +0,0 @@ -# This is a compile check for the dumpers only. Don't install the library! - -include(../../../qtcreator.pri) - -TEMPLATE = lib -TARGET = DebuggingHelper -DESTDIR = $$IDE_LIBRARY_PATH # /tmp would be better in some respect ... - -linux-* { -CONFIG -= release -CONFIG += debug -# The following line works around a linker issue with gcc 4.1.2 -QMAKE_CXXFLAGS *= -O2 -} - -true { - QT = core -} else { - DEFINES += USE_QT_GUI=1 - QT = core gui -} - -SOURCES += ../../../share/qtcreator/debugger/dumper.cpp - diff --git a/src/plugins/debugger/gdb/attachgdbadapter.cpp b/src/plugins/debugger/gdb/attachgdbadapter.cpp index 038b90c94e..b16f98ecb1 100644 --- a/src/plugins/debugger/gdb/attachgdbadapter.cpp +++ b/src/plugins/debugger/gdb/attachgdbadapter.cpp @@ -97,7 +97,7 @@ void GdbAttachEngine::handleAttach(const GdbResponse &response) break; case GdbResultError: if (response.data["msg"].data() == "ptrace: Operation not permitted.") { - notifyInferiorSetupFailed(DumperHelper::msgPtraceError(startParameters().startMode)); + notifyInferiorSetupFailed(msgPtraceError(startParameters().startMode)); break; } // if msg != "ptrace: ..." fall through diff --git a/src/plugins/debugger/gdb/attachgdbadapter.h b/src/plugins/debugger/gdb/attachgdbadapter.h index 045c238afd..8e61e69511 100644 --- a/src/plugins/debugger/gdb/attachgdbadapter.h +++ b/src/plugins/debugger/gdb/attachgdbadapter.h @@ -50,8 +50,6 @@ public: explicit GdbAttachEngine(const DebuggerStartParameters &startParameters); private: - DumperHandling dumperHandling() const { return DumperLoadedByGdb; } - void setupEngine(); void setupInferior(); void runEngine(); diff --git a/src/plugins/debugger/gdb/classicgdbengine.cpp b/src/plugins/debugger/gdb/classicgdbengine.cpp deleted file mode 100644 index 3d355dcf57..0000000000 --- a/src/plugins/debugger/gdb/classicgdbengine.cpp +++ /dev/null @@ -1,1535 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "gdbengine.h" - -#include <debugger/debuggeractions.h> -#include <debugger/debuggercore.h> -#include <debugger/debuggerprotocol.h> -#include <debugger/debuggerstartparameters.h> -#include <debugger/debuggerstringutils.h> -#include <debugger/sourceutils.h> -#include <debugger/stackhandler.h> - -#include <coreplugin/icore.h> -#include <projectexplorer/projectexplorerconstants.h> -#include <qtsupport/qtsupportconstants.h> -#include <utils/qtcassert.h> -#include <utils/savedaction.h> -#include <QFileInfo> -#include <QMessageBox> -#include <QPushButton> - -#if !defined(Q_OS_WIN) -#include <dlfcn.h> -#endif - -#include <cctype> - -#define PRECONDITION QTC_CHECK(!hasPython()) - -#define CB(callback) &GdbEngine::callback, STRINGIFY(callback) - -enum { - debugPending = 0, - debugSubItem = 0, - debug = 0 -}; - -namespace Debugger { -namespace Internal { - -// ----------------- QtDumperHelper::TypeData -DumperHelper::TypeData::TypeData() : - type(UnknownType), - isTemplate(false) -{ -} - -void DumperHelper::TypeData::clear() -{ - isTemplate = false; - type = UnknownType; - tmplate.clear(); - inner.clear(); -} - -// ----------------- QtDumperHelper -DumperHelper::DumperHelper() : - m_qtVersion(0), - m_dumperVersion(1.0) -{ - qFill(m_specialSizes, m_specialSizes + SpecialSizeCount, 0); - setQClassPrefixes(QByteArray()); -} - -void DumperHelper::clear() -{ - m_nameTypeMap.clear(); - m_qtVersion = 0; - m_dumperVersion = 1.0; - m_qtNamespace.clear(); - m_sizeCache.clear(); - qFill(m_specialSizes, m_specialSizes + SpecialSizeCount, 0); - m_expressionCache.clear(); - setQClassPrefixes(QByteArray()); -} - -QString DumperHelper::msgDumperOutdated(double requiredVersion, double currentVersion) -{ - return QCoreApplication::translate("QtDumperHelper", - "Found an outdated version of the debugging helper library (%1); " - "version %2 is required."). - arg(currentVersion).arg(requiredVersion); -} - -QString DumperHelper::msgPtraceError(DebuggerStartMode sm) -{ - if (sm == StartInternal) { - return QCoreApplication::translate("QtDumperHelper", - "ptrace: Operation not permitted.\n\n" - "Could not attach to the process. " - "Make sure no other debugger traces this process.\n" - "Check the settings of\n" - "/proc/sys/kernel/yama/ptrace_scope\n" - "For more details, see /etc/sysctl.d/10-ptrace.conf\n"); - } - return QCoreApplication::translate("QtDumperHelper", - "ptrace: Operation not permitted.\n\n" - "Could not attach to the process. " - "Make sure no other debugger traces this process.\n" - "If your uid matches the uid\n" - "of the target process, check the settings of\n" - "/proc/sys/kernel/yama/ptrace_scope\n" - "For more details, see /etc/sysctl.d/10-ptrace.conf\n"); -} - -static inline void formatQtVersion(int v, QTextStream &str) -{ - str << ((v >> 16) & 0xFF) << '.' << ((v >> 8) & 0xFF) << '.' << (v & 0xFF); -} - -QString DumperHelper::toString(bool debug) const -{ - if (debug) { - QString rc; - QTextStream str(&rc); - str << "version="; - formatQtVersion(m_qtVersion, str); - str << "dumperversion='" << m_dumperVersion << "' namespace='" << m_qtNamespace << "'," << m_nameTypeMap.size() << " known types <type enum>: "; - const NameTypeMap::const_iterator cend = m_nameTypeMap.constEnd(); - for (NameTypeMap::const_iterator it = m_nameTypeMap.constBegin(); it != cend; ++it) { - str <<",[" << it.key() << ',' << it.value() << ']'; - } - str << "\nSpecial size: "; - for (int i = 0; i < SpecialSizeCount; i++) - str << ' ' << m_specialSizes[i]; - str << "\nSize cache: "; - const SizeCache::const_iterator scend = m_sizeCache.constEnd(); - for (SizeCache::const_iterator it = m_sizeCache.constBegin(); it != scend; ++it) { - str << ' ' << it.key() << '=' << it.value() << '\n'; - } - str << "\nExpression cache: (" << m_expressionCache.size() << ")\n"; - const ExpressionCache::const_iterator excend = m_expressionCache.constEnd(); - for (ExpressionCache::const_iterator it = m_expressionCache.constBegin(); it != excend; ++it) - str << " " << it.key() << ' ' << it.value() << '\n'; - return rc; - } - const QString nameSpace = m_qtNamespace.isEmpty() - ? QCoreApplication::translate("QtDumperHelper", "<none>") : QLatin1String(m_qtNamespace); - return QCoreApplication::translate("QtDumperHelper", - "%n known types, Qt version: %1, Qt namespace: %2 Dumper version: %3", - 0, QCoreApplication::CodecForTr, - m_nameTypeMap.size()).arg(QLatin1String(qtVersionString()), nameSpace).arg(m_dumperVersion); -} - -DumperHelper::Type DumperHelper::simpleType(const QByteArray &simpleType) const -{ - return m_nameTypeMap.value(simpleType, UnknownType); -} - -int DumperHelper::qtVersion() const -{ - return m_qtVersion; -} - -QByteArray DumperHelper::qtNamespace() const -{ - return m_qtNamespace; -} - -int DumperHelper::typeCount() const -{ - return m_nameTypeMap.size(); -} - -// Look up unnamespaced 'std' types. -static DumperHelper::Type stdType(const QByteArray &type) -{ - if (type == "vector") - return DumperHelper::StdVectorType; - if (type == "deque") - return DumperHelper::StdDequeType; - if (type == "set") - return DumperHelper::StdSetType; - if (type == "stack") - return DumperHelper::StdStackType; - if (type == "map") - return DumperHelper::StdMapType; - if (type == "basic_string") - return DumperHelper::StdStringType; - return DumperHelper::UnknownType; -} - -static DumperHelper::Type specialType(QByteArray type) -{ - // Std classes. - if (type.startsWith("std::")) - return stdType(type.mid(5)); - - // Strip namespace - // FIXME: that's not a good idea as it makes all namespaces equal. - const int namespaceIndex = type.lastIndexOf("::"); - if (namespaceIndex == -1) { - // None ... check for std.. - const DumperHelper::Type sType = stdType(type); - if (sType != DumperHelper::UnknownType) - return sType; - } else { - type = type.mid(namespaceIndex + 2); - } - - if (type == "QAbstractItem") - return DumperHelper::QAbstractItemType; - if (type == "QMap") - return DumperHelper::QMapType; - if (type == "QMapNode") - return DumperHelper::QMapNodeType; - if (type == "QMultiMap") - return DumperHelper::QMultiMapType; - if (type == "QObject") - return DumperHelper::QObjectType; - if (type == "QObjectSignal") - return DumperHelper::QObjectSignalType; - if (type == "QObjectSlot") - return DumperHelper::QObjectSlotType; - if (type == "QStack") - return DumperHelper::QStackType; - if (type == "QVector") - return DumperHelper::QVectorType; - if (type == "QWidget") - return DumperHelper::QWidgetType; - return DumperHelper::UnknownType; -} - -QByteArray DumperHelper::qtVersionString() const -{ - QString rc; - QTextStream str(&rc); - formatQtVersion(m_qtVersion, str); - return rc.toLatin1(); -} - -// Parse a list of types. -typedef QList<QByteArray> QByteArrayList; - -static QByteArray qClassName(const QByteArray &qtNamespace, const char *className) -{ - if (qtNamespace.isEmpty()) - return className; - QByteArray rc = qtNamespace; - rc += "::"; - rc += className; - return rc; -} - -static double getDumperVersion(const GdbMi &contents) -{ - const GdbMi dumperVersionG = contents["dumperversion"]; - if (dumperVersionG.type() != GdbMi::Invalid) { - bool ok; - const double v = QString::fromLatin1(dumperVersionG.data()).toDouble(&ok); - if (ok) - return v; - } - return 1.0; -} - - -void DumperHelper::setQClassPrefixes(const QByteArray &qNamespace) -{ - // Prefixes with namespaces - m_qPointerPrefix = qClassName(qNamespace, "QPointer"); - m_qSharedPointerPrefix = qClassName(qNamespace, "QSharedPointer"); - m_qSharedDataPointerPrefix = qClassName(qNamespace, "QSharedDataPointer"); - m_qWeakPointerPrefix = qClassName(qNamespace, "QWeakPointer"); - m_qListPrefix = qClassName(qNamespace, "QList"); - m_qLinkedListPrefix = qClassName(qNamespace, "QLinkedList"); - m_qVectorPrefix = qClassName(qNamespace, "QVector"); - m_qQueuePrefix = qClassName(qNamespace, "QQueue"); -} - -bool DumperHelper::parseQuery(const GdbMi &contents) -{ - clear(); - if (debug > 1) - qDebug() << "parseQuery" << contents.toString(true, 2); - - // Common info, dumper version, etc - QByteArray ns = contents["namespace"].data(); - setQtNamespace(ns); - int qtv = 0; - const GdbMi qtversion = contents["qtversion"]; - if (qtversion.children().size() == 3) { - qtv = (qtversion.childAt(0).toInt() << 16) - + (qtversion.childAt(1).toInt() << 8) - + qtversion.childAt(2).toInt(); - } - m_qtVersion = qtv; - // Get list of helpers - QByteArrayList availableSimpleDebuggingHelpers; - foreach (const GdbMi &item, contents["dumpers"].children()) - availableSimpleDebuggingHelpers.append(item.data()); - - // Parse types - m_nameTypeMap.clear(); - foreach (const QByteArray &type, availableSimpleDebuggingHelpers) { - const Type t = specialType(type); - m_nameTypeMap.insert(type, t != UnknownType ? t : SupportedType); - } - - m_dumperVersion = getDumperVersion(contents); - // Parse sizes - foreach (const GdbMi &sizesList, contents["sizes"].children()) { - const int childCount = sizesList.childCount(); - if (childCount > 1) { - const int size = sizesList.childAt(0).toInt(); - for (int c = 1; c < childCount; c++) - addSize(sizesList.childAt(c).data(), size); - } - } - // Parse expressions - foreach (const GdbMi &exprList, contents["expressions"].children()) - if (exprList.childCount() == 2) - m_expressionCache.insert(exprList.childAt(0).data(), - exprList.childAt(1).data()); - return true; -} - -void DumperHelper::addSize(const QByteArray &name, int size) -{ - // Special interest cases - if (name == "char*") { - m_specialSizes[PointerSize] = size; - return; - } - const SpecialSizeType st = specialSizeType(name); - if (st != SpecialSizeCount) { - m_specialSizes[st] = size; - return; - } - do { - // CDB helpers - if (name == "std::string") { - m_sizeCache.insert("std::basic_string<char,std::char_traits<char>,std::allocator<char> >", size); - m_sizeCache.insert("basic_string<char,char_traits<char>,allocator<char> >", size); - break; - } - if (name == "std::wstring") { - m_sizeCache.insert("basic_string<unsigned short,char_traits<unsignedshort>,allocator<unsignedshort> >", size); - m_sizeCache.insert("std::basic_string<unsigned short,std::char_traits<unsigned short>,std::allocator<unsigned short> >", size); - break; - } - } while (false); - m_sizeCache.insert(name, size); -} - -DumperHelper::Type DumperHelper::type(const QByteArray &typeName) const -{ - const DumperHelper::TypeData td = typeData(typeName); - return td.type; -} - -static bool extractTemplate(const QByteArray &type, QByteArray *tmplate, QByteArray *inner) -{ - // Input "Template<Inner1,Inner2,...>::Foo" will return "Template::Foo" in - // 'tmplate' and "Inner1@Inner2@..." etc in 'inner'. Result indicates - // whether parsing was successful - // Gdb inserts a blank after each comma which we would like to avoid - tmplate->clear(); - inner->clear(); - if (!type.contains('<')) - return false; - int level = 0; - bool skipSpace = false; - const int size = type.size(); - - for (int i = 0; i != size; ++i) { - const char c = type.at(i); - switch (c) { - case '<': - *(level == 0 ? tmplate : inner) += c; - ++level; - break; - case '>': - --level; - *(level == 0 ? tmplate : inner) += c; - break; - case ',': - *inner += (level == 1) ? '@' : ','; - skipSpace = true; - break; - default: - if (!skipSpace || c != ' ') { - *(level == 0 ? tmplate : inner) += c; - skipSpace = false; - } - break; - } - } - *tmplate = tmplate->trimmed(); - tmplate->replace("<>", ""); - tmplate->replace("'", ""); // Sometimes 'std::vector' is reported, with quotes. - *inner = inner->trimmed(); - // qDebug() << "EXTRACT TEMPLATE: " << *tmplate << *inner << " FROM " << type; - return !inner->isEmpty(); -} - -DumperHelper::TypeData DumperHelper::typeData(const QByteArray &typeName) const -{ - TypeData td; - td.type = UnknownType; - const Type st = simpleType(typeName); - if (st != UnknownType) { - td.isTemplate = false; - td.type = st; - return td; - } - // Try template - td.isTemplate = extractTemplate(typeName, &td.tmplate, &td.inner); - if (!td.isTemplate) - return td; - // Check the template type QMap<X,Y> -> 'QMap' - td.type = simpleType(td.tmplate); - return td; -} - -static QByteArray sizeofTypeExpression(const QByteArray &type) -{ - if (type.endsWith('*')) - return "sizeof(void*)"; - if (type.endsWith('>')) - return "sizeof(" + type + ')'; - return "sizeof(" + gdbQuoteTypes(type) + ')'; -} - -// Format an expression to have the debugger query the -// size. Use size cache if possible -QByteArray DumperHelper::evaluationSizeofTypeExpression(const QByteArray &typeName) const -{ - // Look up special size types - const SpecialSizeType st = specialSizeType(typeName); - if (st != SpecialSizeCount) { - if (const int size = m_specialSizes[st]) - return QByteArray::number(size); - } - // Look up size cache - const SizeCache::const_iterator sit = m_sizeCache.constFind(typeName); - if (sit != m_sizeCache.constEnd()) - return QByteArray::number(sit.value()); - // Finally have the debugger evaluate - return sizeofTypeExpression(typeName); -} - -DumperHelper::SpecialSizeType DumperHelper::specialSizeType(const QByteArray &typeName) const -{ - if (isPointerType(typeName)) - return PointerSize; - if (typeName == "int") - return IntSize; - if (typeName.startsWith("std::allocator")) - return StdAllocatorSize; - if (typeName.startsWith(m_qPointerPrefix)) - return QPointerSize; - if (typeName.startsWith(m_qSharedPointerPrefix)) - return QSharedPointerSize; - if (typeName.startsWith(m_qSharedDataPointerPrefix)) - return QSharedDataPointerSize; - if (typeName.startsWith(m_qWeakPointerPrefix)) - return QWeakPointerSize; - if (typeName.startsWith(m_qListPrefix)) - return QListSize; - if (typeName.startsWith(m_qLinkedListPrefix)) - return QLinkedListSize; - if (typeName.startsWith(m_qVectorPrefix)) - return QVectorSize; - if (typeName.startsWith(m_qQueuePrefix)) - return QQueueSize; - return SpecialSizeCount; -} - -static inline bool isInteger(const QByteArray &n) -{ - const int size = n.size(); - if (!size) - return false; - for (int i = 0; i < size; i++) - if (!std::isdigit(n.at(i))) - return false; - return true; -} - -// Return debugger expression to get the offset of a map node. -static inline QByteArray qMapNodeValueOffsetExpression(const QByteArray &type) -{ - return "(size_t)&(('" + type + "'*)0)->value"; -} - -void DumperHelper::evaluationParameters(const WatchData &data, - const TypeData &td, QByteArray *inBuffer, QByteArrayList *extraArgsIn) const -{ - enum { maxExtraArgCount = 4 }; - - QByteArrayList &extraArgs = *extraArgsIn; - - // See extractTemplate for parameters - QByteArrayList inners = td.inner.split('@'); - if (inners.at(0).isEmpty()) - inners.clear(); - for (int i = 0; i != inners.size(); ++i) - inners[i] = inners[i].simplified(); - - QByteArray outertype = td.isTemplate ? td.tmplate : data.type; - // adjust the data extract - if (outertype == m_qtNamespace + "QWidget") - outertype = m_qtNamespace + "QObject"; - - QByteArray inner = td.inner; - const QByteArray zero = "0"; - - extraArgs.clear(); - - if (!inners.empty()) { - // "generic" template dumpers: passing sizeof(argument) - // gives already most information the dumpers need - const int count = qMin(int(maxExtraArgCount), inners.size()); - for (int i = 0; i < count; i++) - extraArgs.push_back(evaluationSizeofTypeExpression(inners.at(i))); - } - - // Pad with zeros - while (extraArgs.size() < maxExtraArgCount) - extraArgs.push_back("0"); - - // in rare cases we need more or less: - switch (td.type) { - case QAbstractItemType: - if (data.dumperFlags.isEmpty()) - qWarning("Internal error: empty dumper state '%s'.", data.iname.constData()); - else - inner = data.dumperFlags.mid(1); - break; - case QObjectSlotType: - case QObjectSignalType: { - // we need the number out of something like - // iname="local.ob.slots.2" // ".deleteLater()"? - const int pos = data.iname.lastIndexOf('.'); - const QByteArray slotNumber = data.iname.mid(pos + 1); - QTC_CHECK(slotNumber.toInt() != -1); - extraArgs[0] = slotNumber; - } - break; - case QMapType: - case QMultiMapType: { - QByteArray nodetype; - if (m_qtVersion >= 0x040500) { - nodetype = m_qtNamespace + "QMapNode"; - nodetype += data.type.mid(outertype.size()); - } else { - // FIXME: doesn't work for QMultiMap - nodetype = data.type + "::Node"; - } - //qDebug() << "OUTERTYPE: " << outertype << " NODETYPE: " << nodetype - // << "QT VERSION" << m_qtVersion << ((4 << 16) + (5 << 8) + 0); - extraArgs[2] = evaluationSizeofTypeExpression(nodetype); - extraArgs[3] = qMapNodeValueOffsetExpression(nodetype); - } - break; - case QMapNodeType: - extraArgs[2] = evaluationSizeofTypeExpression(data.type); - extraArgs[3] = qMapNodeValueOffsetExpression(data.type); - break; - case StdVectorType: - //qDebug() << "EXTRACT TEMPLATE: " << outertype << inners; - if (inners.at(0) == "bool") - outertype = "std::vector::bool"; - break; - case StdDequeType: - extraArgs[1] = "0"; - break; - case StdStackType: - // remove 'std::allocator<...>': - extraArgs[1] = "0"; - break; - case StdSetType: - // remove 'std::less<...>': - extraArgs[1] = "0"; - // remove 'std::allocator<...>': - extraArgs[2] = "0"; - break; - case StdMapType: { - // We need the offset of the second item in the value pair. - // We read the type of the pair from the allocator argument because - // that gets the constness "right" (in the sense that gdb/cdb can - // read it back: "std::allocator<std::pair<Key,Value> >" - // -> "std::pair<Key,Value>". Different debuggers have varying - // amounts of terminating blanks... - extraArgs[2].clear(); - extraArgs[3] = "0"; - QByteArray pairType = inners.at(3); - int bracketPos = pairType.indexOf('<'); - if (bracketPos != -1) - pairType.remove(0, bracketPos + 1); - // We don't want the comparator and the allocator confuse gdb. - const char closingBracket = '>'; - bracketPos = pairType.lastIndexOf(closingBracket); - if (bracketPos != -1) - bracketPos = pairType.lastIndexOf(closingBracket, bracketPos - pairType.size() - 1); - if (bracketPos != -1) - pairType.truncate(bracketPos + 1); - extraArgs[2] = "(size_t)&(('"; - extraArgs[2] += pairType; - extraArgs[2] += "'*)0)->second"; - } - break; - case StdStringType: - //qDebug() << "EXTRACT TEMPLATE: " << outertype << inners; - if (inners.at(0) == "char") - outertype = "std::string"; - else if (inners.at(0) == "wchar_t") - outertype = "std::wstring"; - qFill(extraArgs, zero); - break; - case UnknownType: - qWarning("Unknown type encountered in %s.\n", Q_FUNC_INFO); - break; - case SupportedType: - case QVectorType: - case QStackType: - case QObjectType: - case QWidgetType: - break; - } - - // Look up expressions in the cache - if (!m_expressionCache.empty()) { - const ExpressionCache::const_iterator excCend = m_expressionCache.constEnd(); - const QByteArrayList::iterator eend = extraArgs.end(); - for (QByteArrayList::iterator it = extraArgs.begin(); it != eend; ++it) { - QByteArray &e = *it; - if (!e.isEmpty() && e != zero && !isInteger(e)) { - const ExpressionCache::const_iterator eit = m_expressionCache.constFind(e); - if (eit != excCend) - e = eit.value(); - } - } - } - - inBuffer->clear(); - inBuffer->append(outertype); - inBuffer->append('\0'); - inBuffer->append(data.iname); - inBuffer->append('\0'); - inBuffer->append(data.exp); - inBuffer->append('\0'); - inBuffer->append(inner); - inBuffer->append('\0'); - inBuffer->append(data.iname); - inBuffer->append('\0'); - - if (debug) - qDebug() << '\n' << Q_FUNC_INFO << '\n' << data.toString() << "\n-->" << outertype << td.type << extraArgs; -} - -QDebug operator<<(QDebug in, const DumperHelper::TypeData &d) -{ - QDebug nsp = in.nospace(); - nsp << " type=" << d.type << " tpl=" << d.isTemplate; - if (d.isTemplate) - nsp << d.tmplate << '<' << d.inner << '>'; - return in; -} - -static bool isAccessSpecifier(const QByteArray &ba) -{ - return ba == "private" || ba == "protected" || ba == "public"; -} - -// reads a MI-encoded item frome the consolestream -static bool parseConsoleStream(const GdbResponse &response, GdbMi *contents) -{ - QByteArray out = response.consoleStreamOutput; - - int markerPos = out.indexOf('"') + 1; // position of 'success marker' - if (markerPos == 0 || out.at(markerPos) == 'f') { // 't' or 'f' - // custom dumper produced no output - return false; - } - - out = out.mid(markerPos + 1); - out = out.left(out.lastIndexOf('"')); - // optimization: dumper output never needs real C unquoting - out.replace('\\', ""); - - contents->fromStringMultiple(out); - //qDebug() << "CONTENTS" << contents->toString(true); - return contents->isValid(); -} - -void GdbEngine::updateLocalsClassic() -{ - PRECONDITION; - //m_pendingWatchRequests = 0; - m_pendingBreakpointRequests = 0; - m_processedNames.clear(); - - QByteArray level = QByteArray::number(currentFrame()); - // '2' is 'list with type and value' - QByteArray cmd = "-stack-list-arguments 2 " + level + ' ' + level; - postCommand(cmd, Discardable, - CB(handleStackListArgumentsClassic)); - // '2' is 'list with type and value' - postCommand("-stack-list-locals 2", Discardable, - CB(handleStackListLocalsClassic)); // stage 2/2 -} - -static inline QString msgRetrievingWatchData(int pending) -{ - return GdbEngine::tr("Retrieving data for watch view (%n requests pending)...", 0, pending); -} - -void GdbEngine::runDirectDebuggingHelperClassic(const WatchData &data, bool dumpChildren) -{ - Q_UNUSED(dumpChildren) - QByteArray type = data.type; - QByteArray cmd; - - if (type == "QString" || type.endsWith("::QString")) - cmd = "qdumpqstring (&(" + data.exp + "))"; - else if (type == "QStringList" || type.endsWith("::QStringList")) - cmd = "qdumpqstringlist (&(" + data.exp + "))"; - - QVariant var; - var.setValue(data); - postCommand(cmd, Discardable, CB(handleDebuggingHelperValue3Classic), var); - - showStatusMessage(msgRetrievingWatchData(m_uncompleted.size()), 10000); -} - -void GdbEngine::runDebuggingHelperClassic(const WatchData &data0, bool dumpChildren) -{ - PRECONDITION; - if (m_debuggingHelperState != DebuggingHelperAvailable) { - runDirectDebuggingHelperClassic(data0, dumpChildren); - return; - } - WatchData data = data0; - - // Avoid endless loops created by faulty dumpers. - QByteArray processedName = QByteArray::number(dumpChildren) + '-' + data.iname; - if (m_processedNames.contains(processedName)) { - showMessage( - _("<Breaking endless loop for " + data.iname + '>'), LogMiscInput); - data.setAllUnneeded(); - data.setValue(_("<unavailable>")); - data.setHasChildren(false); - insertData(data); - return; - } - m_processedNames.insert(processedName); - - QByteArray params; - QList<QByteArray> extraArgs; - const DumperHelper::TypeData td = m_dumperHelper.typeData(data0.type); - m_dumperHelper.evaluationParameters(data, td, ¶ms, &extraArgs); - - //int protocol = (data.iname.startsWith("watch") && data.type == "QImage") ? 3 : 2; - //int protocol = data.iname.startsWith("watch") ? 3 : 2; - const int protocol = 2; - //int protocol = isDisplayedIName(data.iname) ? 3 : 2; - - QByteArray addr; - if (data.address) - addr = "(void*)" + data.hexAddress(); - else if (data.exp.isEmpty()) // happens e.g. for QAbstractItem - addr = QByteArray(1, '0'); - else - addr = "&(" + data.exp + ')'; - - sendWatchParameters(params); - - QByteArray cmd = "call (void*)qDumpObjectData440(" - + QByteArray::number(protocol) - + ",0," - + addr - + ',' - + (dumpChildren ? '1' : '0'); - foreach (const QByteArray &ex, extraArgs) - cmd += ',' + ex; - cmd += ')'; - - postCommand(cmd, Discardable | NonCriticalResponse); - - showStatusMessage(msgRetrievingWatchData(m_uncompleted.size()), 10000); - - // retrieve response - postCommand("p (char*)&qDumpOutBuffer", Discardable, - CB(handleDebuggingHelperValue2Classic), qVariantFromValue(data)); -} - -void GdbEngine::createGdbVariableClassic(const WatchData &data) -{ - PRECONDITION; - postCommand("-var-delete \"" + data.iname + '"', Discardable); - QByteArray exp = data.exp; - if (exp.isEmpty() && data.address) - exp = "*(" + gdbQuoteTypes(data.type) + "*)" + data.hexAddress(); - QVariant val = QVariant::fromValue<WatchData>(data); - postCommand("-var-create \"" + data.iname + "\" * \"" + exp + '"', - Discardable, CB(handleVarCreate), val); -} - -void GdbEngine::updateSubItemClassic(const WatchData &data0) -{ - PRECONDITION; - WatchData data = data0; - if (debugSubItem) - qDebug() << "UPDATE SUBITEM:" << data.toString(); - QTC_ASSERT(data.isValid(), return); - - // in any case we need the type first - if (data.isTypeNeeded()) { - // This should only happen if we don't have a variable yet. - // Let's play safe, though. - if (!data.variable.isEmpty()) { - // Update: It does so for out-of-scope watchers. -# if 1 - qDebug() << "FIXME: GdbEngine::updateSubItem:" - << data.toString() << "should not happen"; -# else - data.setType(WatchData::msgNotInScope()); - data.setValue(WatchData::msgNotInScope()); - data.setHasChildren(false); - insertData(data); - return; -# endif - } - // The WatchVarCreate handler will receive type information - // and re-insert a WatchData item with correct type, so - // we will not re-enter this bit. - // FIXME: Concurrency issues? - createGdbVariableClassic(data); - return; - } - - // We should have a type now. This is relied upon further below. - QTC_ASSERT(!data.type.isEmpty(), return); - - // A common case that can be easily solved. - if (data.isChildrenNeeded() && isPointerType(data.type) - && !hasDebuggingHelperForType(data.type)) { - // We sometimes know what kind of children pointers have. - if (debugSubItem) - qDebug() << "IT'S A POINTER"; - - if (debuggerCore()->boolSetting(AutoDerefPointers)) { - // Try automatic dereferentiation - data.exp = "(*(" + data.exp + "))"; - data.type = data.type + '.'; // FIXME: fragile HACK to avoid recursion - if (data.value.startsWith(QLatin1String("0x"))) - data.value.insert(0, QLatin1Char('@')); - insertData(data); - } else { - data.setChildrenUnneeded(); - insertData(data); - WatchData data1; - data1.iname = data.iname + ".*"; - data1.name = QLatin1Char('*') + data.name; - data1.exp = "(*(" + data.exp + "))"; - data1.type = stripPointerType(data.type); - data1.setValueNeeded(); - data1.setChildrenUnneeded(); - insertData(data1); - } - return; - } - - if (data.isValueNeeded() && hasDebuggingHelperForType(data.type)) { - if (debugSubItem) - qDebug() << "UPDATE SUBITEM: CUSTOMVALUE"; - runDebuggingHelperClassic(data, - watchHandler()->isExpandedIName(data.iname)); - return; - } - -/* - if (data.isValueNeeded() && data.exp.isEmpty()) { - if (debugSubItem) - qDebug() << "UPDATE SUBITEM: NO EXPRESSION?"; - data.setError("<no expression given>"); - insertData(data); - return; - } -*/ - - if (data.isValueNeeded() && data.variable.isEmpty()) { - if (debugSubItem) - qDebug() << "UPDATE SUBITEM: VARIABLE NEEDED FOR VALUE"; - createGdbVariableClassic(data); - // the WatchVarCreate handler will re-insert a WatchData - // item, with valueNeeded() set. - return; - } - - if (data.isValueNeeded()) { - QTC_ASSERT(!data.variable.isEmpty(), return); // tested above - if (debugSubItem) - qDebug() << "UPDATE SUBITEM: VALUE"; - QByteArray cmd = "-var-evaluate-expression \"" + data.iname + '"'; - postCommand(cmd, Discardable, - CB(handleEvaluateExpressionClassic), QVariant::fromValue(data)); - return; - } - - if (data.isChildrenNeeded() && hasDebuggingHelperForType(data.type)) { - if (debugSubItem) - qDebug() << "UPDATE SUBITEM: CUSTOMVALUE WITH CHILDREN"; - runDebuggingHelperClassic(data, true); - return; - } - - if (data.isChildrenNeeded() && data.variable.isEmpty()) { - if (debugSubItem) - qDebug() << "UPDATE SUBITEM: VARIABLE NEEDED FOR CHILDREN"; - createGdbVariableClassic(data); - // the WatchVarCreate handler will re-insert a WatchData - // item, with childrenNeeded() set. - return; - } - - if (data.isChildrenNeeded()) { - QTC_ASSERT(!data.variable.isEmpty(), return); // tested above - QByteArray cmd = "-var-list-children --all-values \"" + data.variable + '"'; - postCommand(cmd, Discardable, - CB(handleVarListChildrenClassic), QVariant::fromValue(data)); - return; - } - - if (data.isHasChildrenNeeded() && hasDebuggingHelperForType(data.type)) { - if (debugSubItem) - qDebug() << "UPDATE SUBITEM: CUSTOMVALUE WITH CHILDREN"; - runDebuggingHelperClassic(data, watchHandler()->isExpandedIName(data.iname)); - return; - } - -//#if !X - if (data.isHasChildrenNeeded() && data.variable.isEmpty()) { - if (debugSubItem) - qDebug() << "UPDATE SUBITEM: VARIABLE NEEDED FOR CHILDCOUNT"; - createGdbVariableClassic(data); - // the WatchVarCreate handler will re-insert a WatchData - // item, with childrenNeeded() set. - return; - } -//#endif - - if (data.isHasChildrenNeeded()) { - QTC_ASSERT(!data.variable.isEmpty(), return); // tested above - QByteArray cmd = "-var-list-children --all-values \"" + data.variable + '"'; - postCommand(cmd, Discardable, - CB(handleVarListChildrenClassic), QVariant::fromValue(data)); - return; - } - - qDebug() << "FIXME: UPDATE SUBITEM:" << data.toString(); - QTC_ASSERT(false, return); -} - -void GdbEngine::handleDebuggingHelperValue2Classic(const GdbResponse &response) -{ - PRECONDITION; - WatchData data = response.cookie.value<WatchData>(); - QTC_ASSERT(data.isValid(), return); - - // The real dumper might have aborted without giving any answers. - // Remove traces of the question, too. - if (m_cookieForToken.contains(response.token - 1)) { - m_cookieForToken.remove(response.token - 1); - showMessage(_("DETECTING LOST COMMAND %1").arg(response.token - 1)); - // --m_pendingWatchRequests; - data.setError(WatchData::msgNotInScope()); - insertData(data); - return; - } - - //qDebug() << "CUSTOM VALUE RESULT:" << response.toString(); - //qDebug() << "FOR DATA:" << data.toString() << response.resultClass; - if (response.resultClass != GdbResultDone) { - qDebug() << "STRANGE CUSTOM DUMPER RESULT DATA:" << data.toString(); - return; - } - - GdbMi contents; - if (!parseConsoleStream(response, &contents)) { - data.setError(WatchData::msgNotInScope()); - insertData(data); - return; - } - - data.updateType(response.data["type"]); - data.updateDisplayedType(response.data["displaytype"]); - QList<WatchData> list; - parseWatchData(watchHandler()->expandedINames(), data, contents, &list); - //for (int i = 0; i != list.size(); ++i) - // qDebug() << "READ: " << list.at(i).toString(); - foreach (const WatchData &data, list) - insertData(data); -} - -void GdbEngine::handleDebuggingHelperValue3Classic(const GdbResponse &response) -{ - if (response.resultClass == GdbResultDone) { - WatchData data = response.cookie.value<WatchData>(); - QByteArray out = response.consoleStreamOutput; - while (out.endsWith(' ') || out.endsWith('\n')) - out.chop(1); - QList<QByteArray> list = out.split(' '); - if (list.isEmpty()) { - data.setError(WatchData::msgNotInScope()); - data.setAllUnneeded(); - insertData(data); - } else if (data.type == "QString" - || data.type.endsWith("::QString")) { - QList<QByteArray> list = out.split(' '); - QString str; - int l = out.isEmpty() ? 0 : list.size(); - for (int i = 0; i < l; ++i) - str.append(list.at(i).toInt()); - data.setValue(QLatin1Char('"') + str + QLatin1Char('"')); - data.setHasChildren(false); - data.setAllUnneeded(); - insertData(data); - } else if (data.type == "QStringList" - || data.type.endsWith("::QStringList")) { - if (out.isEmpty()) { - data.setValue(tr("<0 items>")); - data.setHasChildren(false); - data.setAllUnneeded(); - insertData(data); - } else { - int l = list.size(); - //: In string list - data.setValue(tr("<%n items>", 0, l)); - data.setHasChildren(!list.empty()); - data.setAllUnneeded(); - insertData(data); - for (int i = 0; i < l; ++i) { - WatchData data1; - data1.name = _("[%1]").arg(i); - data1.type = data.type.left(data.type.size() - 4); - data1.iname = data.iname + '.' + QByteArray::number(i); - const QByteArray &addressSpec = list.at(i); - if (addressSpec.startsWith("0x")) - data.setHexAddress(addressSpec); - else - data.dumperFlags = addressSpec; // Item model dumpers pull tricks - data1.exp = "((" + gdbQuoteTypes(data1.type) + "*)" + addressSpec + ')'; - data1.setHasChildren(false); - data1.setValueNeeded(); - QByteArray cmd = "qdumpqstring (" + data1.exp + ')'; - QVariant var; - var.setValue(data1); - postCommand(cmd, Discardable, - CB(handleDebuggingHelperValue3Classic), var); - } - } - } else { - data.setError(WatchData::msgNotInScope()); - data.setAllUnneeded(); - insertData(data); - } - } else { - WatchData data = response.cookie.value<WatchData>(); - data.setError(WatchData::msgNotInScope()); - data.setAllUnneeded(); - insertData(data); - } -} - -void GdbEngine::tryLoadDebuggingHelpersClassic() -{ - if (m_forceAsyncModel) - return; - - PRECONDITION; - if (dumperHandling() == GdbEngine::DumperNotAvailable) { - // Load at least gdb macro based dumpers. - m_debuggingHelperState = DebuggingHelperLoadTried; - postCommand(Utils::FileReader::fetchQrc(_(":/gdb/gdbmacros.txt"))); - return; - } - - if (debugPending) - qDebug() << "TRY LOAD CUSTOM DUMPERS"; - m_debuggingHelperState = DebuggingHelperUnavailable; - if (!checkDebuggingHelpersClassic()) - return; - - m_debuggingHelperState = DebuggingHelperLoadTried; - - // Do not use STRINGIFY for RTLD_NOW as we really want to expand that to a number. -#if defined(Q_OS_WIN) - // We are using Python on Windows. - QTC_CHECK(false); -#elif defined(Q_OS_MAC) - QByteArray dlopenLib = startParameters().dumperLibrary.toLocal8Bit(); - //postCommand("sharedlibrary libc"); // for malloc - //postCommand("sharedlibrary libdl"); // for dlopen - const QByteArray flag = QByteArray::number(RTLD_NOW); - postCommand("call (void)dlopen(\"" + GdbMi::escapeCString(dlopenLib) - + "\", " + flag + ")", - CB(handleDebuggingHelperSetup)); - //postCommand("sharedlibrary " + dotEscape(dlopenLib)); -#else - QByteArray dlopenLib = startParameters().dumperLibrary.toLocal8Bit(); - //postCommand("p dlopen"); - const QByteArray flag = QByteArray::number(RTLD_NOW); - postCommand("sharedlibrary libc"); // for malloc - postCommand("sharedlibrary libdl"); // for dlopen - postCommand("call (void*)dlopen(\"" + GdbMi::escapeCString(dlopenLib) - + "\", " + flag + ")", - CB(handleDebuggingHelperSetup)); - // Some older systems like CentOS 4.6 prefer this: - postCommand("call (void*)__dlopen(\"" + GdbMi::escapeCString(dlopenLib) - + "\", " + flag + ")", - CB(handleDebuggingHelperSetup)); - postCommand("sharedlibrary " + dotEscape(dlopenLib)); -#endif - - // Retrieve list of dumpable classes. - postCommand("call (void*)qDumpObjectData440(1,0,0,0,0,0,0,0)"); - postCommand("p (char*)&qDumpOutBuffer", CB(handleQueryDebuggingHelperClassic)); -} - -// Called from CoreAdapter and AttachAdapter -void GdbEngine::updateAllClassic() -{ - PRECONDITION; - if (debugPending) - qDebug() << "UPDATING ALL\n"; - QTC_ASSERT(state() == InferiorUnrunnable || state() == InferiorStopOk, - qDebug() << state()); - tryLoadDebuggingHelpersClassic(); - reloadModulesInternal(); - postCommand("-stack-list-frames", Discardable, - CB(handleStackListFrames), - QVariant::fromValue<StackCookie>(StackCookie(false, true))); - stackHandler()->setCurrentIndex(0); - if (supportsThreads()) - postCommand("-thread-list-ids", Discardable, CB(handleThreadListIds), 0); - reloadRegisters(); - updateLocals(); -} - -void GdbEngine::setDebuggingHelperStateClassic(DebuggingHelperState s) -{ - PRECONDITION; - m_debuggingHelperState = s; -} - -void GdbEngine::handleStackListArgumentsClassic(const GdbResponse &response) -{ - PRECONDITION; - // stage 1/2 - - // Linux: - // 12^done,stack-args= - // [frame={level="0",args=[ - // {name="argc",type="int",value="1"}, - // {name="argv",type="char **",value="(char **) 0x7..."}]}] - // Mac: - // 78^done,stack-args= - // {frame={level="0",args={ - // varobj= - // {exp="this",value="0x38a2fab0",name="var21",numchild="3", - // type="CurrentDocumentFind * const",typecode="PTR", - // dynamic_type="",in_scope="true",block_start_addr="0x3938e946", - // block_end_addr="0x3938eb2d"}, - // varobj= - // {exp="before",value="@0xbfffb9f8: {d = 0x3a7f2a70}", - // name="var22",numchild="1",type="const QString ...} }}} - // - // In both cases, iterating over the children of stack-args/frame/args - // is ok. - m_currentFunctionArgs.clear(); - if (response.resultClass == GdbResultDone) { - const GdbMi list = response.data["stack-args"]; - const GdbMi frame = list["frame"]; - const GdbMi args = frame["args"]; - m_currentFunctionArgs = args.children(); - } else { - // Seems to occur on "RedHat 4 based Linux" gdb 7.0.1: - // ^error,msg="Cannot access memory at address 0x0" - showMessage(_("UNEXPECTED RESPONSE: ") + QLatin1String(response.toString())); - } -} - -void GdbEngine::handleStackListLocalsClassic(const GdbResponse &response) -{ - PRECONDITION; - // stage 2/2 - - // There could be shadowed variables - QList<GdbMi> locals = response.data["locals"].children(); - locals += m_currentFunctionArgs; - QMap<QByteArray, int> seen; - // If desired, retrieve list of uninitialized variables looking at - // the current frame. This is invoked first time after a stop from - // handleStop1, which passes on the frame as cookie. The whole stack - // is not known at this point. - QStringList uninitializedVariables; - if (debuggerCore()->action(UseCodeModel)->isChecked()) { - const StackFrame frame = - response.cookie.canConvert<Debugger::Internal::StackFrame>() - ? qvariant_cast<Debugger::Internal::StackFrame>(response.cookie) - : stackHandler()->currentFrame(); - if (frame.isUsable()) - getUninitializedVariables(debuggerCore()->cppCodeModelSnapshot(), - frame.function, frame.file, frame.line, - &uninitializedVariables); - } - WatchHandler *handler = watchHandler(); - insertData(*handler->findData("local")); - - foreach (const GdbMi &item, locals) { - const WatchData data = localVariable(item, uninitializedVariables, &seen); - if (data.isValid()) - insertData(data); - } - - if (!m_resultVarName.isEmpty()) { - WatchData rd; - rd.iname = "return.0"; - rd.name = QLatin1String("return"); - rd.exp = m_resultVarName; - insertData(rd); - } - - handler->updateWatchers(); -} - -static void showQtDumperLibraryWarning(const QString &details) -{ - QMessageBox dialog(Core::ICore::mainWindow()); - QPushButton *qtPref = dialog.addButton(DebuggerCore::tr("Open Qt Options"), - QMessageBox::ActionRole); - QPushButton *helperOff = dialog.addButton(DebuggerCore::tr("Turn off Helper Usage"), - QMessageBox::ActionRole); - QPushButton *justContinue = dialog.addButton(DebuggerCore::tr("Continue Anyway"), - QMessageBox::AcceptRole); - dialog.setDefaultButton(justContinue); - dialog.setWindowTitle(DebuggerCore::tr("Debugging Helper Missing")); - dialog.setText(DebuggerCore::tr("The debugger could not load the debugging helper library.")); - dialog.setInformativeText(DebuggerCore::tr( - "The debugging helper is used to nicely format the values of some Qt " - "and Standard Library data types. " - "It must be compiled for each used Qt version separately. " - "In the Qt Creator Build and Run preferences page, select a Qt version, " - "expand the Details section and click Build All.")); - if (!details.isEmpty()) - dialog.setDetailedText(details); -#if defined(Q_OS_MAC) && QT_VERSION >= 0x050000 - dialog.setWindowModality(Qt::WindowModal); -#endif - dialog.exec(); - if (dialog.clickedButton() == qtPref) { - Core::ICore::showOptionsDialog( - ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_CATEGORY, - QtSupport::Constants::QTVERSION_SETTINGS_PAGE_ID); - } else if (dialog.clickedButton() == helperOff) { - debuggerCore()->action(UseDebuggingHelpers)->setValue(qVariantFromValue(false), false); - } -} - -bool GdbEngine::checkDebuggingHelpersClassic() -{ - PRECONDITION; - if (!debuggerCore()->boolSetting(UseDebuggingHelpers)) - return false; - const QString lib = startParameters().dumperLibrary; - if (QFileInfo(lib).exists()) - return true; - const QStringList &locations = startParameters().dumperLibraryLocations; - const QString loc = locations.join(QLatin1String(", ")); - const QString msg = tr("The debugging helper library was not found at %1.") - .arg(loc); - showMessage(msg); - // This can happen for remote debugging. - if (!locations.isEmpty()) - showQtDumperLibraryWarning(msg); // This might build the library. - return QFileInfo(lib).exists(); -} - -void GdbEngine::handleQueryDebuggingHelperClassic(const GdbResponse &response) -{ - const double dumperVersionRequired = 1.0; - //qDebug() << "DATA DUMPER TRIAL:" << response.toString(); - - GdbMi contents; - QTC_ASSERT(parseConsoleStream(response, &contents), qDebug() << response.toString()); - const bool ok = m_dumperHelper.parseQuery(contents) - && m_dumperHelper.typeCount(); - if (ok) { - // Get version and sizes from dumpers. Expression cache - // currently causes errors. - const double dumperVersion = getDumperVersion(contents); - if (dumperVersion < dumperVersionRequired) { - showQtDumperLibraryWarning( - DumperHelper::msgDumperOutdated(dumperVersionRequired, dumperVersion)); - m_debuggingHelperState = DebuggingHelperUnavailable; - return; - } - m_debuggingHelperState = DebuggingHelperAvailable; - const QString successMsg = tr("Dumper version %1, %n custom dumpers found.", - 0, m_dumperHelper.typeCount()).arg(dumperVersion); - showStatusMessage(successMsg); - - // Sanity check for Qt version of dumpers and debuggee. - QByteArray ns = m_dumperHelper.qtNamespace(); - postCommand("-var-create A@ * '" + ns + "qVersion'()", - CB(handleDebuggingHelperVersionCheckClassic)); - postCommand("-var-delete A@"); - } else { - // Retry if thread has not terminated yet. - m_debuggingHelperState = DebuggingHelperUnavailable; - showStatusMessage(tr("Debugging helpers not found.")); - } - //qDebug() << m_dumperHelper.toString(true); - //qDebug() << m_availableSimpleDebuggingHelpers << "DATA DUMPERS AVAILABLE"; -} - -void GdbEngine::handleDebuggingHelperVersionCheckClassic(const GdbResponse &response) -{ - if (response.resultClass == GdbResultDone) { - QString value = _(response.data["value"].data()); - QString debuggeeQtVersion = value.section(QLatin1Char('"'), 1, 1); - QString dumperQtVersion = QLatin1String(m_dumperHelper.qtVersionString()); - if (debuggeeQtVersion.isEmpty()) { - showMessage(_("DUMPER VERSION CHECK SKIPPED, NO qVersion() OUTPUT IN") - + QLatin1String(response.toString())); - } else if (dumperQtVersion.isEmpty()) { - showMessage(_("DUMPER VERSION CHECK SKIPPED, NO VERSION STRING")); - } else if (dumperQtVersion != debuggeeQtVersion) { - showMessageBox(QMessageBox::Warning, - tr("Debugging helpers: Qt version mismatch"), - tr("The Qt version used to build the debugging helpers (%1) " - "does not match the Qt version used to build the debugged " - "application (%2).\nThis might yield incorrect results.") - .arg(dumperQtVersion).arg(debuggeeQtVersion)); - } else { - showMessage(_("DUMPER VERSION CHECK SUCCESSFUL: ") - + dumperQtVersion); - } - } else { - showMessage(QLatin1String("DUMPER VERSION CHECK NOT COMPLETED")); - } -} - -void GdbEngine::handleVarListChildrenHelperClassic(const GdbMi &item, - const WatchData &parent, int sortId) -{ - //qDebug() << "VAR_LIST_CHILDREN: PARENT" << parent.toString(); - //qDebug() << "VAR_LIST_CHILDREN: ITEM" << item.toString(); - QByteArray exp = item["exp"].data(); - QByteArray name = item["name"].data(); - if (isAccessSpecifier(exp)) { - // Suppress 'private'/'protected'/'public' level. - WatchData data; - data.variable = name; - data.iname = parent.iname; - //data.iname = data.variable; - data.exp = parent.exp; - data.setTypeUnneeded(); - data.setValueUnneeded(); - data.setHasChildrenUnneeded(); - data.setChildrenUnneeded(); - QByteArray cmd = "-var-list-children --all-values \"" + data.variable + '"'; - //iname += '.' + exp; - postCommand(cmd, Discardable, - CB(handleVarListChildrenClassic), QVariant::fromValue(data)); - } else if (!startsWithDigit(QLatin1String(exp)) - && item["numchild"].data() == "0") { - // Happens for structs without data, e.g. interfaces. - WatchData data; - data.name = _(exp); - data.iname = parent.iname + '.' + data.name.toLatin1(); - data.variable = name; - data.updateType(item["type"]); - data.updateValue(item); - data.updateAddress(item["addr"]); - data.setHasChildren(false); - insertData(data); - } else if (parent.iname.endsWith('.')) { - // Happens with anonymous unions. - WatchData data; - data.iname = name; - QByteArray cmd = "-var-list-children --all-values \"" + data.variable + '"'; - postCommand(cmd, Discardable, - CB(handleVarListChildrenClassic), QVariant::fromValue(data)); - } else if (exp == "staticMetaObject") { - // && item.findChild("type").data() == "const QMetaObject") - // FIXME: Namespaces? - // { do nothing } FIXME: make configurable? - // special "clever" hack to avoid clutter in the GUI. - // I am not sure this is a good idea... - } else { - // Suppress 'private'/'protected'/'public' level. - WatchData data; - data.iname = parent.iname + '.' + exp; - data.variable = name; - data.sortId = sortId; - data.updateType(item["type"]); - data.updateValue(item); - data.updateAddress(item["addr"]); - data.updateChildCount(item["numchild"]); - if (!watchHandler()->isExpandedIName(data.iname)) - data.setChildrenUnneeded(); - - data.name = _(exp); - if (data.name == QLatin1String(data.type)) { - if (isPointerType(parent.type)) { - data.exp = "*(" + parent.exp + ')'; - data.name = _("*") + parent.name; - } else { - // A type we derive from? gdb crashes when creating variables here - data.exp = parent.exp; - } - } else if (exp.startsWith('*')) { - // A pointer - data.exp = "*(" + parent.exp + ')'; - } else if (startsWithDigit(data.name)) { - // An array. No variables needed? - data.name = QLatin1Char('[') + data.name + QLatin1Char(']'); - data.exp = parent.exp + '[' + exp + ']'; - } else if (0 && parent.name.endsWith(QLatin1Char('.'))) { - // Happens with anonymous unions - data.exp = parent.exp + data.name.toLatin1(); - //data.name = "<anonymous union>"; - } else if (exp.isEmpty()) { - // Happens with anonymous unions - data.exp = parent.exp; - data.name = tr("<n/a>"); - data.iname = parent.iname + ".@"; - data.type = tr("<anonymous union>").toUtf8(); - } else { - // A structure. Hope there's nothing else... - data.exp = '(' + parent.exp + ")." + data.name.toLatin1(); - } - - if (hasDebuggingHelperForType(data.type)) { - // we do not trust gdb if we have a custom dumper - data.setValueNeeded(); - data.setHasChildrenNeeded(); - } - - //qDebug() << "VAR_LIST_CHILDREN: PARENT 3" << parent.toString(); - //qDebug() << "VAR_LIST_CHILDREN: APPENDEE" << data.toString(); - insertData(data); - } -} - -void GdbEngine::handleVarListChildrenClassic(const GdbResponse &response) -{ - //WatchResultCounter dummy(this, WatchVarListChildren); - WatchData data = response.cookie.value<WatchData>(); - if (!data.isValid()) - return; - if (response.resultClass == GdbResultDone) { - //qDebug() << "VAR_LIST_CHILDREN: PARENT" << data.toString(); - QList<GdbMi> children = response.data["children"].children(); - - if (children.isEmpty()) { - // happens e.g. if no debug information is present or - // if the class really has no children - WatchData data1; - data1.iname = data.iname + ".child"; - //: About variable's value - data1.value = tr("<no information>"); - data1.hasChildren = false; - data1.setAllUnneeded(); - insertData(data1); - data.setAllUnneeded(); - insertData(data); - } else { - if (data.variable.endsWith("private") - || data.variable.endsWith("protected") - || data.variable.endsWith("public")) { - // this skips the spurious "public", "private" etc levels - // gdb produces - } else { - data.setChildrenUnneeded(); - insertData(data); - } - for (int i = 0; i != children.size(); ++i) - handleVarListChildrenHelperClassic(children.at(i), data, i); - } - } else { - data.setError(QString::fromLocal8Bit(response.data["msg"].data())); - } -} - -void GdbEngine::handleEvaluateExpressionClassic(const GdbResponse &response) -{ - WatchData data = response.cookie.value<WatchData>(); - QTC_ASSERT(data.isValid(), qDebug() << "HUH?"); - if (response.resultClass == GdbResultDone) { - //if (col == 0) - // data.name = response.data.findChild("value").data(); - //else - data.updateValue(response.data); - } else { - data.setError(QString::fromLocal8Bit(response.data["msg"].data())); - } - //qDebug() << "HANDLE EVALUATE EXPRESSION:" << data.toString(); - insertData(data); - //updateWatchModel2(); -} - -} // namespace Internal -} // namespace Debugger diff --git a/src/plugins/debugger/gdb/coregdbadapter.h b/src/plugins/debugger/gdb/coregdbadapter.h index f1168b1320..e67495bf6b 100644 --- a/src/plugins/debugger/gdb/coregdbadapter.h +++ b/src/plugins/debugger/gdb/coregdbadapter.h @@ -52,8 +52,6 @@ public: ~GdbCoreEngine(); private: - DumperHandling dumperHandling() const { return DumperNotAvailable; } - void setupEngine(); void setupInferior(); void runEngine(); diff --git a/src/plugins/debugger/gdb/gdb.pri b/src/plugins/debugger/gdb/gdb.pri index 64607124f8..8fc016a19a 100644 --- a/src/plugins/debugger/gdb/gdb.pri +++ b/src/plugins/debugger/gdb/gdb.pri @@ -11,8 +11,6 @@ HEADERS += \ SOURCES += \ $$PWD/gdbengine.cpp \ - $$PWD/classicgdbengine.cpp \ - $$PWD/pythongdbengine.cpp \ $$PWD/gdboptionspage.cpp \ $$PWD/attachgdbadapter.cpp \ $$PWD/coregdbadapter.cpp \ diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 4fdb8529de..d119c253c1 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -34,7 +34,6 @@ #include "gdbplainengine.h" #include "termgdbadapter.h" #include "remotegdbserveradapter.h" - #include "gdboptionspage.h" #include <debugger/debuggerstartparameters.h> @@ -92,6 +91,7 @@ enum { debugPending = 0 }; #define CB(callback) &GdbEngine::callback, STRINGIFY(callback) + QByteArray GdbEngine::tooltipIName(const QString &exp) { return "tooltip." + exp.toLatin1().toHex(); @@ -208,11 +208,7 @@ GdbEngine::GdbEngine(const DebuggerStartParameters &startParameters) m_busy = false; m_debuggingHelperState = DebuggingHelperUninitialized; m_gdbVersion = 100; - m_gdbBuildVersion = -1; - m_isMacGdb = false; m_isQnxGdb = false; - m_hasBreakpointNotifications = false; - m_hasPython = false; m_registerNamesListed = false; m_sourcesListUpdating = false; m_oldestAcceptableToken = -1; @@ -222,16 +218,11 @@ GdbEngine::GdbEngine(const DebuggerStartParameters &startParameters) m_commandsDoneCallback = 0; m_stackNeeded = false; m_preparedForQmlBreak = false; - m_disassembleUsesComma = false; m_terminalTrap = startParameters.useTerminal; m_fullStartDone = false; m_systemDumpersLoaded = false; - m_forceAsyncModel = false; - m_pythonAttemptedToLoad = false; m_gdbProc = new GdbProcess(this); - invalidateSourcesList(); - m_debugInfoTaskHandler = new DebugInfoTaskHandler(this); //ExtensionSystem::PluginManager::addObject(m_debugInfoTaskHandler); @@ -463,7 +454,6 @@ void GdbEngine::handleResponse(const QByteArray &buff) if (!id.isEmpty()) showStatusMessage(tr("Library %1 loaded").arg(_(id)), 1000); progressPing(); - invalidateSourcesList(); Module module; module.startAddress = 0; module.endAddress = 0; @@ -478,7 +468,6 @@ void GdbEngine::handleResponse(const QByteArray &buff) QByteArray id = result["id"].data(); progressPing(); showStatusMessage(tr("Library %1 unloaded").arg(_(id)), 1000); - invalidateSourcesList(); } else if (asyncClass == "thread-group-added") { // 7.1-symbianelf has "{id="i1"}" } else if (asyncClass == "thread-group-created" @@ -522,33 +511,6 @@ void GdbEngine::handleResponse(const QByteArray &buff) QByteArray id = result["id"].data(); showStatusMessage(tr("Thread %1 selected").arg(_(id)), 1000); //"{id="2"}" - } else if (m_isMacGdb && asyncClass == "shlibs-updated") { - // Apple's gdb announces updated libs. - invalidateSourcesList(); - } else if (m_isMacGdb && asyncClass == "shlibs-added") { - // Apple's gdb announces added libs. - // {shlib-info={num="2", name="libmathCommon.A_debug.dylib", - // kind="-", dyld-addr="0x7f000", reason="dyld", requested-state="Y", - // state="Y", path="/usr/lib/system/libmathCommon.A_debug.dylib", - // description="/usr/lib/system/libmathCommon.A_debug.dylib", - // loaded_addr="0x7f000", slide="0x7f000", prefix=""}} - invalidateSourcesList(); - } else if (m_isMacGdb && asyncClass == "resolve-pending-breakpoint") { - // Apple's gdb announces resolved breakpoints. - // new_bp="1",pended_bp="1",new_expr="\"gdbengine.cpp\":1584", - // bkpt={number="1",type="breakpoint",disp="keep",enabled="y", - // addr="0x0000000115cc3ddf",func="foo()",file="../foo.cpp", - // line="1584",shlib="/../libFoo_debug.dylib",times="0"} - const GdbMi bkpt = result["bkpt"]; - const BreakpointResponseId rid(bkpt["number"].data()); - if (!isQmlStepBreakpoint(rid)) { - BreakHandler *handler = breakHandler(); - BreakpointModelId id = handler->findBreakpointByResponseId(rid); - BreakpointResponse br = handler->response(id); - updateResponse(br, bkpt); - handler->setResponse(id, br); - attemptAdjustBreakpointLocation(id); - } } else if (asyncClass == "breakpoint-modified") { // New in FSF gdb since 2011-04-27. // "{bkpt={number="3",type="breakpoint",disp="keep", @@ -557,7 +519,7 @@ void GdbEngine::handleResponse(const QByteArray &buff) // {number="3.1",enabled="y",addr="0x0805ff68", // func="Vector<int>::Vector(int)", // file="simple_gdbtest_app.cpp", - // fullname="/data/...line="135"},{number="3.2"...}}" + // fullname="/data/...line="135"},{number="3.2"...}}.." // Note the leading comma in original-location. Filter it out. // We don't need the field anyway. @@ -596,13 +558,12 @@ void GdbEngine::handleResponse(const QByteArray &buff) } } } - m_hasBreakpointNotifications = true; } else if (asyncClass == "breakpoint-created") { // "{bkpt={number="1",type="breakpoint",disp="del",enabled="y", // addr="<PENDING>",pending="main",times="0", // original-location="main"}}" -- or -- // {bkpt={number="2",type="hw watchpoint",disp="keep",enabled="y", - // what="*0xbfffed48",times="0",original-location="*0xbfffed48" + // what="*0xbfffed48",times="0",original-location="*0xbfffed48"}} BreakHandler *handler = breakHandler(); foreach (const GdbMi &bkpt, result.children()) { BreakpointResponse br; @@ -663,7 +624,6 @@ void GdbEngine::handleResponse(const QByteArray &buff) if (data.startsWith("Reading symbols from ")) { showStatusMessage(tr("Reading %1...").arg(_(data.mid(21))), 1000); progressPing(); - invalidateSourcesList(); } else if (data.startsWith("[New ") || data.startsWith("[Thread ")) { if (data.endsWith('\n')) data.chop(1); @@ -1283,10 +1243,15 @@ void GdbEngine::executeDebuggerCommand(const QString &command, DebuggerLanguages // This is called from CoreAdapter and AttachAdapter. void GdbEngine::updateAll() { - if (hasPython()) - updateAllPython(); - else - updateAllClassic(); + //PENDING_DEBUG("UPDATING ALL\n"); + QTC_CHECK(state() == InferiorUnrunnable || state() == InferiorStopOk); + reloadModulesInternal(); + postCommand("-stack-list-frames", CB(handleStackListFrames), + QVariant::fromValue<StackCookie>(StackCookie(false, true))); + stackHandler()->setCurrentIndex(0); + postCommand("-thread-info", CB(handleThreadInfo), 0); + reloadRegisters(); + updateLocals(); } void GdbEngine::handleQuerySources(const GdbResponse &response) @@ -1578,29 +1543,7 @@ void GdbEngine::handleStop1(const GdbMi &data) postCommand("importPlainDumpers"); } - bool initHelpers = m_debuggingHelperState == DebuggingHelperUninitialized - || m_debuggingHelperState == DebuggingHelperLoadTried; - // Don't load helpers on stops triggered by signals unless it's - // an intentional trap. - if (initHelpers - && dumperHandling() != DumperLoadedByGdbPreload - && reason == "signal-received") { - const QByteArray name = data["signal-name"].data(); - const DebuggerStartParameters &sp = startParameters(); - if (name != stopSignal(sp.toolChainAbi)) - initHelpers = false; - } - if (isSynchronous()) - initHelpers = false; - if (initHelpers) { - tryLoadDebuggingHelpersClassic(); - QVariant var = QVariant::fromValue<GdbMi>(data); - postCommand("p 4", CB(handleStop2), var); // dummy - } else { - handleStop2(data); - } - // Dumper loading is sequenced, as otherwise the display functions - // will start requesting data without knowing that dumpers are available. + handleStop2(data); } void GdbEngine::handleStop2(const GdbResponse &response) @@ -1667,15 +1610,6 @@ void GdbEngine::handleStop2(const GdbMi &data) isStopperThread = true; } - if (m_breakListOutdated) { - reloadBreakListInternal(); - } else { - // Older gdb versions do not produce "library loaded" messages - // so the breakpoint update is not triggered. - if (m_gdbVersion < 70000 && !m_isMacGdb && breakHandler()->size() > 0) - reloadBreakListInternal(); - } - if (reason == "watchpoint-trigger") { // *stopped,reason="watchpoint-trigger",wpt={number="2",exp="*0xbfffed40"}, // value={old="1",new="0"},frame={addr="0x00451e1b", @@ -1745,14 +1679,8 @@ void GdbEngine::handleStop2() if (!m_stackNeeded) return; - if (supportsThreads()) { - if (m_isMacGdb || m_gdbVersion < 70100) { - postCommand("-thread-list-ids", Discardable, CB(handleThreadListIds)); - } else { - // This is only available in gdb 7.1+. - postCommand("-thread-info", Discardable, CB(handleThreadInfo)); - } - } + // This is only available in gdb 7.1+. + postCommand("-thread-info", Discardable, CB(handleThreadInfo)); } void GdbEngine::handleInfoProc(const GdbResponse &response) @@ -1769,40 +1697,31 @@ void GdbEngine::handleShowVersion(const GdbResponse &response) { showMessage(_("PARSING VERSION: " + response.toString())); if (response.resultClass == GdbResultDone) { + bool isMacGdb = false; + int gdbBuildVersion = -1; m_gdbVersion = 100; - m_gdbBuildVersion = -1; - m_isMacGdb = false; m_isQnxGdb = false; QString msg = QString::fromLocal8Bit(response.consoleStreamOutput); extractGdbVersion(msg, - &m_gdbVersion, &m_gdbBuildVersion, &m_isMacGdb, &m_isQnxGdb); + &m_gdbVersion, &gdbBuildVersion, &isMacGdb, &m_isQnxGdb); // On Mac, fsf gdb does not work sufficiently well, // and on Linux and Windows we require at least 7.2. // Older versions with python still work, but can // be significantly slower. - bool isSupported = m_isMacGdb ? m_gdbVersion < 70000 - : (m_gdbVersion > 70200 && m_gdbVersion < 200000); + bool isSupported = m_gdbVersion >= 70500; if (isSupported) showMessage(_("SUPPORTED GDB VERSION ") + msg); else showMessage(_("UNSUPPORTED GDB VERSION ") + msg); showMessage(_("USING GDB VERSION: %1, BUILD: %2%3").arg(m_gdbVersion) - .arg(m_gdbBuildVersion).arg(_(m_isMacGdb ? " (APPLE)" : ""))); + .arg(gdbBuildVersion).arg(_(isMacGdb ? " (APPLE)" : ""))); - if (m_gdbVersion > 70300) - m_hasBreakpointNotifications = true; - - if (m_gdbVersion > 70100) - m_disassembleUsesComma = true; - - if (m_gdbVersion > 70100) { - if (usesExecInterrupt()) - postCommand("set target-async on", ConsoleCommand); - else - postCommand("set target-async off", ConsoleCommand); - } + if (usesExecInterrupt()) + postCommand("set target-async on", ConsoleCommand); + else + postCommand("set target-async off", ConsoleCommand); if (startParameters().multiProcess) postCommand("set detach-on-fork off", ConsoleCommand); @@ -1819,10 +1738,7 @@ void GdbEngine::handleListFeatures(const GdbResponse &response) void GdbEngine::handleHasPython(const GdbResponse &response) { - if (response.resultClass == GdbResultDone) - m_hasPython = true; - else - pythonDumpersFailed(); + Q_UNUSED(response); } void GdbEngine::handlePythonSetup(const GdbResponse &response) @@ -1834,7 +1750,6 @@ void GdbEngine::handlePythonSetup(const GdbResponse &response) postCommand("bbsetup"); } - m_hasPython = true; GdbMi data; data.fromStringMultiple(response.consoleStreamOutput); const GdbMi dumpers = data["dumpers"]; @@ -1855,24 +1770,6 @@ void GdbEngine::handlePythonSetup(const GdbResponse &response) } } -void GdbEngine::pythonDumpersFailed() -{ - m_hasPython = false; - const DebuggerStartParameters &sp = startParameters(); - if (dumperHandling() == DumperLoadedByGdbPreload && checkDebuggingHelpersClassic()) { - QByteArray cmd = "set environment "; - if (sp.toolChainAbi.os() == Abi::MacOS) - cmd += "DYLD_INSERT_LIBRARIES"; - else - cmd += "LD_PRELOAD"; - cmd += ' '; - if (sp.startMode != StartRemoteGdb) - cmd += sp.dumperLibrary.toLocal8Bit(); - postCommand(cmd); - m_debuggingHelperState = DebuggingHelperLoadTried; - } -} - void GdbEngine::showExecutionError(const QString &message) { showMessageBox(QMessageBox::Critical, tr("Execution Error"), @@ -2310,24 +2207,13 @@ void GdbEngine::executeRunToLine(const ContextData &data) showStatusMessage(tr("Run to line %1 requested...").arg(data.lineNumber), 5000); #if 1 QByteArray loc; - if (m_isMacGdb) { - if (data.address) - loc = addressSpec(data.address); - else - loc = "\"\\\"" + breakLocation(data.fileName).toLocal8Bit() + "\\\":" - + QByteArray::number(data.lineNumber) + '"'; - // "tbreak/continue" does _not_ work on Mac. See #4619 - postCommand("-break-insert -t -l -1 -f " + loc); - postCommand("-exec-continue", RunRequest, CB(handleExecuteRunToLine)); - } else { - if (data.address) - loc = addressSpec(data.address); - else - loc = '"' + breakLocation(data.fileName).toLocal8Bit() + '"' + ':' - + QByteArray::number(data.lineNumber); - postCommand("tbreak " + loc); - postCommand("continue", RunRequest, CB(handleExecuteRunToLine)); - } + if (data.address) + loc = addressSpec(data.address); + else + loc = '"' + breakLocation(data.fileName).toLocal8Bit() + '"' + ':' + + QByteArray::number(data.lineNumber); + postCommand("tbreak " + loc); + postCommand("continue", RunRequest, CB(handleExecuteRunToLine)); #else // Seems to jump to unpredicatable places. Observed in the manual // tests in the Foo::Foo() constructor with both gdb 6.8 and 7.1. @@ -2482,7 +2368,7 @@ void GdbEngine::updateResponse(BreakpointResponse &response, const GdbMi &bkpt) } else if (child.hasName("type")) { // "breakpoint", "hw breakpoint", "tracepoint", "hw watchpoint" // {bkpt={number="2",type="hw watchpoint",disp="keep",enabled="y", - // what="*0xbfffed48",times="0",original-location="*0xbfffed48" + // what="*0xbfffed48",times="0",original-location="*0xbfffed48"}} if (child.data().contains("tracepoint")) { response.tracepoint = true; } else if (child.data() == "hw watchpoint" || child.data() == "watchpoint") { @@ -2536,7 +2422,6 @@ void GdbEngine::updateResponse(BreakpointResponse &response, const GdbMi &bkpt) QString GdbEngine::breakLocation(const QString &file) const { - //QTC_CHECK(!m_breakListOutdated); QString where = m_fullToShortName.value(file); if (where.isEmpty()) return QFileInfo(file).fileName(); @@ -2627,31 +2512,12 @@ void GdbEngine::handleWatchInsert(const GdbResponse &response) } } -void GdbEngine::attemptAdjustBreakpointLocation(BreakpointModelId id) -{ - if (m_hasBreakpointNotifications) - return; - if (!debuggerCore()->boolSetting(AdjustBreakpointLocations)) - return; - BreakpointResponse response = breakHandler()->response(id); - if (response.address == 0 || response.correctedLineNumber != 0) - return; - // Prevent endless loop. - response.correctedLineNumber = -1; - breakHandler()->setResponse(id, response); - postCommand("info line *0x" + QByteArray::number(response.address, 16), - NeedsStop | RebuildBreakpointModel, - CB(handleInfoLine), QVariant::fromValue(id)); -} - void GdbEngine::handleCatchInsert(const GdbResponse &response) { BreakHandler *handler = breakHandler(); BreakpointModelId id = response.cookie.value<BreakpointModelId>(); - if (response.resultClass == GdbResultDone) { + if (response.resultClass == GdbResultDone) handler->notifyBreakpointInsertOk(id); - attemptAdjustBreakpointLocation(id); - } } void GdbEngine::handleBkpt(const GdbMi &bkpt, const BreakpointModelId &id) @@ -2727,13 +2593,6 @@ void GdbEngine::handleBreakInsert1(const GdbResponse &response) } else { handler->notifyBreakpointInsertOk(id); } - BreakpointResponse br = handler->response(id); - attemptAdjustBreakpointLocation(id); - // Remove if we only support 7.4 or later. - if (br.multiple && !m_hasBreakpointNotifications) - postCommand("info break " + QByteArray::number(br.id.majorPart()), - NeedsStop, CB(handleBreakListMultiple), - QVariant::fromValue(id)); } } else if (response.data["msg"].data().contains("Unknown option")) { // Older version of gdb don't know the -a option to set tracepoints @@ -2743,9 +2602,7 @@ void GdbEngine::handleBreakInsert1(const GdbResponse &response) QByteArray cmd = "trace " "\"" + GdbMi::escapeCString(fileName.toLocal8Bit()) + "\":" + QByteArray::number(lineNumber); - QVariant vid = QVariant::fromValue(id); - postCommand(cmd, NeedsStop | RebuildBreakpointModel, - CB(handleTraceInsert2), vid); + postCommand(cmd, NeedsStop | RebuildBreakpointModel); } else { // Some versions of gdb like "GNU gdb (GDB) SUSE (6.8.91.20090930-2.4)" // know how to do pending breakpoints using CLI but not MI. So try @@ -2761,7 +2618,6 @@ void GdbEngine::handleBreakInsert2(const GdbResponse &response) { if (response.resultClass == GdbResultDone) { BreakpointModelId id = response.cookie.value<BreakpointModelId>(); - attemptAdjustBreakpointLocation(id); breakHandler()->notifyBreakpointInsertOk(id); } else { // Note: gdb < 60800 doesn't "do" pending breakpoints. @@ -2771,94 +2627,6 @@ void GdbEngine::handleBreakInsert2(const GdbResponse &response) } } -void GdbEngine::handleTraceInsert2(const GdbResponse &response) -{ - if (response.resultClass == GdbResultDone) - reloadBreakListInternal(); -} - -void GdbEngine::reloadBreakListInternal() -{ - if (m_hasBreakpointNotifications) { - // Assume this properly handles breakpoint notifications. - return; - } - postCommand("-break-list", NeedsStop | RebuildBreakpointModel, - CB(handleBreakList)); -} - -void GdbEngine::handleBreakList(const GdbResponse &response) -{ - // 45^done,BreakpointTable={nr_rows="2",nr_cols="6",hdr=[ - // {width="3",alignment="-1",col_name="number",colhdr="Num"}, ... - // body=[bkpt={number="1",type="breakpoint",disp="keep",enabled="y", - // addr="0x000000000040109e",func="main",file="app.cpp", - // fullname="/home/apoenitz/dev/work/plugintest/app/app.cpp", - // line="11",times="1"}, - // bkpt={number="2",type="breakpoint",disp="keep",enabled="y", - // addr="<PENDING>",pending="plugin.cpp:7",times="0"}] ... } - - if (response.resultClass == GdbResultDone) { - GdbMi table = response.data["BreakpointTable"]; - if (table.isValid()) - handleBreakList(table); - } -} - -void GdbEngine::handleBreakList(const GdbMi &table) -{ - const GdbMi body = table["body"]; - QList<GdbMi> bkpts; - if (body.isValid()) { - // Non-Mac - bkpts = body.children(); - } else { - // Mac - bkpts = table.children(); - // Remove the 'hdr' and artificial items. - for (int i = bkpts.size(); --i >= 0; ) { - int num = bkpts.at(i)["number"].toInt(); - if (num <= 0) - bkpts.removeAt(i); - } - } - - BreakHandler *handler = breakHandler(); - foreach (const GdbMi &bkpt, bkpts) { - BreakpointResponse needle; - needle.id = BreakpointResponseId(bkpt["number"].data()); - if (isQmlStepBreakpoint2(needle.id)) - continue; - if (isQFatalBreakpoint(needle.id)) - continue; - BreakpointModelId id = handler->findSimilarBreakpoint(needle); - if (id.isValid()) { - BreakpointResponse response = handler->response(id); - updateResponse(response, bkpt); - handler->setResponse(id, response); - attemptAdjustBreakpointLocation(id); - response = handler->response(id); - if (response.multiple) - postCommand("info break " + response.id.toString().toLatin1(), - NeedsStop, CB(handleBreakListMultiple), - QVariant::fromValue(id)); - } else { - qDebug() << " NOTHING SUITABLE FOUND"; - showMessage(_("CANNOT FIND BP: " + bkpt.toString())); - } - } - - m_breakListOutdated = false; -} - -void GdbEngine::handleBreakListMultiple(const GdbResponse &response) -{ - QTC_CHECK(response.resultClass == GdbResultDone); - const BreakpointModelId id = response.cookie.value<BreakpointModelId>(); - const QString str = QString::fromLocal8Bit(response.consoleStreamOutput); - extractDataFromInfoBreak(str, id); -} - void GdbEngine::handleBreakDisable(const GdbResponse &response) { QTC_CHECK(response.resultClass == GdbResultDone); @@ -2948,164 +2716,14 @@ void GdbEngine::handleBreakCondition(const GdbResponse &response) // the output stream data. // The following happens on Mac: // QByteArray msg = response.data.findChild("msg").data(); - // if (1 || msg.startsWith("Error parsing breakpoint condition. " - // " Will try again when we hit the breakpoint.")) { + // if (msg.startsWith("Error parsing breakpoint condition. " + // " Will try again when we hit the breakpoint.")) BreakpointResponse br = handler->response(id); br.condition = handler->condition(id); handler->setResponse(id, br); changeBreakpoint(id); // Maybe there's more to do. } -void GdbEngine::extractDataFromInfoBreak(const QString &output, BreakpointModelId id) -{ - //qDebug() << output; - if (output.isEmpty()) - return; - // "Num Type Disp Enb Address What - // 4 breakpoint keep y <MULTIPLE> 0x00000000004066ad - // 4.1 y 0x00000000004066ad in CTorTester - // at /data5/dev/ide/main/tests/manual/gdbdebugger/simple/app.cpp:124 - // - or - - // everything on a single line on Windows for constructors of classes - // within namespaces. - // Sometimes the path is relative too. - - // 2 breakpoint keep y <MULTIPLE> 0x0040168e - // 2.1 y 0x0040168e in MainWindow::MainWindow(QWidget*) at mainwindow.cpp:7 - // 2.2 y 0x00401792 in MainWindow::MainWindow(QWidget*) at mainwindow.cpp:7 - - // "Num Type Disp Enb Address What - // 3 breakpoint keep y <MULTIPLE> \n" - // 3.1 y 0x0806094e in Vector<int>::Vector(int) at simple.cpp:141 - // 3.2 y 0x08060994 in Vector<float>::Vector(int) at simple.cpp:141 - // 3.3 y 0x080609da in Vector<double>::Vector(int) at simple.cpp:141 - // 3.4 y 0x08060a1d in Vector<char>::Vector(int) at simple.cpp:141 - - BreakHandler *handler = breakHandler(); - BreakpointResponse response = handler->response(id); - int posMultiple = output.indexOf(_("<MULTIPLE>")); - if (posMultiple != -1) { - QByteArray data = output.toUtf8(); - data.replace('\n', ' '); - data.replace(" ", " "); - data.replace(" ", " "); - data.replace(" ", " "); - int majorPart = 0; - int minorPart = 0; - int hitCount = 0; - bool hitCountComing = false; - bool functionComing = false; - bool locationComing = false; - QByteArray location; - QByteArray function; - qulonglong address = 0; - foreach (const QByteArray &part, data.split(' ')) { - if (part.isEmpty()) - continue; - //qDebug() << "PART: " << part; - if (majorPart == 0) { - majorPart = part.toInt(); - if (majorPart > 0) - continue; - } - if (part == "hit") { - hitCountComing = true; - continue; - } - if (hitCountComing) { - hitCountComing = false; - hitCount = part.toInt(); - continue; - } - if (part == "at") { - locationComing = true; - continue; - } - if (locationComing) { - locationComing = false; - location = part; - continue; - } - if (part == "in") { - functionComing = true; - continue; - } - if (functionComing) { - functionComing = false; - function = part; - continue; - } - if (part.startsWith("0x")) { - address = part.toInt(0, 0); - continue; - } - if (part.size() >= 3 && part.count('.') == 1) { - BreakpointResponseId subId(part); - int tmpMajor = subId.majorPart(); - int tmpMinor = subId.minorPart(); - if (tmpMajor == majorPart) { - if (minorPart) { - // Commit what we had before. - BreakpointResponse sub; - sub.address = address; - sub.functionName = QString::fromUtf8(function); - sub.updateLocation(location); - sub.id = BreakpointResponseId(majorPart, minorPart); - sub.type = response.type; - sub.address = address; - sub.hitCount = hitCount; - handler->insertSubBreakpoint(id, sub); - location.clear(); - function.clear(); - address = 0; - } - - // Now start new. - minorPart = tmpMinor; - continue; - } - } - } - if (minorPart) { - // Commit last chunk. - BreakpointResponse sub; - sub.address = address; - sub.functionName = QString::fromUtf8(function); - sub.updateLocation(location); - sub.id = BreakpointResponseId(majorPart, minorPart); - sub.type = response.type; - sub.hitCount = hitCount; - handler->insertSubBreakpoint(id, sub); - location.clear(); - function.clear(); - address = 0; - } - } else { - qDebug() << "COULD NOT MATCH" << output; - response.id = BreakpointResponseId(); // Unavailable. - } - //handler->setResponse(id, response); -} - -void GdbEngine::handleInfoLine(const GdbResponse &response) -{ - if (response.resultClass == GdbResultDone) { - // Old-style output: "Line 1102 of \"simple/app.cpp\" starts - // at address 0x80526aa <_Z10...+131> and ends at 0x80526b5 - // <_Z10testQStackv+142>.\n" - QByteArray ba = response.consoleStreamOutput; - const BreakpointModelId id = response.cookie.value<BreakpointModelId>(); - const int pos = ba.indexOf(' ', 5); - if (ba.startsWith("Line ") && pos != -1) { - const int line = ba.mid(5, pos - 5).toInt(); - BreakpointResponse br = breakHandler()->response(id); - br.lineNumber = line; - br.correctedLineNumber = line; - breakHandler()->setResponse(id, br); - } - } -} - bool GdbEngine::stateAcceptsBreakpointChanges() const { switch (state()) { @@ -3177,26 +2795,18 @@ void GdbEngine::insertBreakpoint(BreakpointModelId id) QByteArray cmd; if (handler->isTracepoint(id)) { cmd = "-break-insert -a -f "; - } else if (m_isMacGdb) { - cmd = "-break-insert -l -1 -f "; - } else if (m_gdbVersion >= 70000) { + } else { int spec = handler->threadSpec(id); cmd = "-break-insert "; if (spec >= 0) cmd += "-p " + QByteArray::number(spec); cmd += " -f "; - } else if (m_gdbVersion >= 60800) { - // Probably some earlier version would work as well. - cmd = "-break-insert -f "; - } else { - cmd = "-break-insert "; } if (handler->isOneShot(id)) cmd += "-t "; - // FIXME: -d does not work on Mac gdb. - if (!handler->isEnabled(id) && !m_isMacGdb) + if (!handler->isEnabled(id)) cmd += "-d "; if (int ignoreCount = handler->ignoreCount(id)) @@ -3278,7 +2888,6 @@ void GdbEngine::changeBreakpoint(BreakpointModelId id) return; } handler->notifyBreakpointChangeOk(id); - attemptAdjustBreakpointLocation(id); } void GdbEngine::removeBreakpoint(BreakpointModelId id) @@ -3314,7 +2923,6 @@ void GdbEngine::loadSymbols(const QString &modulePath) // FIXME: gdb does not understand quoted names here (tested with 6.8) postCommand("sharedlibrary " + dotEscape(modulePath.toLocal8Bit())); reloadModulesInternal(); - reloadBreakListInternal(); reloadStack(true); updateLocals(); } @@ -3323,7 +2931,6 @@ void GdbEngine::loadAllSymbols() { postCommand("sharedlibrary .*"); reloadModulesInternal(); - reloadBreakListInternal(); reloadStack(true); updateLocals(); } @@ -3347,7 +2954,6 @@ void GdbEngine::loadSymbolsForStack() } if (needUpdate) { //reloadModulesInternal(); - reloadBreakListInternal(); reloadStack(true); updateLocals(); } @@ -3558,11 +3164,6 @@ void GdbEngine::examineModules() // ////////////////////////////////////////////////////////////////////// -void GdbEngine::invalidateSourcesList() -{ - m_breakListOutdated = true; -} - void GdbEngine::reloadSourceFiles() { if ((state() == InferiorRunOk || state() == InferiorStopOk) @@ -3575,10 +3176,6 @@ void GdbEngine::reloadSourceFilesInternal() QTC_CHECK(!m_sourcesListUpdating); m_sourcesListUpdating = true; postCommand("-file-list-exec-source-files", NeedsStop, CB(handleQuerySources)); -#if 0 - if (m_gdbVersion < 70000 && !m_isMacGdb) - postCommand("set stop-on-solib-events 1"); -#endif } @@ -3644,8 +3241,7 @@ StackFrame GdbEngine::parseStackFrame(const GdbMi &frameMi, int level) void GdbEngine::handleStackListFrames(const GdbResponse &response) { - bool handleIt = (m_isMacGdb || response.resultClass == GdbResultDone); - if (!handleIt) { + if (response.resultClass != GdbResultDone) { // That always happens on symbian gdb with // ^error,data={msg="Previous frame identical to this frame (corrupt stack?)" // logStreamOutput: "Previous frame identical to this frame (corrupt stack?)\n" @@ -3747,7 +3343,7 @@ void GdbEngine::handleThreadInfo(const GdbResponse &response) selectThread(other); } updateViews(); // Adjust Threads combobox. - if (m_hasPython && debuggerCore()->boolSetting(ShowThreadNames)) { + if (debuggerCore()->boolSetting(ShowThreadNames)) { postCommand("threadnames " + debuggerCore()->action(MaximalStackDepth)->value().toByteArray(), Discardable, CB(handleThreadNames)); @@ -3918,20 +3514,6 @@ void GdbEngine::handleRegisterListValues(const GdbResponse &response) ////////////////////////////////////////////////////////////////////// // -// Thread specific stuff -// -////////////////////////////////////////////////////////////////////// - -bool GdbEngine::supportsThreads() const -{ - // FSF gdb 6.3 crashes happily on -thread-list-ids. So don't use it. - // The test below is a semi-random pick, 6.8 works fine - return m_isMacGdb || m_gdbVersion > 60500; -} - - -////////////////////////////////////////////////////////////////////// -// // Tooltip specific stuff // ////////////////////////////////////////////////////////////////////// @@ -4015,19 +3597,11 @@ bool GdbEngine::setToolTipExpression(const QPoint &mousePos, if (DebuggerToolTipManager::debug()) qDebug() << "GdbEngine::setToolTipExpression2 " << exp << (*m_toolTipContext); - if (isSynchronous()) { - UpdateParameters params; - params.tryPartial = true; - params.tooltipOnly = true; - params.varList = iname; - updateLocalsPython(params); - } else { - WatchData toolTip; - toolTip.exp = exp.toLatin1(); - toolTip.name = exp; - toolTip.iname = iname; - watchHandler()->insertData(toolTip); - } + UpdateParameters params; + params.tryPartial = true; + params.tooltipOnly = true; + params.varList = iname; + updateLocalsPython(params); return true; } @@ -4044,66 +3618,41 @@ void GdbEngine::reloadLocals() updateLocals(); } -bool GdbEngine::hasDebuggingHelperForType(const QByteArray &type) const +void GdbEngine::updateWatchData(const WatchData &data, const WatchUpdateFlags &flags) { - if (!debuggerCore()->boolSetting(UseDebuggingHelpers)) - return false; + // This should only be called for fresh expanded items, not for + // items that had their children retrieved earlier. + //qDebug() << "\nUPDATE WATCH DATA: " << data.toString() << "\n"; + if (data.iname.endsWith(".")) + return; - if (dumperHandling() == DumperNotAvailable) { - // Inferior calls are not possible in gdb when looking at core files. - return type == "QString" || type.endsWith("::QString") - || type == "QStringList" || type.endsWith("::QStringList"); + // Avoid endless loops created by faulty dumpers. + QByteArray processedName = "1-" + data.iname; + //qDebug() << "PROCESSED NAMES: " << processedName << m_processedNames; + if (m_processedNames.contains(processedName)) { + WatchData data1 = data; + showMessage(_("<Breaking endless loop for " + data.iname + '>'), + LogMiscInput); + data1.setAllUnneeded(); + data1.setValue(_("<unavailable>")); + data1.setHasChildren(false); + insertData(data1); + return; } + m_processedNames.insert(processedName); - if (m_debuggingHelperState != DebuggingHelperAvailable) - return false; + // FIXME: Is this sufficient when "external" changes are + // triggered e.g. by manually entered command in the gdb console? + //qDebug() << "TRY PARTIAL: " << flags.tryIncremental + // << (m_pendingBreakpointRequests == 0); - // Simple types. - return m_dumperHelper.type(type) != DumperHelper::UnknownType; -} + UpdateParameters params; + params.tooltipOnly = data.iname.startsWith("tooltip"); + params.tryPartial = flags.tryIncremental + && m_pendingBreakpointRequests == 0; + params.varList = data.iname; -void GdbEngine::updateWatchData(const WatchData &data, const WatchUpdateFlags &flags) -{ - if (isSynchronous()) { - // This should only be called for fresh expanded items, not for - // items that had their children retrieved earlier. - //qDebug() << "\nUPDATE WATCH DATA: " << data.toString() << "\n"; - if (data.iname.endsWith(".")) - return; - - // Avoid endless loops created by faulty dumpers. - QByteArray processedName = "1-" + data.iname; - //qDebug() << "PROCESSED NAMES: " << processedName << m_processedNames; - if (m_processedNames.contains(processedName)) { - WatchData data1 = data; - showMessage(_("<Breaking endless loop for " + data.iname + '>'), - LogMiscInput); - data1.setAllUnneeded(); - data1.setValue(_("<unavailable>")); - data1.setHasChildren(false); - insertData(data1); - return; - } - m_processedNames.insert(processedName); - - // FIXME: Is this sufficient when "external" changes are - // triggered e.g. by manually entered command in the gdb console? - //qDebug() << "TRY PARTIAL: " << flags.tryIncremental - // << hasPython() - // << (m_pendingBreakpointRequests == 0); - - UpdateParameters params; - params.tooltipOnly = data.iname.startsWith("tooltip"); - params.tryPartial = flags.tryIncremental - && hasPython() - && m_pendingBreakpointRequests == 0; - params.varList = data.iname; - - updateLocalsPython(params); - } else { - PENDING_DEBUG("UPDATE WATCH BUMPS PENDING UP TO " << m_uncompleted.size()); - updateSubItemClassic(data); - } + updateLocalsPython(params); } void GdbEngine::rebuildWatchModel() @@ -4112,8 +3661,6 @@ void GdbEngine::rebuildWatchModel() QTC_CHECK(m_uncompleted.isEmpty()); static int count = 0; ++count; - if (!isSynchronous()) - m_processedNames.clear(); PENDING_DEBUG("REBUILDING MODEL" << count); if (debuggerCore()->boolSetting(LogTimeStamps)) showMessage(LogWindow::logTimeStamp(), LogMiscInput); @@ -4161,127 +3708,10 @@ void GdbEngine::handleVarAssign(const GdbResponse &) updateLocals(); } -void GdbEngine::handleVarCreate(const GdbResponse &response) -{ - WatchData data = response.cookie.value<WatchData>(); - // Happens e.g. when we already issued a var-evaluate command. - if (!data.isValid()) - return; - //qDebug() << "HANDLE VARIABLE CREATION:" << data.toString(); - if (response.resultClass == GdbResultDone) { - data.variable = data.iname; - data.updateType(response.data["type"]); - if (watchHandler()->isExpandedIName(data.iname) - && !response.data["children"].isValid()) - data.setChildrenNeeded(); - else - data.setChildrenUnneeded(); - data.updateChildCount(response.data["numchild"]); - insertData(data); - } else { - data.setError(QString::fromLocal8Bit(response.data["msg"].data())); - if (data.isWatcher()) { - data.value = WatchData::msgNotInScope(); - data.type = " "; - data.setAllUnneeded(); - data.setHasChildren(false); - data.valueEnabled = false; - data.valueEditable = false; - insertData(data); - } - } -} - -void GdbEngine::handleDebuggingHelperSetup(const GdbResponse &response) -{ - if (response.resultClass == GdbResultDone) { - } else { - QString msg = QString::fromLocal8Bit(response.data["msg"].data()); - showStatusMessage(tr("Custom dumper setup: %1").arg(msg), 10000); - } -} - void GdbEngine::updateLocals() { watchHandler()->resetValueCache(); - if (hasPython()) - updateLocalsPython(UpdateParameters()); - else - updateLocalsClassic(); -} - -// Parse a local variable from GdbMi. -WatchData GdbEngine::localVariable(const GdbMi &item, - const QStringList &uninitializedVariables, - QMap<QByteArray, int> *seen) -{ - // Local variables of inlined code are reported as - // 26^done,locals={varobj={exp="this",value="",name="var4",exp="this", - // numchild="1",type="const QtSharedPointer::Basic<CPlusPlus::..."}} - // We do not want these at all. Current hypotheses is that those - // "spurious" locals have _two_ "exp" field. Try to filter them: - QByteArray name; - if (m_isMacGdb) { - int numExps = 0; - foreach (const GdbMi &child, item.children()) - numExps += int(child.name() == "exp"); - if (numExps > 1) - return WatchData(); - name = item["exp"].data(); - } else { - name = item["name"].data(); - } - const QMap<QByteArray, int>::iterator it = seen->find(name); - if (it != seen->end()) { - const int n = it.value(); - ++(it.value()); - WatchData data; - QString nam = _(name); - data.iname = "local." + name + QByteArray::number(n + 1); - data.name = WatchData::shadowedName(nam, n); - if (uninitializedVariables.contains(data.name)) { - data.setError(WatchData::msgNotInScope()); - return data; - } - data.updateValue(item); - //: Type of local variable or parameter shadowed by another - //: variable of the same name in a nested block. - data.setType(GdbEngine::tr("<shadowed>").toUtf8()); - data.setHasChildren(false); - return data; - } - seen->insert(name, 1); - WatchData data; - QString nam = _(name); - data.iname = "local." + name; - data.name = nam; - data.exp = name; - data.updateType(item["type"]); - if (uninitializedVariables.contains(data.name)) { - data.setError(WatchData::msgNotInScope()); - return data; - } - if (isSynchronous()) { - data.updateValue(item); - // We know that the complete list of children is - // somewhere in the response. - data.setChildrenUnneeded(); - } else { - // Set value only directly if it is simple enough, otherwise - // pass through the insertData() machinery. - if (isIntOrFloatType(data.type) || isPointerType(data.type)) - data.updateValue(item); - } - - if (!watchHandler()->isExpandedIName(data.iname)) - data.setChildrenUnneeded(); - - GdbMi t = item["numchild"]; - if (t.isValid()) - data.setHasChildren(t.toInt() > 0); - else if (isPointerType(data.type) || data.name == QLatin1String("this")) - data.setHasChildren(true); - return data; + updateLocalsPython(UpdateParameters()); } void GdbEngine::insertData(const WatchData &data) @@ -4306,7 +3736,7 @@ void GdbEngine::insertData(const WatchData &data) void GdbEngine::assignValueInDebugger(const WatchData *data, const QString &expression, const QVariant &value) { - if (hasPython() && !isIntOrFloatType(data->type)) { + if (!isIntOrFloatType(data->type)) { QByteArray cmd = "bbedit " + data->type.toHex() + ',' + expression.toUtf8().toHex() + ',' @@ -4582,8 +4012,7 @@ void GdbEngine::fetchDisassemblerByCliRangeMixed(const DisassemblerAgentCookie & const quint64 address = ac.agent->address(); QByteArray start = QByteArray::number(address - 20, 16); QByteArray end = QByteArray::number(address + 100, 16); - const char sep = m_disassembleUsesComma ? ',' : ' '; - QByteArray cmd = "disassemble /m 0x" + start + sep + "0x" + end; + QByteArray cmd = "disassemble /m 0x" + start + ",0x" + end; postCommand(cmd, Discardable|ConsoleCommand, CB(handleFetchDisassemblerByCliRangeMixed), QVariant::fromValue(ac)); } @@ -4595,8 +4024,7 @@ void GdbEngine::fetchDisassemblerByCliRangePlain(const DisassemblerAgentCookie & const quint64 address = ac.agent->address(); QByteArray start = QByteArray::number(address - 20, 16); QByteArray end = QByteArray::number(address + 100, 16); - const char sep = m_disassembleUsesComma ? ',' : ' '; - QByteArray cmd = "disassemble 0x" + start + sep + "0x" + end; + QByteArray cmd = "disassemble 0x" + start + ",0x" + end; postCommand(cmd, Discardable, CB(handleFetchDisassemblerByCliRangePlain), QVariant::fromValue(ac)); } @@ -4987,14 +4415,6 @@ void GdbEngine::loadInitScript() void GdbEngine::tryLoadPythonDumpers() { - if (m_forceAsyncModel) - return; - if (!m_hasPython) - return; - if (m_pythonAttemptedToLoad) - return; - m_pythonAttemptedToLoad = true; - const QByteArray dumperSourcePath = Core::ICore::resourcePath().toLocal8Bit() + "/debugger/"; @@ -5010,11 +4430,7 @@ void GdbEngine::tryLoadPythonDumpers() void GdbEngine::reloadDebuggingHelpers() { - // Only supported for python. - if (m_hasPython) { - m_pythonAttemptedToLoad = false; - tryLoadPythonDumpers(); - } + tryLoadPythonDumpers(); } void GdbEngine::handleGdbError(QProcess::ProcessError error) @@ -5270,11 +4686,6 @@ void GdbEngine::handleAdapterCrashed(const QString &msg) showMessageBox(QMessageBox::Critical, tr("Adapter crashed"), msg); } -bool GdbEngine::hasPython() const -{ - return m_hasPython; -} - void GdbEngine::createFullBacktrace() { postCommand("thread apply all bt full", @@ -5363,9 +4774,6 @@ bool GdbEngine::isHiddenBreakpoint(const BreakpointResponseId &id) const bool GdbEngine::usesExecInterrupt() const { - if (m_gdbVersion < 70000) - return false; - // debuggerCore()->boolSetting(TargetAsync) DebuggerStartMode mode = startParameters().startMode; return (mode == AttachToRemoteServer || mode == AttachToRemoteProcess) @@ -5390,9 +4798,6 @@ void GdbEngine::requestDebugInformation(const DebugInfoTask &task) bool GdbEngine::attemptQuickStart() const { - if (m_forceAsyncModel) - return false; - // Don't try if the user does not ask for it. if (!debuggerCore()->boolSetting(AttemptQuickStart)) return false; @@ -5516,6 +4921,188 @@ void addGdbOptionPages(QList<Core::IOptionsPage *> *opts) opts->push_back(new GdbOptionsPage2()); } + +void GdbEngine::updateLocalsPython(const UpdateParameters ¶ms) +{ + //m_pendingWatchRequests = 0; + m_pendingBreakpointRequests = 0; + m_processedNames.clear(); + + WatchHandler *handler = watchHandler(); + QByteArray expanded = "expanded:" + handler->expansionRequests() + ' '; + expanded += "typeformats:" + handler->typeFormatRequests() + ' '; + expanded += "formats:" + handler->individualFormatRequests(); + + QByteArray cutOff = " stringcutoff:" + + debuggerCore()->action(MaximalStringLength)->value().toByteArray(); + + QByteArray watchers; + const QString fileName = stackHandler()->currentFrame().file; + const QString function = stackHandler()->currentFrame().function; + if (!fileName.isEmpty()) { + // Re-create tooltip items that are not filters on existing local variables in + // the tooltip model. + DebuggerToolTipContexts toolTips = + DebuggerToolTipManager::treeWidgetExpressions(fileName, objectName(), function); + + const QString currentExpression = tooltipExpression(); + if (!currentExpression.isEmpty()) { + int currentIndex = -1; + for (int i = 0; i < toolTips.size(); ++i) { + if (toolTips.at(i).expression == currentExpression) { + currentIndex = i; + break; + } + } + if (currentIndex < 0) { + DebuggerToolTipContext context; + context.expression = currentExpression; + context.iname = tooltipIName(currentExpression); + toolTips.push_back(context); + } + } + + foreach (const DebuggerToolTipContext &p, toolTips) { + if (p.iname.startsWith("tooltip")) { + if (!watchers.isEmpty()) + watchers += "##"; + watchers += p.expression.toLatin1(); + watchers += '#'; + watchers += p.iname; + } + } + } + + QHash<QByteArray, int> watcherNames = handler->watcherNames(); + QHashIterator<QByteArray, int> it(watcherNames); + while (it.hasNext()) { + it.next(); + if (!watchers.isEmpty()) + watchers += "##"; + watchers += it.key() + "#watch." + QByteArray::number(it.value()); + } + + const static bool alwaysVerbose = !qgetenv("QTC_DEBUGGER_PYTHON_VERBOSE").isEmpty(); + QByteArray options; + if (alwaysVerbose) + options += "pe,"; + if (debuggerCore()->boolSetting(UseDebuggingHelpers)) + options += "fancy,"; + if (debuggerCore()->boolSetting(AutoDerefPointers)) + options += "autoderef,"; + if (debuggerCore()->boolSetting(UseDynamicType)) + options += "dyntype,"; + if (options.isEmpty()) + options += "defaults,"; + if (params.tryPartial) + options += "partial,"; + if (params.tooltipOnly) + options += "tooltiponly,"; + options.chop(1); + + QByteArray resultVar; + if (!m_resultVarName.isEmpty()) + resultVar = "resultvarname:" + m_resultVarName + ' '; + + postCommand("bb options:" + options + " vars:" + params.varList + ' ' + + resultVar + expanded + " watchers:" + watchers.toHex() + cutOff, + Discardable, CB(handleStackFramePython), QVariant(params.tryPartial)); +} + +void GdbEngine::handleStackFramePython(const GdbResponse &response) +{ + if (response.resultClass == GdbResultDone) { + const bool partial = response.cookie.toBool(); + QByteArray out = response.consoleStreamOutput; + while (out.endsWith(' ') || out.endsWith('\n')) + out.chop(1); + int pos = out.indexOf("data="); + if (pos != 0) { + showMessage(_("DISCARDING JUNK AT BEGIN OF RESPONSE: " + + out.left(pos))); + out = out.mid(pos); + } + GdbMi all; + all.fromStringMultiple(out); + GdbMi data = all["data"]; + + WatchHandler *handler = watchHandler(); + QList<WatchData> list; + + if (!partial) { + list.append(*handler->findData("local")); + list.append(*handler->findData("watch")); + list.append(*handler->findData("return")); + } + + foreach (const GdbMi &child, data.children()) { + WatchData dummy; + dummy.iname = child["iname"].data(); + GdbMi wname = child["wname"]; + if (wname.isValid()) { + // Happens (only) for watched expressions. They are encoded as + // base64 encoded 8 bit data, without quotes + dummy.name = decodeData(wname.data(), Base64Encoded8Bit); + dummy.exp = dummy.name.toUtf8(); + } else { + dummy.name = _(child["name"].data()); + } + parseWatchData(handler->expandedINames(), dummy, child, &list); + } + const GdbMi typeInfo = all["typeinfo"]; + if (typeInfo.type() == GdbMi::List) { + foreach (const GdbMi &s, typeInfo.children()) { + const GdbMi name = s["name"]; + const GdbMi size = s["size"]; + if (name.isValid() && size.isValid()) + m_typeInfoCache.insert(QByteArray::fromBase64(name.data()), + TypeInfo(size.data().toUInt())); + } + } + for (int i = 0; i != list.size(); ++i) { + const TypeInfo ti = m_typeInfoCache.value(list.at(i).type); + if (ti.size) + list[i].size = ti.size; + } + + handler->insertData(list); + + //PENDING_DEBUG("AFTER handleStackFrame()"); + // FIXME: This should only be used when updateLocals() was + // triggered by expanding an item in the view. + //if (m_pendingWatchRequests <= 0) { + //PENDING_DEBUG("\n\n .... AND TRIGGERS MODEL UPDATE\n"); + rebuildWatchModel(); + //} + if (!partial) + emit stackFrameCompleted(); + } else { + showMessage(_("DUMPER FAILED: " + response.toString())); + } +} + +QString GdbEngine::msgPtraceError(DebuggerStartMode sm) +{ + if (sm == StartInternal) { + return QCoreApplication::translate("QtDumperHelper", + "ptrace: Operation not permitted.\n\n" + "Could not attach to the process. " + "Make sure no other debugger traces this process.\n" + "Check the settings of\n" + "/proc/sys/kernel/yama/ptrace_scope\n" + "For more details, see /etc/sysctl.d/10-ptrace.conf\n"); + } + return QCoreApplication::translate("QtDumperHelper", + "ptrace: Operation not permitted.\n\n" + "Could not attach to the process. " + "Make sure no other debugger traces this process.\n" + "If your uid matches the uid\n" + "of the target process, check the settings of\n" + "/proc/sys/kernel/yama/ptrace_scope\n" + "For more details, see /etc/sysctl.d/10-ptrace.conf\n"); +} + + } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index 1a0369fc74..e98d0dd9da 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -66,123 +66,6 @@ enum DebuggingHelperState DebuggingHelperUnavailable }; -/* This is only used with Mac gdb since 2.2 - * - * "Custom dumper" is a library compiled against the current - * Qt containing functions to evaluate values of Qt classes - * (such as QString, taking pointers to their addresses). - * The library must be loaded into the debuggee. - * It provides a function that takes input from an input buffer - * and some parameters and writes output into an output buffer. - * Parameter 1 is the protocol: - * 1) Query. Fills output buffer with known types, Qt version and namespace. - * This information is parsed and stored by this class (special type - * enumeration). - * 2) Evaluate symbol, taking address and some additional parameters - * depending on type. */ - -class DumperHelper -{ -public: - enum Type { - UnknownType, - SupportedType, // A type that requires no special handling by the dumper - // Below types require special handling - QAbstractItemType, - QObjectType, QWidgetType, QObjectSlotType, QObjectSignalType, - QVectorType, QMapType, QMultiMapType, QMapNodeType, QStackType, - StdVectorType, StdDequeType, StdSetType, StdMapType, StdStackType, - StdStringType - }; - - // Type/Parameter struct required for building a value query - struct TypeData { - TypeData(); - void clear(); - - Type type; - bool isTemplate; - QByteArray tmplate; - QByteArray inner; - }; - - DumperHelper(); - void clear(); - - double dumperVersion() const { return m_dumperVersion; } - - int typeCount() const; - // Look up a simple, non-template type - Type simpleType(const QByteArray &simpleType) const; - // Look up a (potentially) template type and fill parameter struct - TypeData typeData(const QByteArray &typeName) const; - Type type(const QByteArray &typeName) const; - - int qtVersion() const; - QByteArray qtVersionString() const; - QByteArray qtNamespace() const; - void setQtNamespace(const QByteArray &ba) - { if (!ba.isEmpty()) m_qtNamespace = ba; } - - // Complete parse of "query" (protocol 1) response from debuggee buffer. - // 'data' excludes the leading indicator character. - bool parseQuery(const GdbMi &data); - // Sizes can be added as the debugger determines them - void addSize(const QByteArray &type, int size); - - // Determine the parameters required for an "evaluate" (protocol 2) call - void evaluationParameters(const WatchData &data, - const TypeData &td, - QByteArray *inBuffer, - QList<QByteArray> *extraParameters) const; - - QString toString(bool debug = false) const; - - static QString msgDumperOutdated(double requiredVersion, double currentVersion); - static QString msgPtraceError(DebuggerStartMode sm); - -private: - typedef QMap<QByteArray, Type> NameTypeMap; - typedef QMap<QByteArray, int> SizeCache; - - // Look up a simple (namespace) type - QByteArray evaluationSizeofTypeExpression(const QByteArray &typeName) const; - - NameTypeMap m_nameTypeMap; - SizeCache m_sizeCache; - - // The initial dumper query function returns sizes of some special - // types to aid CDB since it cannot determine the size of classes. - // They are not complete (std::allocator<X>). - enum SpecialSizeType { IntSize, PointerSize, StdAllocatorSize, - QSharedPointerSize, QSharedDataPointerSize, - QWeakPointerSize, QPointerSize, - QListSize, QLinkedListSize, QVectorSize, QQueueSize, - SpecialSizeCount }; - - // Resolve name to enumeration or SpecialSizeCount (invalid) - SpecialSizeType specialSizeType(const QByteArray &type) const; - - int m_specialSizes[SpecialSizeCount]; - - typedef QMap<QByteArray, QByteArray> ExpressionCache; - ExpressionCache m_expressionCache; - int m_qtVersion; - double m_dumperVersion; - QByteArray m_qtNamespace; - - void setQClassPrefixes(const QByteArray &qNamespace); - - QByteArray m_qPointerPrefix; - QByteArray m_qSharedPointerPrefix; - QByteArray m_qSharedDataPointerPrefix; - QByteArray m_qWeakPointerPrefix; - QByteArray m_qListPrefix; - QByteArray m_qLinkedListPrefix; - QByteArray m_qVectorPrefix; - QByteArray m_qQueuePrefix; -}; - class GdbEngine : public Debugger::DebuggerEngine { Q_OBJECT @@ -206,9 +89,8 @@ private: ////////// General Interface ////////// virtual bool acceptsDebuggerCommands() const; virtual void executeDebuggerCommand(const QString &command, DebuggerLanguages languages); - virtual QByteArray qtNamespace() const { return m_dumperHelper.qtNamespace(); } - virtual void setQtNamespace(const QByteArray &ns) - { return m_dumperHelper.setQtNamespace(ns); } + virtual QByteArray qtNamespace() const { return m_qtNamespace; } + virtual void setQtNamespace(const QByteArray &ns) { m_qtNamespace = ns; } private: ////////// General State ////////// @@ -228,7 +110,6 @@ protected: ////////// Gdb Process Management ////////// void loadInitScript(); void tryLoadPythonDumpers(); - void pythonDumpersFailed(); // Something went wrong with the adapter *before* adapterStarted() was emitted. // Make sure to clean up everything before emitting this signal. @@ -359,7 +240,6 @@ private: CommandsDoneCallback m_commandsDoneCallback; QList<GdbCommand> m_commandsToRunOnTemporaryBreak; - int gdbVersion() const { return m_gdbVersion; } private: ////////// Gdb Output, State & Capability Handling ////////// protected: @@ -374,9 +254,7 @@ protected: StackFrame parseStackFrame(const GdbMi &mi, int level); void resetCommandQueue(); - bool isSynchronous() const { return hasPython(); } - virtual bool hasPython() const; - bool supportsThreads() const; + bool isSynchronous() const { return true; } // Gdb initialization sequence void handleShowVersion(const GdbResponse &response); @@ -384,12 +262,8 @@ protected: void handleHasPython(const GdbResponse &response); void handlePythonSetup(const GdbResponse &response); - int m_gdbVersion; // 6.8.0 is 60800 - int m_gdbBuildVersion; // MAC only? - bool m_isMacGdb; + int m_gdbVersion; // 7.6.1 is 70601 bool m_isQnxGdb; - bool m_hasBreakpointNotifications; - bool m_hasPython; private: ////////// Inferior Management ////////// @@ -428,9 +302,9 @@ private: ////////// Inferior Management ////////// void maybeHandleInferiorPidChanged(const QString &pid); void handleInfoProc(const GdbResponse &response); + QString msgPtraceError(DebuggerStartMode sm); private: ////////// View & Data Stuff ////////// - protected: void selectThread(ThreadId threadId); void activateFrame(int index); @@ -439,10 +313,7 @@ private: ////////// View & Data Stuff ////////// // // Breakpoint specific stuff // - void handleBreakList(const GdbResponse &response); - void handleBreakList(const GdbMi &table); void handleBreakModifications(const GdbMi &bkpts); - void handleBreakListMultiple(const GdbResponse &response); void handleBreakIgnore(const GdbResponse &response); void handleBreakDisable(const GdbResponse &response); void handleBreakEnable(const GdbResponse &response); @@ -455,18 +326,15 @@ private: ////////// View & Data Stuff ////////// void handleWatchInsert(const GdbResponse &response); void handleCatchInsert(const GdbResponse &response); void handleBkpt(const GdbMi &bkpt, const BreakpointModelId &id); - void handleInfoLine(const GdbResponse &response); - void extractDataFromInfoBreak(const QString &output, BreakpointModelId); void updateResponse(BreakpointResponse &response, const GdbMi &bkpt); QByteArray breakpointLocation(BreakpointModelId id); // For gdb/MI. QByteArray breakpointLocation2(BreakpointModelId id); // For gdb/CLI fallback. QString breakLocation(const QString &file) const; - void reloadBreakListInternal(); - void attemptAdjustBreakpointLocation(BreakpointModelId id); // // Modules specific stuff // + protected: void loadSymbols(const QString &moduleName); Q_SLOT void loadAllSymbols(); void loadSymbolsForStack(); @@ -474,6 +342,7 @@ private: ////////// View & Data Stuff ////////// void requestModuleSections(const QString &moduleName); void reloadModules(); void examineModules(); + void reloadModulesInternal(); void handleModulesList(const GdbResponse &response); void handleShowModuleSymbols(const GdbResponse &response); @@ -522,8 +391,6 @@ private: ////////// View & Data Stuff ////////// DisassemblerLines parseMiDisassembler(const GdbMi &response); Q_SLOT void reloadDisassembly(); - bool m_disassembleUsesComma; - // // Source file specific stuff // @@ -539,17 +406,13 @@ private: ////////// View & Data Stuff ////////// QMap<QString, QString> m_fullToShortName; QMultiMap<QString, QString> m_baseNameToFullName; - void invalidateSourcesList(); bool m_sourcesListUpdating; - bool m_breakListOutdated; // // Stack specific stuff // protected: void updateAll(); - void updateAllClassic(); - void updateAllPython(); void handleStackListFrames(const GdbResponse &response); void handleStackSelectThread(const GdbResponse &response); void handleStackSelectFrame(const GdbResponse &response); @@ -581,34 +444,15 @@ protected: virtual void watchPoint(const QPoint &); void handleWatchPoint(const GdbResponse &response); - void updateSubItemClassic(const WatchData &data); - void updateWatchData(const WatchData &data, const WatchUpdateFlags &flags); void rebuildWatchModel(); void showToolTip(); void insertData(const WatchData &data); void sendWatchParameters(const QByteArray ¶ms0); - void createGdbVariableClassic(const WatchData &data); - - void runDebuggingHelperClassic(const WatchData &data, bool dumpChildren); - void runDirectDebuggingHelperClassic(const WatchData &data, bool dumpChildren); - bool hasDebuggingHelperForType(const QByteArray &type) const; - void handleVarListChildrenClassic(const GdbResponse &response); - void handleVarListChildrenHelperClassic(const GdbMi &child, - const WatchData &parent, int sortId); - void handleVarCreate(const GdbResponse &response); void handleVarAssign(const GdbResponse &response); - void handleEvaluateExpressionClassic(const GdbResponse &response); - void handleQueryDebuggingHelperClassic(const GdbResponse &response); - void handleDebuggingHelperValue2Classic(const GdbResponse &response); - void handleDebuggingHelperValue3Classic(const GdbResponse &response); - void handleDebuggingHelperEditValue(const GdbResponse &response); - void handleDebuggingHelperSetup(const GdbResponse &response); - void handleDebuggingHelperVersionCheckClassic(const GdbResponse &response); void handleDetach(const GdbResponse &response); - void handleThreadGroupCreated(const GdbMi &result); void handleThreadGroupExited(const GdbMi &result); @@ -616,17 +460,10 @@ protected: void handleCreateFullBacktrace(const GdbResponse &response); void updateLocals(); - void updateLocalsClassic(); void updateLocalsPython(const UpdateParameters ¶meters); void handleStackFramePython(const GdbResponse &response); - void handleStackListLocalsClassic(const GdbResponse &response); - - WatchData localVariable(const GdbMi &item, - const QStringList &uninitializedVariables, - QMap<QByteArray, int> *seen); void setLocals(const QList<GdbMi> &locals); - void handleStackListArgumentsClassic(const GdbResponse &response); QSet<QByteArray> m_processedNames; struct TypeInfo @@ -641,13 +478,10 @@ protected: // // Dumper Management // - bool checkDebuggingHelpersClassic(); - void setDebuggingHelperStateClassic(DebuggingHelperState); - void tryLoadDebuggingHelpersClassic(); void reloadDebuggingHelpers(); DebuggingHelperState m_debuggingHelperState; - DumperHelper m_dumperHelper; + QByteArray m_qtNamespace; QString m_gdb; // @@ -699,10 +533,8 @@ protected: bool attemptQuickStart() const; bool m_fullStartDone; bool m_systemDumpersLoaded; - bool m_pythonAttemptedToLoad; // Test - bool m_forceAsyncModel; QList<WatchData> m_completed; QSet<QByteArray> m_uncompleted; @@ -718,18 +550,8 @@ protected: QByteArray m_lastDebuggableCommand; protected: - enum DumperHandling - { - DumperNotAvailable, - DumperLoadedByAdapter, - DumperLoadedByGdbPreload, - DumperLoadedByGdb - }; - virtual void write(const QByteArray &data); - virtual DumperHandling dumperHandling() const = 0; - protected: bool prepareCommand(); void interruptLocalInferior(qint64 pid); @@ -738,7 +560,6 @@ protected: ProjectExplorer::DeviceProcessSignalOperation::Ptr m_signalOperation; }; - } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/gdb/gdbplainengine.cpp b/src/plugins/debugger/gdb/gdbplainengine.cpp index 4050e9048e..276cd52afb 100644 --- a/src/plugins/debugger/gdb/gdbplainengine.cpp +++ b/src/plugins/debugger/gdb/gdbplainengine.cpp @@ -112,13 +112,6 @@ void GdbPlainEngine::handleExecRun(const GdbResponse &response) } } -GdbEngine::DumperHandling GdbPlainEngine::dumperHandling() const -{ - // LD_PRELOAD fails for System-Qt on Mac. - return Utils::HostOsInfo::isWindowsHost() || Utils::HostOsInfo::isMacHost() - ? DumperLoadedByGdb : DumperLoadedByGdbPreload; -} - void GdbPlainEngine::setupEngine() { QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); diff --git a/src/plugins/debugger/gdb/gdbplainengine.h b/src/plugins/debugger/gdb/gdbplainengine.h index 1bbc3e5677..6e226a095d 100644 --- a/src/plugins/debugger/gdb/gdbplainengine.h +++ b/src/plugins/debugger/gdb/gdbplainengine.h @@ -55,8 +55,6 @@ private: void interruptInferior2(); void shutdownEngine(); - DumperHandling dumperHandling() const; - QByteArray execFilePath() const; QByteArray toLocalEncoding(const QString &s) const; QString fromLocalEncoding(const QByteArray &b) const; diff --git a/src/plugins/debugger/gdb/pythongdbengine.cpp b/src/plugins/debugger/gdb/pythongdbengine.cpp deleted file mode 100644 index 3072ab7f89..0000000000 --- a/src/plugins/debugger/gdb/pythongdbengine.cpp +++ /dev/null @@ -1,233 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "gdbengine.h" - -#include <debugger/debuggerprotocol.h> -#include <debugger/debuggeractions.h> -#include <debugger/debuggercore.h> -#include <debugger/debuggerstringutils.h> -#include <debugger/debuggertooltipmanager.h> - -#include <debugger/stackhandler.h> - -#include <utils/savedaction.h> -#include <utils/qtcassert.h> - -#define PRECONDITION QTC_CHECK(hasPython()) -#define CB(callback) &GdbEngine::callback, STRINGIFY(callback) - - -namespace Debugger { -namespace Internal { - -void GdbEngine::updateLocalsPython(const UpdateParameters ¶ms) -{ - PRECONDITION; - //m_pendingWatchRequests = 0; - m_pendingBreakpointRequests = 0; - m_processedNames.clear(); - - WatchHandler *handler = watchHandler(); - QByteArray expanded = "expanded:" + handler->expansionRequests() + ' '; - expanded += "typeformats:" + handler->typeFormatRequests() + ' '; - expanded += "formats:" + handler->individualFormatRequests(); - - QByteArray cutOff = " stringcutoff:" - + debuggerCore()->action(MaximalStringLength)->value().toByteArray(); - - QByteArray watchers; - const QString fileName = stackHandler()->currentFrame().file; - const QString function = stackHandler()->currentFrame().function; - if (!fileName.isEmpty()) { - // Re-create tooltip items that are not filters on existing local variables in - // the tooltip model. - DebuggerToolTipContexts toolTips = - DebuggerToolTipManager::treeWidgetExpressions(fileName, objectName(), function); - - const QString currentExpression = tooltipExpression(); - if (!currentExpression.isEmpty()) { - int currentIndex = -1; - for (int i = 0; i < toolTips.size(); ++i) { - if (toolTips.at(i).expression == currentExpression) { - currentIndex = i; - break; - } - } - if (currentIndex < 0) { - DebuggerToolTipContext context; - context.expression = currentExpression; - context.iname = tooltipIName(currentExpression); - toolTips.push_back(context); - } - } - - foreach (const DebuggerToolTipContext &p, toolTips) { - if (p.iname.startsWith("tooltip")) { - if (!watchers.isEmpty()) - watchers += "##"; - watchers += p.expression.toLatin1(); - watchers += '#'; - watchers += p.iname; - } - } - } - - QHash<QByteArray, int> watcherNames = handler->watcherNames(); - QHashIterator<QByteArray, int> it(watcherNames); - while (it.hasNext()) { - it.next(); - if (!watchers.isEmpty()) - watchers += "##"; - watchers += it.key() + "#watch." + QByteArray::number(it.value()); - } - - const static bool alwaysVerbose = !qgetenv("QTC_DEBUGGER_PYTHON_VERBOSE").isEmpty(); - QByteArray options; - if (alwaysVerbose) - options += "pe,"; - if (debuggerCore()->boolSetting(UseDebuggingHelpers)) - options += "fancy,"; - if (debuggerCore()->boolSetting(AutoDerefPointers)) - options += "autoderef,"; - if (debuggerCore()->boolSetting(UseDynamicType)) - options += "dyntype,"; - if (options.isEmpty()) - options += "defaults,"; - if (params.tryPartial) - options += "partial,"; - if (params.tooltipOnly) - options += "tooltiponly,"; - options.chop(1); - - QByteArray resultVar; - if (!m_resultVarName.isEmpty()) - resultVar = "resultvarname:" + m_resultVarName + ' '; - - QByteArray cmd = - "bb options:" + options + " vars:" + params.varList + ' ' - + resultVar + expanded + " watchers:" + watchers.toHex() + cutOff; - - m_lastDebuggableCommand = - "bb options:pe," + options + " vars:" + params.varList + ' ' - + resultVar + expanded + " watchers:" + watchers.toHex() + cutOff; - - postCommand(cmd, Discardable, CB(handleStackFramePython), QVariant(params.tryPartial)); -} - -void GdbEngine::handleStackFramePython(const GdbResponse &response) -{ - PRECONDITION; - if (response.resultClass == GdbResultDone) { - const bool partial = response.cookie.toBool(); - QByteArray out = response.consoleStreamOutput; - while (out.endsWith(' ') || out.endsWith('\n')) - out.chop(1); - int pos = out.indexOf("data="); - if (pos != 0) { - showMessage(_("DISCARDING JUNK AT BEGIN OF RESPONSE: " - + out.left(pos))); - out = out.mid(pos); - } - GdbMi all; - all.fromStringMultiple(out); - GdbMi data = all["data"]; - - WatchHandler *handler = watchHandler(); - QList<WatchData> list; - - if (!partial) { - list.append(*handler->findData("local")); - list.append(*handler->findData("watch")); - list.append(*handler->findData("return")); - } - - foreach (const GdbMi &child, data.children()) { - WatchData dummy; - dummy.iname = child["iname"].data(); - GdbMi wname = child["wname"]; - if (wname.isValid()) { - // Happens (only) for watched expressions. They are encoded as - // base64 encoded 8 bit data, without quotes - dummy.name = decodeData(wname.data(), Base64Encoded8Bit); - dummy.exp = dummy.name.toUtf8(); - } else { - dummy.name = _(child["name"].data()); - } - parseWatchData(handler->expandedINames(), dummy, child, &list); - } - const GdbMi typeInfo = all["typeinfo"]; - if (typeInfo.type() == GdbMi::List) { - foreach (const GdbMi &s, typeInfo.children()) { - const GdbMi name = s["name"]; - const GdbMi size = s["size"]; - if (name.isValid() && size.isValid()) - m_typeInfoCache.insert(QByteArray::fromBase64(name.data()), - TypeInfo(size.data().toUInt())); - } - } - for (int i = 0; i != list.size(); ++i) { - const TypeInfo ti = m_typeInfoCache.value(list.at(i).type); - if (ti.size) - list[i].size = ti.size; - } - - handler->insertData(list); - - //PENDING_DEBUG("AFTER handleStackFrame()"); - // FIXME: This should only be used when updateLocals() was - // triggered by expanding an item in the view. - //if (m_pendingWatchRequests <= 0) { - //PENDING_DEBUG("\n\n .... AND TRIGGERS MODEL UPDATE\n"); - rebuildWatchModel(); - //} - if (!partial) - emit stackFrameCompleted(); - } else { - showMessage(_("DUMPER FAILED: " + response.toString())); - } -} - -// Called from CoreAdapter and AttachAdapter -void GdbEngine::updateAllPython() -{ - PRECONDITION; - //PENDING_DEBUG("UPDATING ALL\n"); - QTC_CHECK(state() == InferiorUnrunnable || state() == InferiorStopOk); - reloadModulesInternal(); - postCommand("-stack-list-frames", CB(handleStackListFrames), - QVariant::fromValue<StackCookie>(StackCookie(false, true))); - stackHandler()->setCurrentIndex(0); - postCommand("-thread-info", CB(handleThreadInfo), 0); - reloadRegisters(); - updateLocals(); -} - -} // namespace Internal -} // namespace Debugger diff --git a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp index 5cec6a3572..4852e902fc 100644 --- a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp +++ b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp @@ -75,16 +75,6 @@ GdbRemoteServerEngine::GdbRemoteServerEngine(const DebuggerStartParameters &star SLOT(uploadProcFinished())); } -GdbEngine::DumperHandling GdbRemoteServerEngine::dumperHandling() const -{ - using namespace ProjectExplorer; - const Abi abi = startParameters().toolChainAbi; - if (abi.os() == Abi::WindowsOS - || abi.binaryFormat() == Abi::ElfFormat) - return DumperLoadedByGdb; - return DumperLoadedByGdbPreload; -} - void GdbRemoteServerEngine::setupEngine() { QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); @@ -378,7 +368,7 @@ void GdbRemoteServerEngine::handleAttach(const GdbResponse &response) } case GdbResultError: if (response.data["msg"].data() == "ptrace: Operation not permitted.") { - notifyInferiorSetupFailed(DumperHelper::msgPtraceError(startParameters().startMode)); + notifyInferiorSetupFailed(msgPtraceError(startParameters().startMode)); break; } // if msg != "ptrace: ..." fall through diff --git a/src/plugins/debugger/gdb/remotegdbserveradapter.h b/src/plugins/debugger/gdb/remotegdbserveradapter.h index 3854576485..96a7c894e1 100644 --- a/src/plugins/debugger/gdb/remotegdbserveradapter.h +++ b/src/plugins/debugger/gdb/remotegdbserveradapter.h @@ -49,8 +49,6 @@ public: explicit GdbRemoteServerEngine(const DebuggerStartParameters &startParameters); private: - DumperHandling dumperHandling() const; - void setupEngine(); void setupInferior(); void runEngine(); diff --git a/src/plugins/debugger/gdb/termgdbadapter.cpp b/src/plugins/debugger/gdb/termgdbadapter.cpp index 48e5ef4378..2a18b6c34b 100644 --- a/src/plugins/debugger/gdb/termgdbadapter.cpp +++ b/src/plugins/debugger/gdb/termgdbadapter.cpp @@ -74,14 +74,6 @@ GdbTermEngine::~GdbTermEngine() m_stubProc.disconnect(); // Avoid spurious state transitions from late exiting stub } -GdbEngine::DumperHandling GdbTermEngine::dumperHandling() const -{ - // LD_PRELOAD fails for System-Qt on Mac. - return Utils::HostOsInfo::isWindowsHost() || Utils::HostOsInfo::isMacHost() - ? DumperLoadedByGdb - : DumperLoadedByAdapter; // Handles loading itself via LD_PRELOAD -} - void GdbTermEngine::setupEngine() { QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); @@ -169,7 +161,7 @@ void GdbTermEngine::handleStubAttached(const GdbResponse &response) break; case GdbResultError: if (response.data["msg"].data() == "ptrace: Operation not permitted.") { - notifyInferiorSetupFailed(DumperHelper::msgPtraceError(startParameters().startMode)); + notifyInferiorSetupFailed(msgPtraceError(startParameters().startMode)); break; } notifyInferiorSetupFailed(QString::fromLocal8Bit(response.data["msg"].data())); diff --git a/src/plugins/debugger/gdb/termgdbadapter.h b/src/plugins/debugger/gdb/termgdbadapter.h index 67e17ce127..76f5491504 100644 --- a/src/plugins/debugger/gdb/termgdbadapter.h +++ b/src/plugins/debugger/gdb/termgdbadapter.h @@ -52,8 +52,6 @@ public: ~GdbTermEngine(); private: - DumperHandling dumperHandling() const; - void setupEngine(); void handleGdbStartFailed(); void setupInferior(); diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index 4e4018b8a2..4b4587e272 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -89,7 +89,6 @@ for(p, SUBDIRS) { $$pv = $$QTC_PLUGIN_DEPENDS } -SUBDIRS += debugger/dumper.pro linux-* { SUBDIRS += debugger/ptracepreload.pro } diff --git a/src/plugins/projectexplorer/localapplicationrunconfiguration.h b/src/plugins/projectexplorer/localapplicationrunconfiguration.h index 98d4dfeb70..9ab9b80c78 100644 --- a/src/plugins/projectexplorer/localapplicationrunconfiguration.h +++ b/src/plugins/projectexplorer/localapplicationrunconfiguration.h @@ -54,8 +54,6 @@ public: virtual RunMode runMode() const = 0; virtual QString workingDirectory() const = 0; virtual QString commandLineArguments() const = 0; - virtual QString dumperLibrary() const = 0; - virtual QStringList dumperLibraryLocations() const = 0; virtual void addToBaseEnvironment(Utils::Environment &env) const; diff --git a/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp b/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp index db63e584ab..b3b2b81273 100644 --- a/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp +++ b/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp @@ -294,16 +294,6 @@ QString QbsRunConfiguration::qbsProduct() const return m_qbsProduct; } -QString QbsRunConfiguration::dumperLibrary() const -{ - return QtSupport::QtKitInformation::dumperLibrary(target()->kit()); -} - -QStringList QbsRunConfiguration::dumperLibraryLocations() const -{ - return QtSupport::QtKitInformation::dumperLibraryLocations(target()->kit()); -} - QString QbsRunConfiguration::defaultDisplayName() { QString defaultName; diff --git a/src/plugins/qbsprojectmanager/qbsrunconfiguration.h b/src/plugins/qbsprojectmanager/qbsrunconfiguration.h index dabc7b7b73..db0204ed0a 100644 --- a/src/plugins/qbsprojectmanager/qbsrunconfiguration.h +++ b/src/plugins/qbsprojectmanager/qbsrunconfiguration.h @@ -83,8 +83,6 @@ public: bool forcedGuiMode() const; QString workingDirectory() const; QString commandLineArguments() const; - QString dumperLibrary() const; - QStringList dumperLibraryLocations() const; QVariantMap toMap() const; diff --git a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp index 6e20bd54db..369eb6443f 100644 --- a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp +++ b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.cpp @@ -553,16 +553,6 @@ QString DesktopQmakeRunConfiguration::proFilePath() const return m_proFilePath; } -QString DesktopQmakeRunConfiguration::dumperLibrary() const -{ - return QtSupport::QtKitInformation::dumperLibrary(target()->kit()); -} - -QStringList DesktopQmakeRunConfiguration::dumperLibraryLocations() const -{ - return QtSupport::QtKitInformation::dumperLibraryLocations(target()->kit()); -} - QString DesktopQmakeRunConfiguration::defaultDisplayName() { QString defaultName; diff --git a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h index 3b17953aac..3233173e0d 100644 --- a/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h +++ b/src/plugins/qmakeprojectmanager/desktopqmakerunconfiguration.h @@ -81,8 +81,6 @@ public: bool forcedGuiMode() const; virtual QString workingDirectory() const; virtual QString commandLineArguments() const; - QString dumperLibrary() const; - QStringList dumperLibraryLocations() const; bool isUsingDyldImageSuffix() const; void setUsingDyldImageSuffix(bool state); diff --git a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp index f703e6d13f..c60cdddfd6 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp @@ -140,16 +140,6 @@ QString QmlProjectRunConfiguration::commandLineArguments() const return args; } -QString QmlProjectRunConfiguration::dumperLibrary() const -{ - return QString(); -} - -QStringList QmlProjectRunConfiguration::dumperLibraryLocations() const -{ - return QStringList(); -} - QString QmlProjectRunConfiguration::workingDirectory() const { QFileInfo projectFile(target()->project()->projectFilePath()); diff --git a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h index cef09742c9..d763877942 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h +++ b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.h @@ -65,8 +65,6 @@ public: QString executable() const; RunMode runMode() const; QString commandLineArguments() const; - QString dumperLibrary() const; - QStringList dumperLibraryLocations() const; QString workingDirectory() const; QtSupport::BaseQtVersion *qtVersion() const; diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp index e656693009..1af4919e44 100644 --- a/src/plugins/qtsupport/baseqtversion.cpp +++ b/src/plugins/qtsupport/baseqtversion.cpp @@ -41,7 +41,6 @@ #include <projectexplorer/toolchain.h> #include <projectexplorer/projectexplorer.h> #include <projectexplorer/headerpath.h> -#include <qtsupport/debugginghelper.h> #include <qtsupport/debugginghelperbuildtask.h> #include <qtsupport/qtsupportconstants.h> @@ -137,7 +136,6 @@ int BaseQtVersion::getUniqueId() BaseQtVersion::BaseQtVersion(const FileName &qmakeCommand, bool isAutodetected, const QString &autodetectionSource) : m_id(getUniqueId()), m_isAutodetected(isAutodetected), - m_hasDebuggingHelper(false), m_hasQmlDump(false), m_mkspecUpToDate(false), m_mkspecReadUpToDate(false), @@ -158,7 +156,6 @@ BaseQtVersion::BaseQtVersion(const FileName &qmakeCommand, bool isAutodetected, BaseQtVersion::BaseQtVersion() : m_id(-1), m_isAutodetected(false), - m_hasDebuggingHelper(false), m_hasQmlDump(false), m_mkspecUpToDate(false), m_mkspecReadUpToDate(false), @@ -911,7 +908,6 @@ void BaseQtVersion::updateVersionInfo() const m_installed = true; m_hasExamples = false; m_hasDocumentation = false; - m_hasDebuggingHelper = false; m_hasQmlDump = false; if (!queryQMakeVariables(qmakeCommand(), qmakeRunEnvironment(), &m_versionInfo)) { @@ -927,7 +923,6 @@ void BaseQtVersion::updateVersionInfo() const const QString qtHeaderData = qmakeProperty(m_versionInfo, "QT_INSTALL_HEADERS"); if (!qtInstallData.isNull()) { if (!qtInstallData.isEmpty()) { - m_hasDebuggingHelper = !DebuggingHelperLibrary::debuggingHelperLibraryByInstallData(qtInstallData).isEmpty(); m_hasQmlDump = !QmlDumpTool::toolForQtPaths(qtInstallData, qtInstallBins, qtHeaderData, false).isEmpty() || !QmlDumpTool::toolForQtPaths(qtInstallData, qtInstallBins, qtHeaderData, true).isEmpty(); @@ -1072,13 +1067,6 @@ Environment BaseQtVersion::qmakeRunEnvironment() const return Environment::systemEnvironment(); } -bool BaseQtVersion::hasGdbDebuggingHelper() const -{ - updateVersionInfo(); - return m_hasDebuggingHelper; -} - - bool BaseQtVersion::hasQmlDump() const { updateVersionInfo(); @@ -1114,14 +1102,6 @@ Environment BaseQtVersion::qmlToolsEnvironment() const return environment; } -QString BaseQtVersion::gdbDebuggingHelperLibrary() const -{ - QString qtInstallData = qmakeProperty("QT_INSTALL_DATA"); - if (qtInstallData.isEmpty()) - return QString(); - return DebuggingHelperLibrary::debuggingHelperLibraryByInstallData(qtInstallData); -} - QString BaseQtVersion::qmlDumpTool(bool debugVersion) const { const QString qtInstallData = qmakeProperty("QT_INSTALL_DATA"); @@ -1132,21 +1112,6 @@ QString BaseQtVersion::qmlDumpTool(bool debugVersion) const return QmlDumpTool::toolForQtPaths(qtInstallData, qtInstallBins, qtHeaderData, debugVersion); } -QStringList BaseQtVersion::debuggingHelperLibraryLocations() const -{ - QString qtInstallData = qmakeProperty("QT_INSTALL_DATA"); - if (qtInstallData.isEmpty()) - return QStringList(); - return DebuggingHelperLibrary::debuggingHelperLibraryDirectories(qtInstallData); -} - -bool BaseQtVersion::supportsBinaryDebuggingHelper() const -{ - if (!isValid()) - return false; - return true; -} - void BaseQtVersion::recheckDumper() { m_versionInfoUpToDate = false; diff --git a/src/plugins/qtsupport/baseqtversion.h b/src/plugins/qtsupport/baseqtversion.h index 5b382c2d69..4322d0d05b 100644 --- a/src/plugins/qtsupport/baseqtversion.h +++ b/src/plugins/qtsupport/baseqtversion.h @@ -191,12 +191,8 @@ public: static void buildDebuggingHelper(ProjectExplorer::Kit *k, int tools); void buildDebuggingHelper(ProjectExplorer::ToolChain *tc, int tools); - virtual bool supportsBinaryDebuggingHelper() const; - virtual QString gdbDebuggingHelperLibrary() const; virtual QString qmlDumpTool(bool debugVersion) const; - virtual QStringList debuggingHelperLibraryLocations() const; - virtual bool hasGdbDebuggingHelper() const; virtual bool hasQmlDump() const; virtual bool hasQmlDumpWithRelocatableFlag() const; virtual bool needsQmlDump() const; @@ -263,7 +259,6 @@ private: int m_id; bool m_isAutodetected; - mutable bool m_hasDebuggingHelper; // controlled by m_versionInfoUpToDate mutable bool m_hasQmlDump; // controlled by m_versionInfoUpToDate mutable bool m_mkspecUpToDate; mutable bool m_mkspecReadUpToDate; diff --git a/src/plugins/qtsupport/customexecutablerunconfiguration.cpp b/src/plugins/qtsupport/customexecutablerunconfiguration.cpp index 617f1f32a3..42590f66bc 100644 --- a/src/plugins/qtsupport/customexecutablerunconfiguration.cpp +++ b/src/plugins/qtsupport/customexecutablerunconfiguration.cpp @@ -300,16 +300,6 @@ QWidget *CustomExecutableRunConfiguration::createConfigurationWidget() return new CustomExecutableConfigurationWidget(this); } -QString CustomExecutableRunConfiguration::dumperLibrary() const -{ - return QtKitInformation::dumperLibrary(target()->kit()); -} - -QStringList CustomExecutableRunConfiguration::dumperLibraryLocations() const -{ - return QtKitInformation::dumperLibraryLocations(target()->kit()); -} - ProjectExplorer::Abi CustomExecutableRunConfiguration::abi() const { return ProjectExplorer::Abi(); // return an invalid ABI: We do not know what we will end up running! diff --git a/src/plugins/qtsupport/customexecutablerunconfiguration.h b/src/plugins/qtsupport/customexecutablerunconfiguration.h index 78d5acd27f..b94cad60b3 100644 --- a/src/plugins/qtsupport/customexecutablerunconfiguration.h +++ b/src/plugins/qtsupport/customexecutablerunconfiguration.h @@ -69,8 +69,6 @@ public: QString commandLineArguments() const; QWidget *createConfigurationWidget(); - QString dumperLibrary() const; - QStringList dumperLibraryLocations() const; ProjectExplorer::Abi abi() const; diff --git a/src/plugins/qtsupport/debugginghelper.cpp b/src/plugins/qtsupport/debugginghelper.cpp deleted file mode 100644 index 442b59cf88..0000000000 --- a/src/plugins/qtsupport/debugginghelper.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#include "debugginghelper.h" - -#include <coreplugin/icore.h> - -#include <QCoreApplication> -#include <QDir> -#include <QStringList> - -#include <QDesktopServices> - -using namespace QtSupport; - -static inline QStringList validBinaryFilenames() -{ - return QStringList() - << QLatin1String("debug/dumper.dll") - << QLatin1String("libdumper.dylib") - << QLatin1String("libdumper.so"); -} - -QStringList DebuggingHelperLibrary::debuggingHelperLibraryDirectories(const QString &qtInstallData) -{ - const QChar slash = QLatin1Char('/'); - const uint hash = qHash(qtInstallData); - QStringList directories; - directories - << (qtInstallData + QLatin1String("/qtc-debugging-helper/")) - << QDir::cleanPath((QCoreApplication::applicationDirPath() + QLatin1String("/../qtc-debugging-helper/") + QString::number(hash))) + slash - << (QDesktopServices::storageLocation(QDesktopServices::DataLocation) + QLatin1String("/qtc-debugging-helper/") + QString::number(hash)) + slash; - return directories; -} - -static QString sourcePath() -{ - return Core::ICore::resourcePath() + QLatin1String("/debugger/"); -} - -static QStringList sourceFileNames() -{ - return QStringList() - << QLatin1String("dumper.cpp") << QLatin1String("dumper_p.h") - << QLatin1String("dumper.h") << QLatin1String("dumper.pro") - << QLatin1String("LICENSE.LGPL") << QLatin1String("LGPL_EXCEPTION.TXT"); -} - -QString DebuggingHelperLibrary::debuggingHelperLibraryByInstallData(const QString &qtInstallData) -{ - if (!Core::ICore::instance()) - return QString(); - - const QStringList directories = DebuggingHelperLibrary::debuggingHelperLibraryDirectories(qtInstallData); - const QStringList binFilenames = validBinaryFilenames(); - - return byInstallDataHelper(sourcePath(), sourceFileNames(), directories, binFilenames, false); -} - -QString DebuggingHelperLibrary::copy(const QString &qtInstallData, - QString *errorMessage) -{ - // Locations to try: - // $QTDIR/qtc-debugging-helper - // $APPLICATION-DIR/qtc-debugging-helper/$hash - // $USERDIR/qtc-debugging-helper/$hash - const QStringList directories = DebuggingHelperLibrary::debuggingHelperLibraryDirectories(qtInstallData); - - // Try to find a writeable directory. - foreach (const QString &directory, directories) - if (copyFiles(sourcePath(), sourceFileNames(), directory, errorMessage)) { - errorMessage->clear(); - return directory; - } - *errorMessage = QCoreApplication::translate("ProjectExplorer::DebuggingHelperLibrary", - "The debugger helpers could not be built in any of the directories:\n- %1\n\nReason: %2") - .arg(directories.join(QLatin1String("\n- ")), *errorMessage); - return QString(); -} - -bool DebuggingHelperLibrary::build(BuildHelperArguments arguments, QString *log, QString *errorMessage) -{ - arguments.proFilename = QLatin1String("dumper.pro"); - arguments.helperName = QCoreApplication::translate("ProjectExplorer::DebuggingHelperLibrary", - "GDB helper"); - return buildHelper(arguments, log, errorMessage); -} diff --git a/src/plugins/qtsupport/debugginghelper.h b/src/plugins/qtsupport/debugginghelper.h deleted file mode 100644 index b7df8ce640..0000000000 --- a/src/plugins/qtsupport/debugginghelper.h +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -****************************************************************************/ - -#ifndef DEBUGGINGHELPER_H -#define DEBUGGINGHELPER_H - -#include "qtsupport_global.h" - -#include <utils/buildablehelperlibrary.h> - -#include <QString> - -QT_FORWARD_DECLARE_CLASS(QStringList) - -namespace QtSupport { - -class QTSUPPORT_EXPORT DebuggingHelperLibrary : public Utils::BuildableHelperLibrary -{ -public: - static QString debuggingHelperLibraryByInstallData(const QString &qtInstallData); - static QStringList debuggingHelperLibraryDirectories(const QString &qtInstallData); - - // Build the helpers and return the output log/errormessage. - static bool build(BuildHelperArguments arguments, QString *log, QString *errorMessage); - - // Copy the source files to a target location and return the chosen target location. - static QString copy(const QString &qtInstallData, QString *errorMessage); - -}; -} // namespace QtSupport - -#endif // DEBUGGINGHELPER_H diff --git a/src/plugins/qtsupport/debugginghelper.ui b/src/plugins/qtsupport/debugginghelper.ui index cd7dba4e4b..87f7a168c1 100644 --- a/src/plugins/qtsupport/debugginghelper.ui +++ b/src/plugins/qtsupport/debugginghelper.ui @@ -42,13 +42,6 @@ </property> </widget> </item> - <item row="2" column="2"> - <widget class="QPushButton" name="gdbHelperBuildButton"> - <property name="text"> - <string>Build</string> - </property> - </widget> - </item> <item row="1" column="1"> <widget class="QLabel" name="qmlDumpStatus"> <property name="sizePolicy"> @@ -62,29 +55,6 @@ </property> </widget> </item> - <item row="2" column="0"> - <widget class="QLabel" name="gdbHelperLabel"> - <property name="toolTip"> - <string>Helps showing content of Qt types. Only used in older versions of GDB.</string> - </property> - <property name="text"> - <string>GDB Helper:</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QLabel" name="gdbHelperStatus"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>2</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string notr="true">TextLabel</string> - </property> - </widget> - </item> </layout> </item> <item> diff --git a/src/plugins/qtsupport/debugginghelperbuildtask.cpp b/src/plugins/qtsupport/debugginghelperbuildtask.cpp index 090806562c..d361b0a021 100644 --- a/src/plugins/qtsupport/debugginghelperbuildtask.cpp +++ b/src/plugins/qtsupport/debugginghelperbuildtask.cpp @@ -28,7 +28,6 @@ ****************************************************************************/ #include "debugginghelperbuildtask.h" -#include "debugginghelper.h" #include "qmldumptool.h" #include "baseqtversion.h" #include "qtversionmanager.h" @@ -117,13 +116,6 @@ DebuggingHelperBuildTask::Tools DebuggingHelperBuildTask::availableTools(const B QTC_ASSERT(version, return 0); // Check the build requirements of the tools DebuggingHelperBuildTask::Tools tools = 0; - // Gdb helpers are needed on Mac/gdb only. - foreach (const Abi &abi, version->qtAbis()) { - if (abi.os() == Abi::MacOS) { - tools |= DebuggingHelperBuildTask::GdbDebugging; - break; - } - } if (QmlDumpTool::canBuild(version)) tools |= QmlDump; return tools; @@ -169,18 +161,6 @@ bool DebuggingHelperBuildTask::buildDebuggingHelper(QFutureInterface<void> &futu arguments.mkspec = m_mkspec; arguments.environment = m_environment; - if (m_tools & GdbDebugging) { - QString output, error; - bool success = true; - - arguments.directory = DebuggingHelperLibrary::copy(m_qtInstallData, &error); - if (arguments.directory.isEmpty() - || !DebuggingHelperLibrary::build(arguments, &output, &error)) - success = false; - log(output, error); - if (!success) - return false; - } future.setProgressValue(2); if (m_tools & QmlDump) { diff --git a/src/plugins/qtsupport/debugginghelperbuildtask.h b/src/plugins/qtsupport/debugginghelperbuildtask.h index dc767cf0cf..e45371d7a6 100644 --- a/src/plugins/qtsupport/debugginghelperbuildtask.h +++ b/src/plugins/qtsupport/debugginghelperbuildtask.h @@ -50,9 +50,8 @@ class QTSUPPORT_EXPORT DebuggingHelperBuildTask : public QObject public: enum DebuggingHelper { - GdbDebugging = 0x01, QmlDump = 0x02, - AllTools = GdbDebugging | QmlDump + AllTools = QmlDump }; Q_DECLARE_FLAGS(Tools, DebuggingHelper) diff --git a/src/plugins/qtsupport/qtkitinformation.cpp b/src/plugins/qtsupport/qtkitinformation.cpp index b630ec79e8..fc9116aef4 100644 --- a/src/plugins/qtsupport/qtkitinformation.cpp +++ b/src/plugins/qtsupport/qtkitinformation.cpp @@ -172,22 +172,6 @@ void QtKitInformation::setQtVersion(ProjectExplorer::Kit *k, const BaseQtVersion setQtVersionId(k, v->uniqueId()); } -QString QtKitInformation::dumperLibrary(const ProjectExplorer::Kit *k) -{ - BaseQtVersion *version = QtKitInformation::qtVersion(k); - if (version) - return version->gdbDebuggingHelperLibrary(); - return QString(); -} - -QStringList QtKitInformation::dumperLibraryLocations(const ProjectExplorer::Kit *k) -{ - BaseQtVersion *version = QtKitInformation::qtVersion(k); - if (version) - return version->debuggingHelperLibraryLocations(); - return QStringList(); -} - void QtKitInformation::qtVersionsChanged(const QList<int> &addedIds, const QList<int> &removedIds, const QList<int> &changedIds) diff --git a/src/plugins/qtsupport/qtkitinformation.h b/src/plugins/qtsupport/qtkitinformation.h index a8f1503b60..de5314d2f3 100644 --- a/src/plugins/qtsupport/qtkitinformation.h +++ b/src/plugins/qtsupport/qtkitinformation.h @@ -66,11 +66,6 @@ public: static BaseQtVersion *qtVersion(const ProjectExplorer::Kit *k); static void setQtVersion(ProjectExplorer::Kit *k, const BaseQtVersion *v); - // Information derived from the Qt version: - // FIXME: This should be part of an RunConfigurationAspect... - static QString dumperLibrary(const ProjectExplorer::Kit *k); - static QStringList dumperLibraryLocations(const ProjectExplorer::Kit *k); - private slots: void qtVersionsChanged(const QList<int> &addedIds, const QList<int> &removedIds, diff --git a/src/plugins/qtsupport/qtoptionspage.cpp b/src/plugins/qtsupport/qtoptionspage.cpp index e993f3c8fe..e610bd5620 100644 --- a/src/plugins/qtsupport/qtoptionspage.cpp +++ b/src/plugins/qtsupport/qtoptionspage.cpp @@ -172,8 +172,6 @@ QtOptionsPageWidget::QtOptionsPageWidget(QWidget *parent) connect(m_debuggingHelperUi->rebuildButton, SIGNAL(clicked()), this, SLOT(buildDebuggingHelper())); - connect(m_debuggingHelperUi->gdbHelperBuildButton, SIGNAL(clicked()), - this, SLOT(buildGdbHelper())); connect(m_debuggingHelperUi->qmlDumpBuildButton, SIGNAL(clicked()), this, SLOT(buildQmlDump())); @@ -239,8 +237,6 @@ void QtOptionsPageWidget::debuggingHelperBuildFinished(int qtVersionId, const QS item->setData(0, BuildLogRole, output); bool success = true; - if (tools & DebuggingHelperBuildTask::GdbDebugging) - success &= version->hasGdbDebuggingHelper(); if (tools & DebuggingHelperBuildTask::QmlDump) success &= version->hasQmlDump(); @@ -449,10 +445,6 @@ void QtOptionsPageWidget::buildDebuggingHelper(DebuggingHelperBuildTask::Tools t Core::ProgressManager::addTask(task, taskName, "QmakeProjectManager::BuildHelpers"); } -void QtOptionsPageWidget::buildGdbHelper() -{ - buildDebuggingHelper(DebuggingHelperBuildTask::GdbDebugging); -} void QtOptionsPageWidget::buildQmlDump() { @@ -715,28 +707,22 @@ void QtOptionsPageWidget::updateDebuggingHelperUi() m_ui->debuggingHelperWidget->setVisible(false); } else { const DebuggingHelperBuildTask::Tools availableTools = DebuggingHelperBuildTask::availableTools(version); - const bool canBuildGdbHelper = availableTools & DebuggingHelperBuildTask::GdbDebugging; const bool canBuildQmlDumper = availableTools & DebuggingHelperBuildTask::QmlDump; - const bool hasGdbHelper = !version->gdbDebuggingHelperLibrary().isEmpty(); const bool hasQmlDumper = version->hasQmlDump(); const bool needsQmlDumper = version->needsQmlDump(); - bool isBuildingGdbHelper = false; bool isBuildingQmlDumper = false; if (currentItem) { DebuggingHelperBuildTask::Tools buildingTools = currentItem->data(0, BuildRunningRole).value<DebuggingHelperBuildTask::Tools>(); - isBuildingGdbHelper = buildingTools & DebuggingHelperBuildTask::GdbDebugging; isBuildingQmlDumper = buildingTools & DebuggingHelperBuildTask::QmlDump; } // get names of tools from labels QStringList helperNames; const QChar colon = QLatin1Char(':'); - if (hasGdbHelper) - helperNames << m_debuggingHelperUi->gdbHelperLabel->text().remove(colon); if (hasQmlDumper) helperNames << m_debuggingHelperUi->qmlDumpLabel->text().remove(colon); @@ -750,21 +736,6 @@ void QtOptionsPageWidget::updateDebuggingHelperUi() m_ui->debuggingHelperWidget->setSummaryText(status); - QString gdbHelperText; - Qt::TextInteractionFlags gdbHelperTextFlags = Qt::NoTextInteraction; - if (hasGdbHelper) { - gdbHelperText = QDir::toNativeSeparators(version->gdbDebuggingHelperLibrary()); - gdbHelperTextFlags = Qt::TextSelectableByMouse; - } else { - if (canBuildGdbHelper) - gdbHelperText = tr("<i>Not yet built.</i>"); - else - gdbHelperText = tr("<i>Not needed.</i>"); - } - m_debuggingHelperUi->gdbHelperStatus->setText(gdbHelperText); - m_debuggingHelperUi->gdbHelperStatus->setTextInteractionFlags(gdbHelperTextFlags); - m_debuggingHelperUi->gdbHelperBuildButton->setEnabled(canBuildGdbHelper && !isBuildingGdbHelper); - QString qmlDumpStatusText, qmlDumpStatusToolTip; Qt::TextInteractionFlags qmlDumpStatusTextFlags = Qt::NoTextInteraction; if (hasQmlDumper) { @@ -809,10 +780,8 @@ void QtOptionsPageWidget::updateDebuggingHelperUi() const bool hasLog = currentItem && !currentItem->data(0, BuildLogRole).toString().isEmpty(); m_debuggingHelperUi->showLogButton->setEnabled(hasLog); - const bool canBuild = canBuildGdbHelper - || canBuildQmlDumper; - const bool isBuilding = isBuildingGdbHelper - || isBuildingQmlDumper; + const bool canBuild = canBuildQmlDumper; + const bool isBuilding = isBuildingQmlDumper; m_debuggingHelperUi->rebuildButton->setEnabled(canBuild && !isBuilding); m_debuggingHelperUi->toolChainComboBox->setEnabled(canBuild && !isBuilding); diff --git a/src/plugins/qtsupport/qtoptionspage.h b/src/plugins/qtsupport/qtoptionspage.h index 80a740a43d..7a4a8de0b4 100644 --- a/src/plugins/qtsupport/qtoptionspage.h +++ b/src/plugins/qtsupport/qtoptionspage.h @@ -106,7 +106,6 @@ private slots: void updateCurrentQtName(); void buildDebuggingHelper(DebuggingHelperBuildTask::Tools tools = DebuggingHelperBuildTask::AllTools); - void buildGdbHelper(); void buildQmlDump(); void slotShowDebuggingBuildLog(); void debuggingHelperBuildFinished(int qtVersionId, const QString &output, diff --git a/src/plugins/qtsupport/qtsupport.pro b/src/plugins/qtsupport/qtsupport.pro index df7fe51a81..dcea5b3330 100644 --- a/src/plugins/qtsupport/qtsupport.pro +++ b/src/plugins/qtsupport/qtsupport.pro @@ -20,7 +20,6 @@ HEADERS += \ qtoptionspage.h \ customexecutablerunconfiguration.h \ customexecutableconfigurationwidget.h \ - debugginghelper.h \ debugginghelperbuildtask.h \ qtsupportconstants.h \ profilereader.h \ @@ -49,7 +48,6 @@ SOURCES += \ qtoptionspage.cpp \ customexecutablerunconfiguration.cpp \ customexecutableconfigurationwidget.cpp \ - debugginghelper.cpp \ debugginghelperbuildtask.cpp \ profilereader.cpp \ qtparser.cpp \ diff --git a/src/plugins/qtsupport/qtsupport.qbs b/src/plugins/qtsupport/qtsupport.qbs index 72f0597a6a..dc9060481a 100644 --- a/src/plugins/qtsupport/qtsupport.qbs +++ b/src/plugins/qtsupport/qtsupport.qbs @@ -65,8 +65,6 @@ QtcPlugin { "customexecutableconfigurationwidget.h", "customexecutablerunconfiguration.cpp", "customexecutablerunconfiguration.h", - "debugginghelper.cpp", - "debugginghelper.h", "debugginghelper.ui", "debugginghelperbuildtask.cpp", "debugginghelperbuildtask.h", diff --git a/src/plugins/qtsupport/qtversionmanager.cpp b/src/plugins/qtsupport/qtversionmanager.cpp index 136a78b4f0..df5067711e 100644 --- a/src/plugins/qtsupport/qtversionmanager.cpp +++ b/src/plugins/qtsupport/qtversionmanager.cpp @@ -35,13 +35,12 @@ #include "qtfeatureprovider.h" #include "qtsupportconstants.h" -#include <qtsupport/debugginghelper.h> - #include <coreplugin/icore.h> #include <coreplugin/helpmanager.h> #include <extensionsystem/pluginmanager.h> +#include <utils/buildablehelperlibrary.h> #include <utils/filesystemwatcher.h> #include <utils/hostosinfo.h> #include <utils/persistentsettings.h> @@ -386,7 +385,7 @@ void QtVersionManager::saveQtVersions() void QtVersionManager::findSystemQt() { - FileName systemQMakePath = QtSupport::DebuggingHelperLibrary::findSystemQt(Environment::systemEnvironment()); + FileName systemQMakePath = BuildableHelperLibrary::findSystemQt(Environment::systemEnvironment()); if (systemQMakePath.isNull()) return; |
