Commit bad8a451 authored by hjk's avatar hjk

Debugger: Remove support for non-Python GDB

This affects mainly Apple's version of GDB. Mac users are advised to
use LLDB, or some recent build of FSF GDB.

Change-Id: I6a7fbb591e79f737e12d08b0e881e9e4d1d9660c
Reviewed-by: default avatarFriedemann Kleint <Friedemann.Kleint@digia.com>
parent fd2e00f6
This source diff could not be displayed because it is too large. You can view the blob instead.
/****************************************************************************
**
** 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 DUMPER_H
#define DUMPER_H
#ifdef MACROSDEBUG
Q_DECL_EXPORT extern char xDumpInBuffer[];
Q_DECL_EXPORT extern char xDumpOutBuffer[];
#else
Q_DECL_EXPORT extern char qDumpInBuffer[];
Q_DECL_EXPORT extern char qDumpOutBuffer[];
#endif
extern "C" Q_DECL_EXPORT
void *qDumpObjectData440(int protocolVersion, int token, const void *data,
int dumpChildren, int extraInt0, int extraInt1, int extraInt2, int extraInt3);
#endif // DUMPER_H
TEMPLATE = lib
CONFIG += shared
linux-* {
CONFIG -= release
CONFIG += debug
}
HEADERS += dumper.h
SOURCES = dumper.cpp
false {
DEFINES += USE_QT_GUI=0
DEFINES += USE_QT_CORE=0
QT=
# We need a few convenience macros.
#CONFIG -= qt
}
false {
DEFINES += USE_QT_CORE=1
DEFINES += USE_QT_GUI=0
QT = core
exists($$QMAKE_INCDIR_QT/QtCore/private/qobject_p.h):DEFINES += HAS_QOBJECT_P_H
}
true {
DEFINES += USE_QT_CORE=1
DEFINES += USE_QT_GUI=1
QT = core gui
greaterThan(QT_MAJOR_VERSION, 4):QT *= widgets
exists($$QMAKE_INCDIR_QT/QtCore/private/qobject_p.h):DEFINES += HAS_QOBJECT_P_H
}
/****************************************************************************
**
** 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 DUMPER_P_H
#define DUMPER_P_H
#include <QObject>
#include <QPointer>
#ifndef QT_BOOTSTRAPPED
#undef NS
#ifdef QT_NAMESPACE
# define STRINGIFY0(s) #s
# define STRINGIFY1(s) STRINGIFY0(s)
# define NS STRINGIFY1(QT_NAMESPACE) "::"
# define NSX "'" STRINGIFY1(QT_NAMESPACE) "::"
# define NSY "'"
#else
# define NS ""
# define NSX "'"
# define NSY "'"
#endif
#if defined(QT_BEGIN_NAMESPACE)
QT_BEGIN_NAMESPACE
#endif
struct Sender { QObject *sender; int signal; int ref; };
#if QT_VERSION < 0x040600
struct Connection
{
QObject *receiver;
int method;
uint connectionType : 3; // 0 == auto, 1 == direct, 2 == queued, 4 == blocking
QBasicAtomicPointer<int> argumentTypes;
int method_() const { return method; }
};
#elif QT_VERSION < 0x040800
struct Connection
{
QObject *sender;
QObject *receiver;
int method;
uint connectionType : 3; // 0 == auto, 1 == direct, 2 == queued, 4 == blocking
QBasicAtomicPointer<int> argumentTypes;
Connection *nextConnectionList;
//senders linked list
Connection *next;
Connection **prev;
int method_() const { return method; }
};
#else
typedef void (*StaticMetaCallFunction)(QObject *, QMetaObject::Call, int, void **);
struct Connection
{
QObject *sender;
QObject *receiver;
StaticMetaCallFunction callFunction;
// The next pointer for the singly-linked ConnectionList
Connection *nextConnectionList;
//senders linked list
Connection *next;
Connection **prev;
QBasicAtomicPointer<int> argumentTypes;
ushort method_offset;
ushort method_relative;
ushort connectionType : 3; // 0 == auto, 1 == direct, 2 == queued, 4 == blocking
~Connection();
int method() const { return method_offset + method_relative; }
int method_() const { return method(); }
};
#endif
#if QT_VERSION < 0x040600
typedef QList<Connection> ConnectionList;
typedef QList<Sender> SenderList;
static inline const Connection &connectionAt(const ConnectionList &l, int i)
{
return l.at(i);
}
static inline const QObject *senderAt(const SenderList &l, int i)
{
return l.at(i).sender;
}
static inline int signalAt(const SenderList &l, int i)
{
return l.at(i).signal;
}
//#elif QT_VERSION < 0x040800
#else
struct ConnectionList
{
ConnectionList() : first(0), last(0) { }
int size() const
{
int count = 0;
for (Connection *c = first; c != 0; c = c->nextConnectionList)
++count;
return count;
}
Connection *first;
Connection *last;
};
typedef Connection *SenderList;
static inline const Connection &connectionAt(const ConnectionList &l, int i)
{
Connection *conn = l.first;
for (int cnt = 0; cnt < i; ++cnt)
conn = conn->nextConnectionList;
return *conn;
}
#endif
class ObjectPrivate : public QObjectData
{
public:
ObjectPrivate() {}
virtual ~ObjectPrivate() {}
#if QT_VERSION < 0x040600
QList<QObject *> pendingChildInsertedEvents;
void *threadData;
void *currentSender;
void *currentChildBeingDeleted;
QList<QPointer<QObject> > eventFilters;
void *extraData;
mutable quint32 connectedSignals;
QString objectName;
void *connectionLists;
SenderList senders;
int *deleteWatch;
#elif QT_VERSION < 0x040800
QString objectName;
void *extraData;
void *threadData;
void *connectionLists;
SenderList senders;
void *currentSender;
mutable quint32 connectedSignals[2];
QList<QObject *> pendingChildInsertedEvents;
QList<QPointer<QObject> > eventFilters;
void *currentChildBeingDeleted;
QAtomicPointer<void> sharedRefcount;
int *deleteWatch;
#else
QString objectName;
void *extraData;
void *threadData;
void *connectionLists;
Connection *senders;
Sender *currentSender;
mutable quint32 connectedSignals[2];
void *unused;
QList<QPointer<QObject> > eventFilters;
union {
QObject *currentChildBeingDeleted;
void *declarativeData;
};
QAtomicPointer<void> sharedRefcount;
#ifdef QT_JAMBI_BUILD
int *deleteWatch;
#endif
#endif
};
#endif // QT_BOOTSTRAPPED
#if defined(QT_BEGIN_NAMESPACE)
QT_END_NAMESPACE
#endif
#endif // DUMPER_P_H
#-------------------------------------------------
#
# Project created by QtCreator 2009-05-05T11:16:25
#
#-------------------------------------------------
TARGET = dumpertest
CONFIG += console
CONFIG -= app_bundle
greaterThan(QT_MAJOR_VERSION, 4):QT *= widgets
TEMPLATE = app
SOURCES += main.cpp \
../dumper.cpp
exists($$QMAKE_INCDIR_QT/QtCore/private/qobject_p.h) {
DEFINES+=HAS_QOBJECT_P_H
}
This diff is collapsed.
......@@ -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;
......
......@@ -59,7 +59,6 @@ public:
QString proFilePath() const;
const QString remoteChannel() const;
const QString dumperLib() const;
bool isEnabled() const;
QString disabledReason() const;
......
......@@ -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)
......
......@@ -70,9 +70,6 @@ public:
QString title() const;
QString dumperLibrary() const;
QStringList dumperLibraryLocations() const;
QVariantMap toMap() const;
void setEnabled(bool b);
......
......@@ -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"
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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;
......
# 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
......@@ -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
......
......@@ -50,8 +50,6 @@ public:
explicit GdbAttachEngine(const DebuggerStartParameters &startParameters);
private:
DumperHandling dumperHandling() const { return DumperLoadedByGdb; }
void setupEngine();
void setupInferior();
void runEngine();
......
This diff is collapsed.
......@@ -52,8 +52,6 @@ public:
~GdbCoreEngine();
private:
DumperHandling dumperHandling() const { return DumperNotAvailable; }
void setupEngine();
void setupInferior();
void runEngine();
......
......@@ -11,8 +11,6 @@ HEADERS += \
SOURCES += \
$$PWD/gdbengine.cpp \
$$PWD/classicgdbengine.cpp \
$$PWD/pythongdbengine.cpp \
$$PWD/gdboptionspage.cpp \
$$PWD/attachgdbadapter.cpp \
$$PWD/coregdbadapter.cpp \
......
This diff is collapsed.
This diff is collapsed.
......@@ -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());
......
......@@ -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;
......
/****************************************************************************
**
** 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 &params)
{
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();