include(gdb/gdb.pri)
include(script/script.pri)
include(pdb/pdb.pri)
+include(lldb/lldbhost.pri)
contains(QT_CONFIG, declarative) {
QT += declarative
PdbEngineType = 0x08,
TcfEngineType = 0x10,
QmlEngineType = 0x20,
- QmlCppEngineType = 0x40,
+ QmlCppEngineType = 0x40,
+ LLDBEngineType = 0x80,
AllEngineTypes = GdbEngineType
| ScriptEngineType
| CdbEngineType
| TcfEngineType
| QmlEngineType
| QmlCppEngineType
+ | LLDBEngineType
};
enum DebuggerLanguage
#include "gdb/remoteplaingdbadapter.h"
#include "qml/qmlengine.h"
#include "qml/qmlcppengine.h"
+#include "lldb/lldbenginehost.h"
#ifdef Q_OS_WIN
# include "peutils.h"
DebuggerEngine *createTcfEngine(const DebuggerStartParameters &);
DebuggerEngine *createQmlEngine(const DebuggerStartParameters &);
DebuggerEngine *createQmlCppEngine(const DebuggerStartParameters &);
+DebuggerEngine *createLLDBEngine(const DebuggerStartParameters &);
bool checkGdbConfiguration(int toolChain, QString *errorMsg, QString *settingsPage);
if (sp.processArgs.size() >= 5 && sp.processArgs.at(0) == _("@tcf@"))
engineType = GdbEngineType;
+ if (sp.processArgs.contains( _("@lldb@")))
+ engineType = LLDBEngineType;
+
if (engineType == NoEngineType
&& sp.startMode != AttachToRemote
&& !sp.executable.isEmpty())
if (Internal::GdbEngine *embeddedGdbEngine = gdbEngine())
initGdbEngine(embeddedGdbEngine);
break;
+ case LLDBEngineType:
+ d->m_engine = Internal::createLLDBEngine(sp);
case NoEngineType:
case AllEngineTypes:
break;
--- /dev/null
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "ipcengineguest.h"
+#include "ipcenginehost.h"
+#include "breakpoint.h"
+#include "stackframe.h"
+#include "threaddata.h"
+#include "debuggerstreamops.h"
+
+#include <QSysInfo>
+#include <QDebug>
+#include <QFileInfo>
+#include <QTimer>
+#include <utils/qtcassert.h>
+
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+#define SET_NATIVE_BYTE_ORDER(x) x.setByteOrder(QDataStream::LittleEndian)
+#else
+#define SET_NATIVE_BYTE_ORDER(x) x.setByteOrder(QDataStream::BigEndian)
+#endif
+
+namespace Debugger {
+namespace Internal {
+
+IPCEngineGuest::IPCEngineGuest()
+ : QObject()
+ , m_local_host(0)
+ , m_nextMessagePayloadSize(0)
+ , m_cookie(1)
+ , m_device(0)
+{
+}
+
+IPCEngineGuest::~IPCEngineGuest()
+{
+}
+
+void IPCEngineGuest::setLocalHost(IPCEngineHost * h)
+{
+ m_local_host = h;
+}
+
+void IPCEngineGuest::setHostDevice(QIODevice * d)
+{
+ if (m_device) {
+ disconnect(m_device, SIGNAL(readyRead()), this, SLOT(readyRead()));
+ delete m_device;
+ }
+ m_device = d;
+ if (m_device)
+ connect(m_device, SIGNAL(readyRead()), this, SLOT(readyRead()));
+}
+
+void IPCEngineGuest::rpcCall(IPCEngineGuest::Function f, QByteArray payload )
+{
+#if 0
+ if (m_local_host) {
+ QMetaObject::invokeMethod(m_local_host,
+ "rpcCallback",
+ Qt::QueuedConnection,
+ Q_ARG(quint64, f),
+ Q_ARG(QByteArray, payload));
+ } else
+#endif
+ if (m_device) {
+ {
+ QDataStream s(m_device);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << m_cookie++;
+ s << (quint64) f;
+ s << (quint64) payload.size();
+ }
+ m_device->write(payload);
+ m_device->putChar('T');
+ }
+}
+
+void IPCEngineGuest::readyRead()
+{
+ if (!m_nextMessagePayloadSize) {
+ if (quint64(m_device->bytesAvailable()) < (sizeof(quint64) * 3))
+ return;
+ QDataStream s(m_device);
+ SET_NATIVE_BYTE_ORDER(s);
+ s >> m_nextMessageCookie;
+ s >> m_nextMessageFunction;
+ s >> m_nextMessagePayloadSize;
+ m_nextMessagePayloadSize += 1; // terminator and "got header" marker
+ }
+
+ quint64 ba = m_device->bytesAvailable();
+ if (ba < m_nextMessagePayloadSize)
+ return;
+
+ qint64 rrr = (m_nextMessagePayloadSize);
+ QByteArray payload = m_device->read(rrr);
+ if (quint64(payload.size()) != m_nextMessagePayloadSize || !payload.endsWith('T')) {
+ showMessage(QLatin1String("IPC Error: corrupted frame"));
+ showMessage(tr("Fatal engine shutdown. Incompatible binary or ipc error."), LogError);
+ showStatusMessage(tr("Fatal engine shutdown. Incompatible binary or ipc error."));
+ notifyEngineIll();
+ return;
+ }
+ payload.chop(1);
+ rpcCallback(m_nextMessageFunction, payload);
+ m_nextMessagePayloadSize = 0;
+
+ if (quint64(m_device->bytesAvailable ()) >= (sizeof(quint64) * 3))
+ QTimer::singleShot(0, this, SLOT(readyRead()));
+}
+
+void IPCEngineGuest::rpcCallback(quint64 f, QByteArray payload )
+{
+ switch (f) {
+ default:
+ showMessage(QLatin1String("IPC Error: unhandled id in host to guest call"));
+ showMessage(tr("Fatal engine shutdown. Incompatible binary or ipc error."), LogError);
+ showStatusMessage(tr("Fatal engine shutdown. Incompatible binary or ipc error."));
+ notifyEngineIll();
+ break;
+ case IPCEngineHost::SetupIPC:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ int version;
+ s >> version;
+ Q_ASSERT(version == 1);
+ }
+ break;
+ case IPCEngineHost::StateChanged:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ quint64 st;
+ s >> st;
+ m_state = (DebuggerState)st;
+ }
+ break;
+ case IPCEngineHost::SetupEngine:
+ setupEngine();
+ break;
+ case IPCEngineHost::SetupInferior:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ QString executable;
+ QStringList arguments;
+ QStringList environment;
+ s >> executable;
+ s >> arguments;
+ s >> environment;
+ setupInferior(executable, arguments, environment);
+ }
+ break;
+ case IPCEngineHost::RunEngine:
+ runEngine();
+ break;
+ case IPCEngineHost::ShutdownInferior:
+ shutdownInferior();
+ break;
+ case IPCEngineHost::ShutdownEngine:
+ shutdownEngine();
+ break;
+ case IPCEngineHost::DetachDebugger:
+ detachDebugger();
+ break;
+ case IPCEngineHost::ExecuteStep:
+ executeStep();
+ break;
+ case IPCEngineHost::ExecuteStepOut:
+ executeStepOut();
+ break;
+ case IPCEngineHost::ExecuteNext:
+ executeNext();
+ break;
+ case IPCEngineHost::ExecuteStepI:
+ executeStepI();
+ break;
+ case IPCEngineHost::ExecuteNextI:
+ executeNextI();
+ break;
+ case IPCEngineHost::ContinueInferior:
+ continueInferior();
+ break;
+ case IPCEngineHost::InterruptInferior:
+ interruptInferior();
+ break;
+ case IPCEngineHost::ExecuteRunToLine:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ QString fileName;
+ quint64 lineNumber;
+ s >> fileName;
+ s >> lineNumber;
+ executeRunToLine(fileName, lineNumber);
+ }
+ break;
+ case IPCEngineHost::ExecuteRunToFunction:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ QString functionName;
+ s >> functionName;
+ executeRunToFunction(functionName);
+ }
+ break;
+ case IPCEngineHost::ExecuteJumpToLine:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ QString fileName;
+ quint64 lineNumber;
+ s >> fileName;
+ s >> lineNumber;
+ executeJumpToLine(fileName, lineNumber);
+ }
+ break;
+ case IPCEngineHost::ActivateFrame:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ quint64 id;
+ s >> id;
+ activateFrame(id);
+ }
+ break;
+ case IPCEngineHost::SelectThread:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ quint64 id;
+ s >> id;
+ selectThread(id);
+ }
+ break;
+ case IPCEngineHost::Disassemble:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ quint64 pc;
+ s >> pc;
+ disassemble(pc);
+ }
+ break;
+ case IPCEngineHost::AddBreakpoint:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ BreakpointData d;
+ s >> d;
+ addBreakpoint(d);
+ }
+ break;
+ case IPCEngineHost::RemoveBreakpoint:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ quint64 token;
+ s >> token;
+ removeBreakpoint(token);
+ }
+ break;
+ case IPCEngineHost::ChangeBreakpoint:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ BreakpointData d;
+ s >> d;
+ changeBreakpoint(d);
+ }
+ break;
+ case IPCEngineHost::RequestUpdateWatchData:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ WatchData data;
+ s >> data;
+ requestUpdateWatchData(data);
+ }
+ break;
+ };
+}
+
+DebuggerState IPCEngineGuest::state() const
+{
+ return m_state;
+}
+
+void IPCEngineGuest::notifyEngineSetupOk()
+{
+ rpcCall(NotifyEngineSetupOk);
+}
+
+void IPCEngineGuest::notifyEngineSetupFailed()
+{
+ rpcCall(NotifyEngineSetupFailed);
+}
+
+void IPCEngineGuest::notifyEngineRunFailed()
+{
+ rpcCall(NotifyEngineRunFailed);
+}
+
+void IPCEngineGuest::notifyInferiorSetupOk()
+{
+ rpcCall(NotifyInferiorSetupOk);
+}
+
+void IPCEngineGuest::notifyInferiorSetupFailed()
+{
+ rpcCall(NotifyInferiorSetupFailed);
+}
+
+void IPCEngineGuest::notifyEngineRunAndInferiorRunOk()
+{
+ rpcCall(NotifyEngineRunAndInferiorRunOk);
+}
+
+void IPCEngineGuest::notifyEngineRunAndInferiorStopOk()
+{
+ rpcCall(NotifyEngineRunAndInferiorStopOk);
+}
+
+void IPCEngineGuest::notifyInferiorRunRequested()
+{
+ rpcCall(NotifyInferiorRunRequested);
+}
+
+void IPCEngineGuest::notifyInferiorRunOk()
+{
+ rpcCall(NotifyInferiorRunOk);
+}
+
+void IPCEngineGuest::notifyInferiorRunFailed()
+{
+ rpcCall(NotifyInferiorRunFailed);
+}
+
+void IPCEngineGuest::notifyInferiorStopOk()
+{
+ rpcCall(NotifyInferiorStopOk);
+}
+
+void IPCEngineGuest::notifyInferiorSpontaneousStop()
+{
+ rpcCall(NotifyInferiorSpontaneousStop);
+}
+
+void IPCEngineGuest::notifyInferiorStopFailed()
+{
+ rpcCall(NotifyInferiorStopFailed);
+}
+
+void IPCEngineGuest::notifyInferiorExited()
+{
+ rpcCall(NotifyInferiorExited);
+}
+
+void IPCEngineGuest::notifyInferiorShutdownOk()
+{
+ rpcCall(NotifyInferiorShutdownOk);
+}
+
+void IPCEngineGuest::notifyInferiorShutdownFailed()
+{
+ rpcCall(NotifyInferiorShutdownFailed);
+}
+
+void IPCEngineGuest::notifyEngineSpontaneousShutdown()
+{
+ rpcCall(NotifyEngineSpontaneousShutdown);
+}
+
+void IPCEngineGuest::notifyEngineShutdownOk()
+{
+ rpcCall(NotifyEngineShutdownOk);
+}
+
+void IPCEngineGuest::notifyEngineShutdownFailed()
+{
+ rpcCall(NotifyEngineShutdownFailed);
+}
+
+void IPCEngineGuest::notifyInferiorIll()
+{
+ rpcCall(NotifyInferiorIll);
+}
+
+void IPCEngineGuest::notifyEngineIll()
+{
+ rpcCall(NotifyEngineIll);
+}
+
+void IPCEngineGuest::notifyInferiorPid(qint64 pid)
+{
+ QByteArray p;
+ {
+ QDataStream s(&p, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << pid;
+ }
+ rpcCall(NotifyInferiorPid, p);
+}
+
+void IPCEngineGuest::showStatusMessage(const QString &msg, quint64 timeout)
+{
+ QByteArray p;
+ {
+ QDataStream s(&p, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << msg;
+ s << (qint64)timeout;
+ }
+ rpcCall(ShowStatusMessage, p);
+}
+
+void IPCEngineGuest::showMessage(const QString &msg, quint16 channel, quint64 timeout)
+{
+ QByteArray p;
+ {
+ QDataStream s(&p, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << msg;
+ s << (qint64)channel;
+ s << (qint64)timeout;
+ }
+ rpcCall(ShowMessage, p);
+}
+
+void IPCEngineGuest::currentFrameChanged(qint64 osid)
+{
+ QByteArray p;
+ {
+ QDataStream s(&p, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << osid;
+ }
+ rpcCall(CurrentFrameChanged, p);
+}
+
+void IPCEngineGuest::currentThreadChanged(qint64 osid)
+{
+ QByteArray p;
+ {
+ QDataStream s(&p, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << osid;
+ }
+ rpcCall(CurrentThreadChanged, p);
+}
+
+void IPCEngineGuest::listFrames(const StackFrames &frames)
+{
+ QByteArray p;
+ {
+ QDataStream s(&p, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << frames;
+ }
+ rpcCall(ListFrames, p);
+}
+
+void IPCEngineGuest::listThreads(const Threads &threads)
+{
+ QByteArray p;
+ {
+ QDataStream s(&p, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << threads;
+ }
+ rpcCall(ListThreads, p);
+}
+
+void IPCEngineGuest::disassembled(quint64 pc, const QString &da)
+{
+ QByteArray p;
+ {
+ QDataStream s(&p, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << pc;
+ s << da;
+ }
+ rpcCall(Disassembled, p);
+}
+
+void IPCEngineGuest::notifyAddBreakpointOk(quint64 id)
+{
+ QByteArray p;
+ {
+ QDataStream s(&p, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << id;
+ }
+ rpcCall(NotifyAddBreakpointOk, p);
+}
+
+void IPCEngineGuest::notifyAddBreakpointFailed(quint64 id)
+{
+ QByteArray p;
+ {
+ QDataStream s(&p, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << id;
+ }
+ rpcCall(NotifyAddBreakpointFailed, p);
+}
+
+void IPCEngineGuest::notifyRemoveBreakpointOk(quint64 id)
+{
+ QByteArray p;
+ {
+ QDataStream s(&p, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << id;
+ }
+ rpcCall(NotifyRemoveBreakpointOk, p);
+}
+
+void IPCEngineGuest::notifyRemoveBreakpointFailed(quint64 id)
+{
+ QByteArray p;
+ {
+ QDataStream s(&p, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << id;
+ }
+ rpcCall(NotifyRemoveBreakpointFailed, p);
+}
+
+void IPCEngineGuest::notifyChangeBreakpointOk(quint64 id)
+{
+ QByteArray p;
+ {
+ QDataStream s(&p, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << id;
+ }
+ rpcCall(NotifyChangeBreakpointOk, p);
+}
+
+void IPCEngineGuest::notifyChangeBreakpointFailed(quint64 id)
+{
+ QByteArray p;
+ {
+ QDataStream s(&p, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << id;
+ }
+ rpcCall(NotifyChangeBreakpointFailed, p);
+}
+
+void IPCEngineGuest::notifyBreakpointAdjusted(const Internal::BreakpointData &bp)
+{
+ QByteArray p;
+ {
+ QDataStream s(&p, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << bp;
+ }
+ rpcCall(NotifyBreakpointAdjusted, p);
+}
+
+void IPCEngineGuest::updateWatchData(bool fullCycle, const QList<Internal::WatchData> &wd)
+{
+ QByteArray p;
+ {
+ QDataStream s(&p, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << fullCycle;
+ s << quint64(wd.count());
+ for (int i = 0; i < wd.count(); i++)
+ s << wd.at(i);
+ }
+ rpcCall(UpdateWatchData, p);
+}
+
+} // namespace Internal
+} // namespace Debugger
+
+
--- /dev/null
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef DEBUGGER_IPCENGINE_H
+#define DEBUGGER_IPCENGINE_H
+
+#include "debuggerengine.h"
+#include "threadshandler.h"
+#include "stackhandler.h"
+#include "breakhandler.h"
+
+#include <QtCore/QQueue>
+#include <QtCore/QVariant>
+#include <QtCore/QThread>
+
+namespace Debugger {
+namespace Internal {
+
+class IPCEngineHost;
+class IPCEngineGuest : public QObject
+{
+ Q_OBJECT
+
+public:
+ IPCEngineGuest();
+ virtual ~IPCEngineGuest();
+
+ void setLocalHost(IPCEngineHost *);
+ void setHostDevice(QIODevice *);
+
+ virtual void setupEngine() = 0;
+ virtual void setupInferior(const QString &executeable,
+ const QStringList &arguments, const QStringList &environment) = 0;
+ virtual void runEngine() = 0;
+ virtual void shutdownInferior() = 0;
+ virtual void shutdownEngine() = 0;
+ virtual void detachDebugger() = 0;
+ virtual void executeStep() = 0;
+ virtual void executeStepOut() = 0;
+ virtual void executeNext() = 0;
+ virtual void executeStepI() = 0;
+ virtual void executeNextI() = 0;
+ virtual void continueInferior() = 0;
+ virtual void interruptInferior() = 0;
+ virtual void executeRunToLine(const QString &fileName, int lineNumber) = 0;
+ virtual void executeRunToFunction(const QString &functionName) = 0;
+ virtual void executeJumpToLine(const QString &fileName, int lineNumber) = 0;
+ virtual void activateFrame(qint64 token) = 0;
+ virtual void selectThread(qint64 token) = 0;
+ virtual void disassemble(quint64 pc) = 0;
+ virtual void addBreakpoint(const Internal::BreakpointData &bp) = 0;
+ virtual void removeBreakpoint(quint64 id) = 0;
+ virtual void changeBreakpoint(const Internal::BreakpointData &bp) = 0;
+ virtual void requestUpdateWatchData(const Internal::WatchData &data,
+ const Internal::WatchUpdateFlags & flags = Internal::WatchUpdateFlags()) = 0;
+
+ enum Function
+ {
+ NotifyEngineSetupOk = 1,
+ NotifyEngineSetupFailed = 2,
+ NotifyEngineRunFailed = 3,
+ NotifyInferiorSetupOk = 4,
+ NotifyInferiorSetupFailed = 5,
+ NotifyEngineRunAndInferiorRunOk = 6,
+ NotifyEngineRunAndInferiorStopOk = 7,
+ NotifyInferiorRunRequested = 8,
+ NotifyInferiorRunOk = 9,
+ NotifyInferiorRunFailed = 10,
+ NotifyInferiorStopOk = 11,
+ NotifyInferiorSpontaneousStop = 12,
+ NotifyInferiorStopFailed = 13,
+ NotifyInferiorExited = 14,
+ NotifyInferiorShutdownOk = 15,
+ NotifyInferiorShutdownFailed = 16,
+ NotifyEngineSpontaneousShutdown = 17,
+ NotifyEngineShutdownOk = 18,
+ NotifyEngineShutdownFailed = 19,
+ NotifyInferiorIll = 20,
+ NotifyEngineIll = 21,
+ NotifyInferiorPid = 22,
+ ShowStatusMessage = 23,
+ ShowMessage = 24,
+ CurrentFrameChanged = 25,
+ CurrentThreadChanged = 26,
+ ListFrames = 27,
+ ListThreads = 28,
+ Disassembled = 29,
+ NotifyAddBreakpointOk = 30,
+ NotifyAddBreakpointFailed = 31,
+ NotifyRemoveBreakpointOk = 32,
+ NotifyRemoveBreakpointFailed = 33,
+ NotifyChangeBreakpointOk = 34,
+ NotifyChangeBreakpointFailed = 35,
+ NotifyBreakpointAdjusted = 36,
+ UpdateWatchData = 47
+ };
+ Q_ENUMS(Function);
+
+ DebuggerState state() const;
+ void notifyEngineSetupOk();
+ void notifyEngineSetupFailed();
+ void notifyEngineRunFailed();
+ void notifyInferiorSetupOk();
+ void notifyInferiorSetupFailed();
+ void notifyEngineRunAndInferiorRunOk();
+ void notifyEngineRunAndInferiorStopOk();
+ void notifyInferiorRunRequested();
+ void notifyInferiorRunOk();
+ void notifyInferiorRunFailed();
+ void notifyInferiorStopOk();
+ void notifyInferiorSpontaneousStop();
+ void notifyInferiorStopFailed();
+ void notifyInferiorExited();
+ void notifyInferiorShutdownOk();
+ void notifyInferiorShutdownFailed();
+ void notifyEngineSpontaneousShutdown();
+ void notifyEngineShutdownOk();
+ void notifyEngineShutdownFailed();
+ void notifyInferiorIll();
+ void notifyEngineIll();
+ void notifyInferiorPid(qint64 pid);
+ void showMessage(const QString &msg, quint16 channel = LogDebug, quint64 timeout = -1);
+ void showStatusMessage(const QString &msg, quint64 timeout = -1);
+
+ void currentFrameChanged(qint64 token);
+ void currentThreadChanged(qint64 token);
+ void listFrames(const StackFrames &);
+ void listThreads(const Threads &);
+ void disassembled(quint64 pc, const QString &da);
+
+ void notifyAddBreakpointOk(quint64 id);
+ void notifyAddBreakpointFailed(quint64 id);
+ void notifyRemoveBreakpointOk(quint64 id);
+ void notifyRemoveBreakpointFailed(quint64 id);
+ void notifyChangeBreakpointOk(quint64 id);
+ void notifyChangeBreakpointFailed(quint64 id);
+ void notifyBreakpointAdjusted(const Internal::BreakpointData &bp);
+
+ void updateWatchData(bool fullCycle, const QList<Internal::WatchData> &);
+
+ void rpcCall(Function f, QByteArray payload = QByteArray());
+public slots:
+ void rpcCallback(quint64 f, QByteArray payload = QByteArray());
+private slots:
+ void readyRead();
+private:
+ IPCEngineHost *m_local_host;
+ quint64 m_nextMessageCookie;
+ quint64 m_nextMessageFunction;
+ quint64 m_nextMessagePayloadSize;
+ quint64 m_cookie;
+ QIODevice *m_device;
+ DebuggerState m_state;
+};
+
+} // namespace Internal
+} // namespace Debugger
+
+#endif // DEBUGGER_LLDBENGINE_H
--- /dev/null
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "ipcenginehost.h"
+#include "ipcengineguest.h"
+#include "breakhandler.h"
+#include "breakpoint.h"
+#include "moduleshandler.h"
+#include "registerhandler.h"
+#include "stackhandler.h"
+#include "watchhandler.h"
+#include "watchutils.h"
+#include "threadshandler.h"
+#include "debuggeragents.h"
+#include "debuggerstreamops.h"
+
+#include <QSysInfo>
+#include <QDebug>
+#include <QFileInfo>
+#include <QTimer>
+#include <utils/qtcassert.h>
+
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+#define SET_NATIVE_BYTE_ORDER(x) x.setByteOrder(QDataStream::LittleEndian)
+#else
+#define SET_NATIVE_BYTE_ORDER(x) x.setByteOrder(QDataStream::BigEndian)
+#endif
+
+namespace Debugger {
+namespace Internal {
+
+IPCEngineHost::IPCEngineHost (const DebuggerStartParameters &startParameters)
+ : DebuggerEngine(startParameters)
+ , m_local_guest(0)
+ , m_nextMessagePayloadSize(0)
+ , m_cookie(1)
+ , m_device(0)
+{
+ connect(this, SIGNAL(stateChanged(const DebuggerState &)), this, SLOT(m_stateChanged(const DebuggerState &)));
+}
+
+IPCEngineHost::~IPCEngineHost()
+{
+ delete m_device;
+}
+
+void IPCEngineHost::setLocalGuest(IPCEngineGuest *g)
+{
+ m_local_guest = g;
+}
+
+void IPCEngineHost::setGuestDevice(QIODevice *d)
+{
+ if (m_device) {
+ disconnect(m_device, SIGNAL(readyRead()), this, SLOT(readyRead()));
+ delete m_device;
+ }
+ m_device = d;
+ if (m_device)
+ connect(m_device, SIGNAL(readyRead()), this, SLOT(readyRead()));
+}
+
+void IPCEngineHost::setupEngine()
+{
+ QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
+ rpcCall(SetupEngine);
+}
+
+void IPCEngineHost::setupInferior()
+{
+ QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
+ QByteArray p;
+ {
+ QDataStream s(&p, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << QFileInfo(startParameters().executable).absoluteFilePath();
+ s << startParameters().processArgs;
+ s << startParameters().environment;
+ }
+ rpcCall(SetupInferior, p);
+}
+
+void IPCEngineHost::runEngine()
+{
+ QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
+ rpcCall(RunEngine);
+}
+
+void IPCEngineHost::shutdownInferior()
+{
+ QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state());
+ rpcCall(ShutdownInferior);
+}
+
+void IPCEngineHost::shutdownEngine()
+{
+ rpcCall(ShutdownEngine);
+}
+
+void IPCEngineHost::detachDebugger()
+{
+ rpcCall(DetachDebugger);
+}
+
+void IPCEngineHost::executeStep()
+{
+ rpcCall(ExecuteStep);
+}
+
+void IPCEngineHost::executeStepOut()
+{
+ rpcCall(ExecuteStepOut);
+}
+
+void IPCEngineHost::executeNext()
+{
+ rpcCall(ExecuteNext);
+}
+
+void IPCEngineHost::executeStepI()
+{
+ rpcCall(ExecuteStepI);
+}
+
+void IPCEngineHost::executeNextI()
+{
+ rpcCall(ExecuteNextI);
+}
+
+void IPCEngineHost::continueInferior()
+{
+ QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
+ resetLocation();
+ rpcCall(ContinueInferior);
+}
+
+void IPCEngineHost::interruptInferior()
+{
+ QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state());
+ rpcCall(InterruptInferior);
+}
+
+void IPCEngineHost::executeRunToLine(const QString &fileName, int lineNumber)
+{
+ QByteArray p;
+ {
+ QDataStream s(&p, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << fileName;
+ s << quint64(lineNumber);
+ }
+ rpcCall(ExecuteRunToLine, p);
+}
+
+void IPCEngineHost::executeRunToFunction(const QString &functionName)
+{
+ QByteArray p;
+ {
+ QDataStream s(&p, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << functionName;
+ }
+ rpcCall(ExecuteRunToFunction, p);
+}
+
+void IPCEngineHost::executeJumpToLine(const QString &fileName, int lineNumber)
+{
+ QByteArray p;
+ {
+ QDataStream s(&p, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << fileName;
+ s << quint64(lineNumber);
+ }
+ rpcCall(ExecuteJumpToLine, p);
+}
+
+
+void IPCEngineHost::activateFrame(int index)
+{
+ resetLocation();
+ QByteArray p;
+ {
+ QDataStream s(&p, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << quint64(index);
+ }
+ rpcCall(ActivateFrame, p);
+}
+
+void IPCEngineHost::selectThread(int index)
+{
+ resetLocation();
+ Threads threads = threadsHandler()->threads();
+ QTC_ASSERT(index < threads.size(), return);
+ QByteArray p;
+ {
+ QDataStream s(&p, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << quint64(threads.at(index).id);
+ }
+ rpcCall(SelectThread, p);
+}
+
+void IPCEngineHost::fetchDisassembler(Internal::DisassemblerViewAgent *v)
+{
+ quint64 address = v->frame().address;
+ m_frameToDisassemblerAgent.insert(address, v);
+ QByteArray p;
+ {
+ QDataStream s(&p, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << address;
+ }
+ rpcCall(Disassemble, p);
+}
+
+
+void IPCEngineHost::addBreakpoint(const Internal::BreakpointData &bp)
+{
+ QByteArray p;
+ {
+ QDataStream s(&p, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << bp;
+ }
+ rpcCall(AddBreakpoint, p);
+}
+
+void IPCEngineHost::removeBreakpoint(quint64 id)
+{
+ QByteArray p;
+ {
+ QDataStream s(&p, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << id;
+ }
+ rpcCall(RemoveBreakpoint, p);
+}
+
+void IPCEngineHost::changeBreakpoint(const Internal::BreakpointData &bp)
+{
+ QByteArray p;
+ {
+ QDataStream s(&p, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << bp;
+ }
+ rpcCall(RemoveBreakpoint, p);
+}
+
+void IPCEngineHost::updateWatchData(const Internal::WatchData &data,
+ const Internal::WatchUpdateFlags &flags)
+{
+ Q_UNUSED(flags);
+ QByteArray p;
+ {
+ QDataStream s(&p, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << data;
+ }
+ rpcCall(RequestUpdateWatchData, p);
+}
+
+void IPCEngineHost::rpcCallback(quint64 f, QByteArray payload)
+{
+ switch (f) {
+ default:
+ showMessage(QLatin1String("IPC Error: unhandled id in guest to host call"));
+ showMessage(tr("Fatal engine shutdown. Incompatible binary or ipc error."), LogError);
+ showStatusMessage(tr("Fatal engine shutdown. Incompatible binary or ipc error."));
+ notifyEngineSpontaneousShutdown();
+ break;
+ case IPCEngineGuest::NotifyEngineSetupOk:
+ notifyEngineSetupOk();
+ break;
+ case IPCEngineGuest::NotifyEngineSetupFailed:
+ notifyEngineSetupFailed();
+ break;
+ case IPCEngineGuest::NotifyEngineRunFailed:
+ notifyEngineRunFailed();
+ break;
+ case IPCEngineGuest::NotifyInferiorSetupOk:
+ attemptBreakpointSynchronization();
+ notifyInferiorSetupOk();
+ break;
+ case IPCEngineGuest::NotifyInferiorSetupFailed:
+ notifyInferiorSetupFailed();
+ break;
+ case IPCEngineGuest::NotifyEngineRunAndInferiorRunOk:
+ notifyEngineRunAndInferiorRunOk();
+ break;
+ case IPCEngineGuest::NotifyEngineRunAndInferiorStopOk:
+ notifyEngineRunAndInferiorStopOk();
+ break;
+ case IPCEngineGuest::NotifyInferiorRunRequested:
+ notifyInferiorRunRequested();
+ break;
+ case IPCEngineGuest::NotifyInferiorRunOk:
+ notifyInferiorRunOk();
+ break;
+ case IPCEngineGuest::NotifyInferiorRunFailed:
+ notifyInferiorRunFailed();
+ break;
+ case IPCEngineGuest::NotifyInferiorStopOk:
+ notifyInferiorStopOk();
+ break;
+ case IPCEngineGuest::NotifyInferiorSpontaneousStop:
+ notifyInferiorSpontaneousStop();
+ break;
+ case IPCEngineGuest::NotifyInferiorStopFailed:
+ notifyInferiorStopFailed();
+ break;
+ case IPCEngineGuest::NotifyInferiorExited:
+ notifyInferiorExited();
+ break;
+ case IPCEngineGuest::NotifyInferiorShutdownOk:
+ notifyInferiorShutdownOk();
+ break;
+ case IPCEngineGuest::NotifyInferiorShutdownFailed:
+ notifyInferiorShutdownFailed();
+ break;
+ case IPCEngineGuest::NotifyEngineSpontaneousShutdown:
+ notifyEngineSpontaneousShutdown();
+ break;
+ case IPCEngineGuest::NotifyEngineShutdownOk:
+ notifyEngineShutdownOk();
+ break;
+ case IPCEngineGuest::NotifyEngineShutdownFailed:
+ notifyEngineShutdownFailed();
+ break;
+ case IPCEngineGuest::NotifyInferiorIll:
+ notifyInferiorIll();
+ break;
+ case IPCEngineGuest::NotifyEngineIll:
+ notifyEngineIll();
+ break;
+ case IPCEngineGuest::NotifyInferiorPid:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ quint64 pid;
+ s >> pid;
+ notifyInferiorPid(pid);
+ }
+ break;
+ case IPCEngineGuest::ShowStatusMessage:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ QString msg;
+ qint64 timeout;
+ s >> msg;
+ s >> timeout;
+ showStatusMessage(msg, timeout);
+ }
+ break;
+ case IPCEngineGuest::ShowMessage:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ QString msg;
+ qint16 channel;
+ qint64 timeout;
+ s >> msg;
+ s >> channel;
+ s >> timeout;
+ showMessage(msg, channel, timeout);
+ }
+ break;
+ case IPCEngineGuest::CurrentFrameChanged:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ quint64 token;
+ s >> token;
+
+ resetLocation();
+ StackHandler *sh = stackHandler();
+ sh->setCurrentIndex(token);
+ gotoLocation(sh->currentFrame(), true);
+ }
+ break;
+ case IPCEngineGuest::CurrentThreadChanged:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ quint64 token;
+ s >> token;
+ threadsHandler()->setCurrentThreadId(token);
+ }
+ break;
+ case IPCEngineGuest::ListFrames:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ StackFrames frames;
+ s >> frames;
+ stackHandler()->setFrames(frames);
+ }
+ break;
+ case IPCEngineGuest::ListThreads:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ Threads threads;
+ s >> threads;
+ threadsHandler()->setThreads(threads);
+ }
+ break;
+ case IPCEngineGuest::Disassembled:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ quint64 pc;
+ QString da;
+ s >> pc;
+ s >> da;
+ Internal::DisassemblerViewAgent *view = m_frameToDisassemblerAgent.take(pc);
+ if (view)
+ view->setContents(da);
+ }
+ break;
+ case IPCEngineGuest::UpdateWatchData:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ bool fullCycle;
+ qint64 count;
+ QList<WatchData> wd;
+ s >> fullCycle;
+ s >> count;
+ for (qint64 i = 0; i < count; i++) {
+ WatchData d;
+ s >> d;
+ wd.append(d);
+ }
+ WatchHandler *wh = watchHandler();
+ if (!wh)
+ break;
+ wh->beginCycle(fullCycle);
+ wh->insertBulkData(wd);
+ wh->endCycle(fullCycle);
+ }
+ break;
+ case IPCEngineGuest::NotifyAddBreakpointOk:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ quint64 id;
+ s >> id;
+ notifyAddBreakpointOk(id);
+ }
+ case IPCEngineGuest::NotifyAddBreakpointFailed:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ quint64 id;
+ s >> id;
+ notifyAddBreakpointFailed(id);
+ }
+ case IPCEngineGuest::NotifyRemoveBreakpointOk:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ quint64 id;
+ s >> id;
+ notifyRemoveBreakpointOk(id);
+ }
+ case IPCEngineGuest::NotifyRemoveBreakpointFailed:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ quint64 id;
+ s >> id;
+ notifyRemoveBreakpointFailed(id);
+ }
+ case IPCEngineGuest::NotifyChangeBreakpointOk:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ quint64 id;
+ s >> id;
+ notifyChangeBreakpointOk(id);
+ }
+ case IPCEngineGuest::NotifyChangeBreakpointFailed:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ quint64 id;
+ s >> id;
+ notifyChangeBreakpointFailed(id);
+ }
+ case IPCEngineGuest::NotifyBreakpointAdjusted:
+ {
+ QDataStream s(payload);
+ SET_NATIVE_BYTE_ORDER(s);
+ BreakpointData d;
+ s >> d;
+ notifyBreakpointAdjusted(d);
+ }
+ }
+}
+
+void IPCEngineHost::m_stateChanged(const DebuggerState &state)
+{
+ QByteArray p;
+ {
+ QDataStream s(&p, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << (qint64)state;
+ }
+ rpcCall(StateChanged, p);
+
+}
+
+void IPCEngineHost::rpcCall(Function f, QByteArray payload)
+{
+ if (m_local_guest) {
+ QMetaObject::invokeMethod(m_local_guest,
+ "rpcCallback",
+ Qt::QueuedConnection,
+ Q_ARG(quint64, f),
+ Q_ARG(QByteArray, payload));
+ } else if (m_device) {
+ QByteArray header;
+ {
+ QDataStream s(&header, QIODevice::WriteOnly);
+ SET_NATIVE_BYTE_ORDER(s);
+ s << m_cookie++;
+ s << (quint64) f;
+ s << (quint64) payload.size();
+ }
+ m_device->write(header);
+ m_device->write(payload);
+ m_device->putChar('T');
+ }
+}
+
+void IPCEngineHost::readyRead()
+{
+ QDataStream s(m_device);
+ SET_NATIVE_BYTE_ORDER(s);
+ if (!m_nextMessagePayloadSize) {
+ if (quint64(m_device->bytesAvailable ()) < (sizeof(quint64) * 3))
+ return;
+ s >> m_nextMessageCookie;
+ s >> m_nextMessageFunction;
+ s >> m_nextMessagePayloadSize;
+ m_nextMessagePayloadSize += 1; // terminator and "got header" marker
+ }
+
+ quint64 ba = m_device->bytesAvailable();
+ if (ba < m_nextMessagePayloadSize)
+ return;
+
+ QByteArray payload = m_device->read(m_nextMessagePayloadSize - 1);
+
+ char terminator;
+ m_device->getChar(&terminator);
+ if (terminator != 'T') {
+ showStatusMessage(tr("Fatal engine shutdown. Incompatible binary or ipc error."));
+ showMessage(QLatin1String("IPC Error: terminator missing"));
+ notifyEngineSpontaneousShutdown();
+ return;
+ }
+ rpcCallback(m_nextMessageFunction, payload);
+ m_nextMessagePayloadSize = 0;
+ if (quint64(m_device->bytesAvailable()) >= (sizeof(quint64) * 3))
+ QTimer::singleShot(0, this, SLOT(readyRead()));
+}
+
+
+} // namespace Internal
+} // namespace Debugger
+
+
--- /dev/null
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef DEBUGGER_IPCENGINE_HOST_H
+#define DEBUGGER_IPCENGINE_HOST_H
+
+#include "debuggerengine.h"
+#include "threadshandler.h"
+#include "stackhandler.h"
+#include "breakhandler.h"
+
+#include <QtCore/QQueue>
+#include <QtCore/QVariant>
+#include <QtCore/QThread>
+
+namespace Debugger {
+namespace Internal {
+
+class IPCEngineGuest;
+class IPCEngineHost : public DebuggerEngine
+{
+ Q_OBJECT
+
+public:
+ explicit IPCEngineHost(const DebuggerStartParameters &startParameters);
+ ~IPCEngineHost();
+
+ // use either one
+ void setLocalGuest(IPCEngineGuest *);
+ void setGuestDevice(QIODevice *);
+
+ enum Function
+ {
+ SetupIPC = 1,
+ StateChanged = 2,
+ SetupEngine = 3,
+ SetupInferior = 4,
+ RunEngine = 5,
+ ShutdownInferior = 6,
+ ShutdownEngine = 7,
+ DetachDebugger = 8,
+ ExecuteStep = 9,
+ ExecuteStepOut = 10,
+ ExecuteNext = 11,
+ ExecuteStepI = 12,
+ ExecuteNextI = 13,
+ ContinueInferior = 14,
+ InterruptInferior = 15,
+ ExecuteRunToLine = 16,
+ ExecuteRunToFunction = 17,
+ ExecuteJumpToLine = 18,
+ ActivateFrame = 19,
+ SelectThread = 20,
+ Disassemble = 21,
+ AddBreakpoint = 22,
+ RemoveBreakpoint = 23,
+ ChangeBreakpoint = 24,
+ RequestUpdateWatchData = 25
+ };
+ Q_ENUMS(Function);
+
+ void setupEngine();
+ void setupInferior();
+ void runEngine();
+ void shutdownInferior();
+ void shutdownEngine();
+ void detachDebugger();
+ void executeStep();
+ void executeStepOut() ;
+ void executeNext();
+ void executeStepI();
+ void executeNextI();
+ void continueInferior();
+ void interruptInferior();
+ void executeRunToLine(const QString &fileName, int lineNumber);
+ void executeRunToFunction(const QString &functionName);
+ void executeJumpToLine(const QString &fileName, int lineNumber);
+ void activateFrame(int index);
+ void selectThread(int index);
+ void fetchDisassembler(Internal::DisassemblerViewAgent *);
+ void addBreakpoint(const Internal::BreakpointData &bp);
+ void removeBreakpoint(quint64 id);
+ void changeBreakpoint(const Internal::BreakpointData &bp);
+ void updateWatchData(const Internal::WatchData &data,
+ const Internal::WatchUpdateFlags &flags = Internal::WatchUpdateFlags());
+
+ void rpcCall(Function f, QByteArray payload = QByteArray());
+public slots:
+ void rpcCallback(quint64 f, QByteArray payload = QByteArray());
+private slots:
+ void m_stateChanged(const DebuggerState &state);
+ void readyRead();
+private:
+ IPCEngineGuest *m_local_guest;
+ quint64 m_nextMessageCookie;
+ quint64 m_nextMessageFunction;
+ quint64 m_nextMessagePayloadSize;
+ quint64 m_cookie;
+ QIODevice *m_device;
+ QHash <quint64, Internal::DisassemblerViewAgent *> m_frameToDisassemblerAgent;
+};
+
+} // namespace Internal
+} // namespace Debugger
+
+#endif // DEBUGGER_LLDBENGINE_H
--- /dev/null
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#define QT_NO_CAST_FROM_ASCII
+
+#include "lldbenginehost.h"
+
+#include "debuggeractions.h"
+#include "debuggerconstants.h"
+#include "debuggerdialogs.h"
+#include "debuggerplugin.h"
+#include "debuggerstringutils.h"
+
+#include "breakhandler.h"
+#include "breakpoint.h"
+#include "moduleshandler.h"
+#include "registerhandler.h"
+#include "stackhandler.h"
+#include "watchhandler.h"
+#include "watchutils.h"
+#include "threadshandler.h"
+#include "debuggeragents.h"
+
+#include <utils/qtcassert.h>
+#include <QtCore/QDebug>
+#include <QtCore/QProcess>
+#include <QtCore/QFileInfo>
+#include <QtCore/QThread>
+#include <QtCore/QCoreApplication>
+#include <QtNetwork/QLocalSocket>
+#include <QtNetwork/QLocalServer>
+
+namespace Debugger {
+namespace Internal {
+
+LLDBEngineHost::LLDBEngineHost(const DebuggerStartParameters &startParameters)
+ :IPCEngineHost(startParameters)
+{
+ QLocalServer *s = new QLocalServer(this);
+ s->removeServer (QLatin1String("/tmp/qtcreator-debuggeripc"));
+ s->listen (QLatin1String("/tmp/qtcreator-debuggeripc"));
+
+ m_guestp = new QProcess(this);
+ m_guestp->setProcessChannelMode(QProcess::ForwardedChannels);
+
+ connect(m_guestp, SIGNAL(finished(int, QProcess::ExitStatus)),
+ this, SLOT(finished (int, QProcess::ExitStatus)));
+
+ QString a(qApp->applicationDirPath() + QLatin1String("/../Resources/qtcreator-lldb"));
+ m_guestp->start(a,QStringList());
+
+ if (!m_guestp->waitForStarted()) {
+ showStatusMessage(tr("lldb failed to start"));
+ notifyEngineIll();
+ return;
+ }
+
+ s->waitForNewConnection(-1);
+ QLocalSocket *f = s->nextPendingConnection();
+ s->close(); // wtf race in accept
+ setGuestDevice(f);
+}
+
+LLDBEngineHost::~LLDBEngineHost()
+{
+ disconnect(m_guestp, SIGNAL(finished(int, QProcess::ExitStatus)),
+ this, SLOT(finished (int, QProcess::ExitStatus)));
+ m_guestp->terminate();
+ m_guestp->kill();
+}
+
+void LLDBEngineHost::finished (int, QProcess::ExitStatus)
+{
+ showStatusMessage(QLatin1String("lldb crashed"));
+ notifyEngineIll();
+}
+
+DebuggerEngine *createLLDBEngine(const DebuggerStartParameters &startParameters)
+{
+ return new LLDBEngineHost(startParameters);
+}
+
+} // namespace Internal
+} // namespace Debugger
--- /dev/null
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** 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.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef DEBUGGER_LLDBENGINE_HOST_H
+#define DEBUGGER_LLDBENGINE_HOST_H
+
+#include "ipcenginehost.h"
+
+#include <QtCore/QProcess>
+
+namespace Debugger {
+namespace Internal {
+
+class LLDBEngineHost : public IPCEngineHost
+{
+ Q_OBJECT
+public:
+ explicit LLDBEngineHost(const DebuggerStartParameters &startParameters);
+ ~LLDBEngineHost();
+private:
+ QProcess *m_guestp;
+private slots:
+ void finished (int, QProcess::ExitStatus);
+};
+
+} // namespace Internal
+} // namespace Debugger
+
+#endif // DEBUGGER_LLDBENGINE_H
--- /dev/null
+HEADERS += $$PWD/ipcenginehost.h \
+ $$PWD/lldbenginehost.h
+
+SOURCES += $$PWD/ipcenginehost.cpp \
+ $$PWD/lldbenginehost.cpp
+
+INCLUDEPATH+=
+
+DEFINES += IPC_STANDALONE_HOST
+
+FORMS +=
+
+RESOURCES +=