From: Arvid Ephraim Picciani Date: Fri, 8 Oct 2010 10:14:51 +0000 (+0200) Subject: Experimental lldb engine host X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=c0da255a875be0c9cf02b182e6fe26ff63546733;p=qt-creator-jp%2Fqt-creator-jp.git Experimental lldb engine host --- diff --git a/src/plugins/debugger/debugger.pro b/src/plugins/debugger/debugger.pro index 1b066a8f61..3ab43200aa 100644 --- a/src/plugins/debugger/debugger.pro +++ b/src/plugins/debugger/debugger.pro @@ -123,6 +123,7 @@ include(cdb/cdb.pri) include(gdb/gdb.pri) include(script/script.pri) include(pdb/pdb.pri) +include(lldb/lldbhost.pri) contains(QT_CONFIG, declarative) { QT += declarative diff --git a/src/plugins/debugger/debuggerconstants.h b/src/plugins/debugger/debuggerconstants.h index c9e419f2cc..30688ba0cd 100644 --- a/src/plugins/debugger/debuggerconstants.h +++ b/src/plugins/debugger/debuggerconstants.h @@ -208,7 +208,8 @@ enum DebuggerEngineType PdbEngineType = 0x08, TcfEngineType = 0x10, QmlEngineType = 0x20, - QmlCppEngineType = 0x40, + QmlCppEngineType = 0x40, + LLDBEngineType = 0x80, AllEngineTypes = GdbEngineType | ScriptEngineType | CdbEngineType @@ -216,6 +217,7 @@ enum DebuggerEngineType | TcfEngineType | QmlEngineType | QmlCppEngineType + | LLDBEngineType }; enum DebuggerLanguage diff --git a/src/plugins/debugger/debuggerrunner.cpp b/src/plugins/debugger/debuggerrunner.cpp index 949e7eab62..aa095193cd 100644 --- a/src/plugins/debugger/debuggerrunner.cpp +++ b/src/plugins/debugger/debuggerrunner.cpp @@ -39,6 +39,7 @@ #include "gdb/remoteplaingdbadapter.h" #include "qml/qmlengine.h" #include "qml/qmlcppengine.h" +#include "lldb/lldbenginehost.h" #ifdef Q_OS_WIN # include "peutils.h" @@ -72,6 +73,7 @@ DebuggerEngine *createPdbEngine(const DebuggerStartParameters &); DebuggerEngine *createTcfEngine(const DebuggerStartParameters &); DebuggerEngine *createQmlEngine(const DebuggerStartParameters &); DebuggerEngine *createQmlCppEngine(const DebuggerStartParameters &); +DebuggerEngine *createLLDBEngine(const DebuggerStartParameters &); bool checkGdbConfiguration(int toolChain, QString *errorMsg, QString *settingsPage); @@ -429,6 +431,9 @@ void DebuggerRunControl::createEngine(const DebuggerStartParameters &startParams 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()) @@ -477,6 +482,8 @@ void DebuggerRunControl::createEngine(const DebuggerStartParameters &startParams if (Internal::GdbEngine *embeddedGdbEngine = gdbEngine()) initGdbEngine(embeddedGdbEngine); break; + case LLDBEngineType: + d->m_engine = Internal::createLLDBEngine(sp); case NoEngineType: case AllEngineTypes: break; diff --git a/src/plugins/debugger/lldb/ipcengineguest.cpp b/src/plugins/debugger/lldb/ipcengineguest.cpp new file mode 100644 index 0000000000..0a21927d1a --- /dev/null +++ b/src/plugins/debugger/lldb/ipcengineguest.cpp @@ -0,0 +1,608 @@ +/************************************************************************** +** +** 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 +#include +#include +#include +#include + +#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 &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 + + diff --git a/src/plugins/debugger/lldb/ipcengineguest.h b/src/plugins/debugger/lldb/ipcengineguest.h new file mode 100644 index 0000000000..e532382ab3 --- /dev/null +++ b/src/plugins/debugger/lldb/ipcengineguest.h @@ -0,0 +1,185 @@ +/************************************************************************** +** +** 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 +#include +#include + +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 &); + + 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 diff --git a/src/plugins/debugger/lldb/ipcenginehost.cpp b/src/plugins/debugger/lldb/ipcenginehost.cpp new file mode 100644 index 0000000000..277fd26607 --- /dev/null +++ b/src/plugins/debugger/lldb/ipcenginehost.cpp @@ -0,0 +1,603 @@ +/************************************************************************** +** +** 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 +#include +#include +#include +#include + +#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 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 + + diff --git a/src/plugins/debugger/lldb/ipcenginehost.h b/src/plugins/debugger/lldb/ipcenginehost.h new file mode 100644 index 0000000000..2a8e49b2a1 --- /dev/null +++ b/src/plugins/debugger/lldb/ipcenginehost.h @@ -0,0 +1,132 @@ +/************************************************************************** +** +** 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 +#include +#include + +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 m_frameToDisassemblerAgent; +}; + +} // namespace Internal +} // namespace Debugger + +#endif // DEBUGGER_LLDBENGINE_H diff --git a/src/plugins/debugger/lldb/lldbenginehost.cpp b/src/plugins/debugger/lldb/lldbenginehost.cpp new file mode 100644 index 0000000000..d410c44dd5 --- /dev/null +++ b/src/plugins/debugger/lldb/lldbenginehost.cpp @@ -0,0 +1,110 @@ +/************************************************************************** +** +** 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 +#include +#include +#include +#include +#include +#include +#include + +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 diff --git a/src/plugins/debugger/lldb/lldbenginehost.h b/src/plugins/debugger/lldb/lldbenginehost.h new file mode 100644 index 0000000000..47822daf11 --- /dev/null +++ b/src/plugins/debugger/lldb/lldbenginehost.h @@ -0,0 +1,55 @@ +/************************************************************************** +** +** 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 + +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 diff --git a/src/plugins/debugger/lldb/lldbhost.pri b/src/plugins/debugger/lldb/lldbhost.pri new file mode 100644 index 0000000000..e2f63b0b2b --- /dev/null +++ b/src/plugins/debugger/lldb/lldbhost.pri @@ -0,0 +1,13 @@ +HEADERS += $$PWD/ipcenginehost.h \ + $$PWD/lldbenginehost.h + +SOURCES += $$PWD/ipcenginehost.cpp \ + $$PWD/lldbenginehost.cpp + +INCLUDEPATH+= + +DEFINES += IPC_STANDALONE_HOST + +FORMS += + +RESOURCES +=