Debugger: Remove LldbLibEngine

That's dead code now that we go with the Python interface.

Change-Id: Ie10393d6adf5d25540c4082aeccf683e88bcdc89
Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
hjk
2013-11-27 10:22:23 +01:00
parent baf190ff4a
commit e76be1ca7b
22 changed files with 0 additions and 3410 deletions

View File

@@ -151,7 +151,6 @@ include(cdb/cdb.pri)
include(gdb/gdb.pri) include(gdb/gdb.pri)
include(pdb/pdb.pri) include(pdb/pdb.pri)
include(lldb/lldb.pri) include(lldb/lldb.pri)
include(lldblib/lldbhost.pri)
include(qml/qml.pri) include(qml/qml.pri)
include(namedemangler/namedemangler.pri) include(namedemangler/namedemangler.pri)

View File

@@ -131,16 +131,6 @@ QtcPlugin {
] ]
} }
Group {
name: "lldblib"
id: lldblib
prefix: "lldblib/"
files: [
"ipcenginehost.cpp", "ipcenginehost.h",
"lldbenginehost.cpp", "lldbenginehost.h"
]
}
Group { Group {
name: "pdb" name: "pdb"
prefix: "pdb/" prefix: "pdb/"
@@ -247,16 +237,6 @@ QtcPlugin {
] ]
} }
Group {
name: "LLDBOptions"
condition: qbs.targetOS.contains("osx")
files: [
"lldblib/lldboptionspage.cpp",
"lldblib/lldboptionspage.h",
"lldblib/lldboptionspagewidget.ui",
]
}
Properties { Properties {
condition: qbs.targetOS.contains("windows") condition: qbs.targetOS.contains("windows")
cpp.dynamicLibraries: [ cpp.dynamicLibraries: [

View File

@@ -190,14 +190,12 @@ enum DebuggerEngineType
PdbEngineType = 0x008, PdbEngineType = 0x008,
QmlEngineType = 0x020, QmlEngineType = 0x020,
QmlCppEngineType = 0x040, QmlCppEngineType = 0x040,
LldbLibEngineType = 0x080,
LldbEngineType = 0x100, LldbEngineType = 0x100,
AllEngineTypes = GdbEngineType AllEngineTypes = GdbEngineType
| CdbEngineType | CdbEngineType
| PdbEngineType | PdbEngineType
| QmlEngineType | QmlEngineType
| QmlCppEngineType | QmlCppEngineType
| LldbLibEngineType
| LldbEngineType | LldbEngineType
}; };

View File

@@ -75,7 +75,6 @@ DebuggerEngine *createGdbEngine(const DebuggerStartParameters &sp);
DebuggerEngine *createPdbEngine(const DebuggerStartParameters &sp); DebuggerEngine *createPdbEngine(const DebuggerStartParameters &sp);
DebuggerEngine *createQmlEngine(const DebuggerStartParameters &sp); DebuggerEngine *createQmlEngine(const DebuggerStartParameters &sp);
DebuggerEngine *createQmlCppEngine(const DebuggerStartParameters &sp, QString *error); DebuggerEngine *createQmlCppEngine(const DebuggerStartParameters &sp, QString *error);
DebuggerEngine *createLldbLibEngine(const DebuggerStartParameters &sp);
DebuggerEngine *createLldbEngine(const DebuggerStartParameters &sp); DebuggerEngine *createLldbEngine(const DebuggerStartParameters &sp);
static const char *engineTypeName(DebuggerEngineType et) static const char *engineTypeName(DebuggerEngineType et)
@@ -93,8 +92,6 @@ static const char *engineTypeName(DebuggerEngineType et)
return "QML engine"; return "QML engine";
case Debugger::QmlCppEngineType: case Debugger::QmlCppEngineType:
return "QML C++ engine"; return "QML C++ engine";
case Debugger::LldbLibEngineType:
return "LLDB binary engine";
case Debugger::LldbEngineType: case Debugger::LldbEngineType:
return "LLDB command line engine"; return "LLDB command line engine";
case Debugger::AllEngineTypes: case Debugger::AllEngineTypes:
@@ -518,8 +515,6 @@ DebuggerEngine *DebuggerRunControlFactory::createEngine(DebuggerEngineType et,
return createQmlEngine(sp); return createQmlEngine(sp);
case LldbEngineType: case LldbEngineType:
return createLldbEngine(sp); return createLldbEngine(sp);
case LldbLibEngineType:
return createLldbLibEngine(sp);
case QmlCppEngineType: case QmlCppEngineType:
return createQmlCppEngine(sp, errorMessage); return createQmlCppEngine(sp, errorMessage);
default: default:

View File

@@ -1,31 +0,0 @@
LLDB Guest Engine
You can use the LLDB debugger from the LLVM project with the Qt Creator debugger
plugin on Mac OS.
For the Qt Creator build to pick up the LLDB Guest Engine,
you must download the LLDB debugger and configure it
to be included in the Qt Creator build.
To debug an application, Qt Creator must access the memory of the application.
On Mac OS X, this requires code signing.
To enable LLDB debugger support in Qt Creator:
1. To download the LLDB debugger, enter the following command:
svn co http://llvm.org/svn/llvm-project/lldb/trunk lldb
2. To sign the code, follow the instructions in lldb/docs/code-signing.txt.
3. To open LLDB in Xcode for building, enter the following command:
open lldb.xcodeproj
then select the Release target and press the build button.
4. In Xcode, press the build button.
5. type the following to have the qt creator build system find your lldb build:
export WITH_LLDB=/path/to/lldb
6. To rebuild Qt Creator, change back to the top level directory of
the Qt Creator source, and enter the following command:
qmake -r && make

View File

@@ -1,761 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#define QT_NO_CAST_FROM_ASCII
#include "lldbengineguest.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 <utils/qtcassert.h>
#include <QDebug>
#include <QProcess>
#include <QFileInfo>
#include <QThread>
#include <QMutexLocker>
#include <lldb/API/LLDB.h>
#define DEBUG_FUNC_ENTER \
showMessage(QString(QLatin1String("LLDB guest engine: %1 ")) \
.arg(QLatin1String(Q_FUNC_INFO))); \
qDebug("%s", Q_FUNC_INFO)
#define SYNC_INFERIOR_OR(x) if (m_running) { x; }
namespace Debugger {
namespace Internal {
void LldbEventListener::listen(lldb::SBListener *listener)
{
while (true) {
lldb::SBEvent event;
if (listener->WaitForEvent(1000, event))
emit lldbEvent(&event);
}
}
LldbEngineGuest::LldbEngineGuest()
: IPCEngineGuest()
, m_running (false)
, m_worker (new LldbEventListener)
, m_lldb (new lldb::SBDebugger)
, m_target (new lldb::SBTarget)
, m_process (new lldb::SBProcess)
, m_listener(new lldb::SBListener("bla"))
, m_relistFrames (false)
#if defined(HAVE_LLDB_PRIVATE)
, py (new PythonLLDBToGdbMiHack)
#endif
{
qRegisterMetaType<lldb::SBListener *>("lldb::SBListener *");
qRegisterMetaType<lldb::SBEvent *>("lldb::SBEvent *");
m_worker->moveToThread(&m_wThread);
connect(m_worker, SIGNAL(lldbEvent(lldb::SBEvent*)), this,
SLOT(lldbEvent(lldb::SBEvent*)), Qt::BlockingQueuedConnection);
m_wThread.start();
setObjectName(QLatin1String("LLDBEngineGuest"));
}
LldbEngineGuest::~LldbEngineGuest()
{
delete m_lldb;
delete m_target;
delete m_process;
delete m_listener;
}
void LldbEngineGuest::nuke()
{
::exit(4);
}
void LldbEngineGuest::setupEngine()
{
DEBUG_FUNC_ENTER;
lldb::SBDebugger::Initialize();
*m_lldb = lldb::SBDebugger::Create();
m_lldb->Initialize();
if (m_lldb->IsValid())
notifyEngineSetupOk();
else
notifyEngineSetupFailed();
}
void LldbEngineGuest::setupInferior(const QString &executable,
const QStringList &args, const QStringList &env)
{
DEBUG_FUNC_ENTER;
foreach (const QString &s, args) {
m_arguments.append(s.toLocal8Bit());
}
foreach (const QString &s, env) {
m_environment.append(s.toLocal8Bit());
}
qDebug("creating target for %s", executable.toLocal8Bit().data());
showStatusMessage(QLatin1String("starting ") + executable);
*m_target = m_lldb->CreateTarget(executable.toLocal8Bit().data());
if (!m_target->IsValid()) {
notifyInferiorSetupFailed();
return;
}
DEBUG_FUNC_ENTER;
const char **argp = new const char *[m_arguments.count() + 1];
argp[m_arguments.count()] = 0;
for (int i = 0; i < m_arguments.count(); i++) {
argp[i] = m_arguments[i].data();
}
const char **envp = new const char *[m_environment.count() + 1];
envp[m_environment.count()] = 0;
for (int i = 0; i < m_environment.count(); i++) {
envp[i] = m_environment[i].data();
}
lldb::SBError err;
*m_process = m_target->Launch(argp, envp, NULL, NULL, true, err);
if (!err.Success()) {
showMessage(QString::fromLocal8Bit(err.GetCString()));
qDebug() << err.GetCString();
notifyInferiorSetupFailed();
}
/*
* note, the actual string ptrs are still valid. They are in m_environment.
* They probably leak. Considered the marvelous API, there is not much we can do
*/
delete [] envp;
if (!m_process->IsValid())
notifyEngineRunFailed();
QTC_ASSERT(m_listener->IsValid(), qDebug() << false);
m_listener->StartListeningForEvents(m_process->GetBroadcaster(), UINT32_MAX);
QMetaObject::invokeMethod(m_worker, "listen", Qt::QueuedConnection,
Q_ARG(lldb::SBListener *, m_listener));
notifyInferiorSetupOk();
}
void LldbEngineGuest::runEngine()
{
DEBUG_FUNC_ENTER;
m_process->Continue();
}
void LldbEngineGuest::shutdownInferior()
{
DEBUG_FUNC_ENTER;
m_process->Kill();
}
void LldbEngineGuest::shutdownEngine()
{
DEBUG_FUNC_ENTER;
m_currentFrame = lldb::SBFrame();
m_currentThread = lldb::SBThread();
m_breakpoints.clear();
m_localesCache.clear();
/*
* this leaks. However, Terminate is broken and lldb leaks anyway
* We should kill the engine guest process
*/
*m_lldb = lldb::SBDebugger();
// leakd.Terminate();
notifyEngineShutdownOk();
}
void LldbEngineGuest::detachDebugger()
{
DEBUG_FUNC_ENTER;
}
void LldbEngineGuest::executeStep()
{
DEBUG_FUNC_ENTER;
if (!m_currentThread.IsValid())
return;
m_currentThread.StepInto();
}
void LldbEngineGuest::executeStepOut()
{
DEBUG_FUNC_ENTER;
if (!m_currentThread.IsValid())
return;
m_currentThread.StepOut();
}
void LldbEngineGuest::executeNext()
{
DEBUG_FUNC_ENTER;
if (!m_currentThread.IsValid())
return;
m_currentThread.StepOver();
}
void LldbEngineGuest::executeStepI()
{
DEBUG_FUNC_ENTER;
if (!m_currentThread.IsValid())
return;
m_currentThread.StepInstruction(false);
}
void LldbEngineGuest::executeNextI()
{
DEBUG_FUNC_ENTER;
if (!m_currentThread.IsValid())
return;
m_currentThread.StepInstruction(true);
}
void LldbEngineGuest::continueInferior()
{
DEBUG_FUNC_ENTER;
notifyInferiorRunRequested();
m_process->Continue();
showStatusMessage(QLatin1String("resuming inferior"));
}
void LldbEngineGuest::interruptInferior()
{
DEBUG_FUNC_ENTER;
m_process->Stop();
notifyInferiorStopOk();
m_relistFrames = true;
updateThreads();
}
void LldbEngineGuest::executeRunToLine(const ContextData &data);
{
DEBUG_FUNC_ENTER;
// TODO
Q_UNUSED(data);
}
void LldbEngineGuest::executeRunToFunction(const QString &functionName)
{
DEBUG_FUNC_ENTER;
// TODO
Q_UNUSED(functionName);
}
void LldbEngineGuest::executeJumpToLine(const ContextData &data);
{
DEBUG_FUNC_ENTER;
// TODO
Q_UNUSED(data);
}
void LldbEngineGuest::activateFrame(qint64 token)
{
DEBUG_FUNC_ENTER;
SYNC_INFERIOR_OR(showMessage(QLatin1String(
"activateFrame called while inferior running")); return);
currentFrameChanged(token);
m_localesCache.clear();
lldb::SBFrame fr = m_currentThread.GetFrameAtIndex(token);
m_currentFrame = fr;
lldb::SBSymbolContext context = fr.GetSymbolContext(lldb::eSymbolContextEverything);
lldb::SBValueList values = fr.GetVariables(true, true, false, true);
QList<WatchData> wd;
QByteArray iname = "local";
for (uint i = 0; i < values.GetSize(); i++) {
lldb::SBValue v = values.GetValueAtIndex(i);
if (!v.IsInScope(fr))
continue;
getWatchDataR(v, 1, iname, wd);
}
updateWatchData(true, wd);
}
void LldbEngineGuest::requestUpdateWatchData(const Internal::WatchData &data,
const Internal::WatchUpdateFlags &)
{
DEBUG_FUNC_ENTER;
SYNC_INFERIOR_OR(return);
lldb::SBValue v = m_localesCache.value(QString::fromUtf8(data.iname));
QList<WatchData> wd;
for (uint j = 0; j < v.GetNumChildren(); j++) {
lldb::SBValue vv = v.GetChildAtIndex(j);
getWatchDataR(vv, 1, data.iname, wd);
}
updateWatchData(false, wd);
}
void LldbEngineGuest::getWatchDataR(lldb::SBValue v, int level,
const QByteArray &p_iname, QList<WatchData> &wd)
{
QByteArray iname = p_iname + '.' + QByteArray(v.GetName());
m_localesCache.insert(QString::fromLocal8Bit(iname), v);
#if defined(HAVE_LLDB_PRIVATE)
wd += py->expand(p_iname, v, m_currentFrame, *m_process);
#else
WatchData d;
d.name = QString::fromLocal8Bit(v.GetName());
d.iname = iname;
d.type = QByteArray(v.GetTypeName()).trimmed();
d.value = (QString::fromLocal8Bit(v.GetValue(m_currentFrame)));
d.hasChildren = v.GetNumChildren();
d.state = WatchData::State(0);
wd.append(d);
#endif
if (--level > 0) {
for (uint j = 0; j < v.GetNumChildren(); j++) {
lldb::SBValue vv = v.GetChildAtIndex(j);
getWatchDataR(vv, level, iname, wd);
}
}
}
void LldbEngineGuest::disassemble(quint64 pc)
{
DEBUG_FUNC_ENTER;
SYNC_INFERIOR_OR(return);
if (!m_currentThread.IsValid())
return;
for (uint j = 0; j < m_currentThread.GetNumFrames(); j++) {
lldb::SBFrame fr = m_currentThread.GetFrameAtIndex(j);
if (pc == fr.GetPCAddress().GetLoadAddress(*m_target)) {
QString linesStr = QString::fromLocal8Bit(fr.Disassemble());
DisassemblerLines lines;
foreach (const QString &lineStr, linesStr.split(QLatin1Char('\n'))) {
lines.appendLine(DisassemblerLine(lineStr));
}
disassembled(pc, lines);
}
}
}
void LldbEngineGuest::fetchFrameSource(qint64 frame)
{
QFile f(m_frame_to_file.value(frame));
f.open(QFile::ReadOnly);
frameSourceFetched(frame, QFileInfo(m_frame_to_file.value(frame)).fileName()
, QString::fromLocal8Bit(f.readAll()));
}
void LldbEngineGuest::addBreakpoint(BreakpointId id,
const Internal::BreakpointParameters &bp_)
{
DEBUG_FUNC_ENTER;
SYNC_INFERIOR_OR(notifyAddBreakpointFailed(id); return);
Internal::BreakpointParameters bp(bp_);
lldb::SBBreakpoint llbp = m_target->BreakpointCreateByLocation(
bp.fileName.toLocal8Bit().constData(), bp.lineNumber);
if (llbp.IsValid()) {
m_breakpoints.insert(id, llbp);
llbp.SetIgnoreCount(bp.ignoreCount);
bp.ignoreCount = llbp.GetIgnoreCount();
bp.enabled = llbp.IsEnabled();
lldb::SBBreakpointLocation location = llbp.GetLocationAtIndex(0);
if (location.IsValid()) {
bp.address = location.GetLoadAddress();
// FIXME get those from lldb
bp.lineNumber = bp.lineNumber;
bp.fileName = bp.fileName;
notifyAddBreakpointOk(id);
showMessage(QLatin1String("[BB] ok."));
notifyBreakpointAdjusted(id, bp);
} else {
m_breakpoints.take(id);
showMessage(QLatin1String("[BB] failed. cant resolve yet"));
// notifyAddBreakpointFailed(id);
// notifyAddBreakpointOk(id);
}
} else {
showMessage(QLatin1String("[BB] failed. dunno."));
notifyAddBreakpointFailed(id);
}
}
void LldbEngineGuest::removeBreakpoint(BreakpointId id)
{
DEBUG_FUNC_ENTER;
SYNC_INFERIOR_OR(notifyRemoveBreakpointFailed(id); return);
lldb::SBBreakpoint llbp = m_breakpoints.take(id);
llbp.SetEnabled(false);
notifyRemoveBreakpointOk(id);
}
void LldbEngineGuest::changeBreakpoint(BreakpointId id,
const Internal::BreakpointParameters &bp)
{
DEBUG_FUNC_ENTER;
// TODO
Q_UNUSED(id);
Q_UNUSED(bp);
}
void LldbEngineGuest::selectThread(qint64 token)
{
DEBUG_FUNC_ENTER;
SYNC_INFERIOR_OR(return);
m_frame_to_file.clear();
for (uint i = 0; i < m_process->GetNumThreads(); i++) {
lldb::SBThread t = m_process->GetThreadAtIndex(i);
if (t.GetThreadID() == token) {
m_currentThread = t;
StackFrames frames;
int firstResolvableFrame = -1;
for (uint j = 0; j < t.GetNumFrames(); j++) {
lldb::SBFrame fr = t.GetFrameAtIndex(j);
if (!fr.IsValid()) {
qDebug("warning: frame %i is garbage", j);
continue;
}
lldb::SBSymbolContext context =
fr.GetSymbolContext(lldb::eSymbolContextEverything);
lldb::SBSymbol sym = fr.GetSymbol();
lldb::SBFunction func = fr.GetFunction();
lldb::SBCompileUnit tu = fr.GetCompileUnit();
lldb::SBModule module = fr.GetModule();
lldb::SBBlock block = fr.GetBlock();
lldb::SBBlock fblock = fr.GetFrameBlock();
lldb::SBLineEntry le = fr.GetLineEntry();
lldb::SBValueList values = fr.GetVariables(true, true, true, false);
#if 0
qDebug()<<"\tframe "<<fr.GetFrameID();
qDebug() << "\t\tPC: " << ("0x" + QByteArray::number(
fr.GetPCAddress().GetLoadAddress(*m_target), 16)).data();
qDebug() << "\t\tFP: " << ("0x" + QByteArray::number(fr.GetFP(), 16)).data();
qDebug() << "\t\tSP: " << ("0x" + QByteArray::number(fr.GetSP(), 16)).data();
qDebug() << "\t\tsymbol: " << sym.IsValid() << sym.GetName() << sym.GetMangledName();
qDebug() << "\t\tfunction:" << func.IsValid();
qDebug() << "\t\ttu: " << tu.IsValid();
if (tu.IsValid())
qDebug() << "\t\tmodule: " << module.IsValid() << module.GetFileSpec().IsValid()
<< module.GetFileSpec().GetFilename();
qDebug() << "\t\tblock: " << block.IsValid() << block.GetInlinedName();
qDebug() << "\t\tfblock: " << block.IsValid() << block.GetInlinedName();
qDebug() << "\t\tle: " << le.IsValid() << le.GetLine()<<le.GetColumn();
qDebug() << "\t\tvalues: "<<values.IsValid() << values.GetSize();
qDebug() << "\t\tcontext: " << context.IsValid();
qDebug() << "\t\t\tmodule: " << context.GetModule().IsValid();
qDebug() << "\t\t\tfunction: " << context.GetFunction().IsValid();
qDebug() << "\t\t\tblock: " << context.GetBlock().IsValid();
qDebug() << "\t\t\tle: " << context.GetLineEntry().IsValid();
qDebug() << "\t\t\tsymbol: " << context.GetSymbol().IsValid();
// qDebug() << "\t\tdisassemly -->\n" << fr.Disassemble() << "<--";
#endif
QString sourceFile;
QString sourceFilePath;
int lineNumber = 0;
if (le.IsValid()) {
lineNumber = le.GetLine();
if (le.GetFileSpec().IsValid()) {
sourceFile = QString::fromLocal8Bit(le.GetFileSpec().GetFilename());
sourceFilePath = QString::fromLocal8Bit(le.GetFileSpec().GetDirectory())
+ QLatin1String("/") + sourceFile;
if (firstResolvableFrame < 0)
firstResolvableFrame = j;
}
}
sourceFilePath = QFileInfo(sourceFilePath).canonicalFilePath();
QString functionName;
if (func.IsValid())
functionName = QString::fromLocal8Bit(func.GetName());
else
functionName = QString::fromLocal8Bit(sym.GetName());
StackFrame frame;
frame.level = fr.GetFrameID();
if (func.IsValid())
frame.function = QString::fromLocal8Bit(func.GetName());
else
frame.function = QString::fromLocal8Bit(sym.GetName());
frame.from = QString::fromLocal8Bit(module.GetFileSpec().GetFilename());
frame.address = fr.GetPCAddress().GetLoadAddress(*m_target);
frame.line = lineNumber;
frame.file = sourceFilePath;
frame.usable = QFileInfo(frame.file).isReadable();
frames.append(frame);
m_frame_to_file.insert(j, frame.file);
}
currentThreadChanged(token);
listFrames(frames);
activateFrame(firstResolvableFrame > -1 ? firstResolvableFrame : 0);
return;
}
}
}
void LldbEngineGuest::updateThreads()
{
DEBUG_FUNC_ENTER;
SYNC_INFERIOR_OR(return);
/* There is no way to find the StopReason of a _process_
* We try to emulate gdb here, by assuming there must be exactly one 'guilty' thread.
* However, if there are no threads at all, it must be that the process
* no longer exists. Let's tear down the whole session.
*/
if (m_process->GetNumThreads() < 1) {
notifyEngineSpontaneousShutdown();
m_process->Kill();
m_process->Destroy();
}
Threads threads;
for (uint i = 0; i < m_process->GetNumThreads(); i++) {
lldb::SBThread t = m_process->GetThreadAtIndex(i);
if (!t.IsValid()) {
qDebug("warning: thread %i is garbage", i);
continue;
}
ThreadData thread;
thread.id = t.GetThreadID();
thread.targetId = QString::number(t.GetThreadID());
thread.core.clear();
thread.state = QString::number(t.GetStopReason());
switch (t.GetStopReason()) {
case lldb::eStopReasonInvalid:
case lldb::eStopReasonNone:
case lldb::eStopReasonTrace:
thread.state = QLatin1String("running");
break;
case lldb::eStopReasonBreakpoint:
case lldb::eStopReasonWatchpoint:
showStatusMessage(QLatin1String("hit breakpoint"));
thread.state = QLatin1String("hit breakpoint");
if (m_currentThread.GetThreadID() != t.GetThreadID()) {
m_currentThread = t;
currentThreadChanged(t.GetThreadID());
m_relistFrames = true;
}
break;
case lldb::eStopReasonSignal:
showStatusMessage(QLatin1String("stopped"));
thread.state = QLatin1String("stopped");
if (m_currentThread.GetThreadID() != t.GetThreadID()) {
m_currentThread = t;
currentThreadChanged(t.GetThreadID());
m_relistFrames = true;
}
break;
case lldb::eStopReasonException:
showStatusMessage(QLatin1String("application crashed."));
thread.state = QLatin1String("crashed");
if (m_currentThread.GetThreadID() != t.GetThreadID()) {
m_currentThread = t;
currentThreadChanged(t.GetThreadID());
m_relistFrames = true;
}
break;
case lldb::eStopReasonPlanComplete:
thread.state = QLatin1String("crazy things happened");
break;
};
thread.lineNumber = 0;
thread.name = QString::fromLocal8Bit(t.GetName());
lldb::SBFrame fr = t.GetFrameAtIndex(0);
if (!fr.IsValid()) {
qDebug("warning: frame 0 is garbage");
continue;
}
lldb::SBSymbolContext context = fr.GetSymbolContext(lldb::eSymbolContextEverything);
lldb::SBSymbol sym = fr.GetSymbol();
lldb::SBFunction func = fr.GetFunction();
lldb::SBLineEntry le = fr.GetLineEntry();
QString sourceFile;
QString sourceFilePath;
int lineNumber = 0;
if (le.IsValid()) {
lineNumber = le.GetLine();
if (le.GetFileSpec().IsValid()) {
sourceFile = QString::fromLocal8Bit(le.GetFileSpec().GetFilename());
sourceFilePath = QString::fromLocal8Bit(le.GetFileSpec().GetDirectory())
+ QLatin1String("/") + sourceFile;
}
}
QString functionName;
if (func.IsValid())
functionName = QString::fromLocal8Bit(func.GetName());
else
functionName = QString::fromLocal8Bit(sym.GetName());
lldb::SBValueList values = fr.GetVariables(true, true, false, false);
thread.fileName = sourceFile;
thread.function = functionName;
thread.address = fr.GetPCAddress().GetLoadAddress(*m_target);
thread.lineNumber = lineNumber;
threads.append(thread);
}
listThreads(threads);
if (m_relistFrames) {
selectThread(m_currentThread.GetThreadID());
m_relistFrames = false;
}
}
void LldbEngineGuest::lldbEvent(lldb::SBEvent *ev)
{
qDebug() << "lldbevent" << ev->GetType() <<
m_process->GetState() << (int)state();
uint32_t etype = ev->GetType();
switch (etype) {
// ProcessEvent
case 1:
switch (m_process->GetState()) {
case lldb::eStateRunning: // 5
if (!m_running)
m_running = true;
notifyInferiorPid(m_process->GetProcessID());
switch (state()) {
case EngineRunRequested:
notifyEngineRunAndInferiorRunOk();
break;
case InferiorRunRequested:
notifyInferiorRunOk();
break;
case InferiorStopOk:
notifyInferiorRunRequested();
notifyInferiorRunOk();
break;
default:
break;
}
break;
case lldb::eStateExited: // 9
if (m_running)
m_running = false;
switch (state()) {
case InferiorShutdownRequested:
notifyInferiorShutdownOk();
break;
case InferiorRunOk:
m_relistFrames = true;
updateThreads();
notifyEngineSpontaneousShutdown();
m_process->Kill();
m_process->Destroy();
break;
default:
updateThreads();
break;
}
break;
case lldb::eStateStopped: // 4
if (m_running)
m_running = false;
switch (state()) {
case InferiorShutdownRequested:
notifyInferiorShutdownOk();
break;
case InferiorRunOk:
m_relistFrames = true;
updateThreads();
notifyInferiorSpontaneousStop();
// fall
default:
m_relistFrames = true;
updateThreads();
break;
}
break;
case lldb::eStateCrashed: // 7
if (m_running)
m_running = false;
switch (state()) {
case InferiorShutdownRequested:
notifyInferiorShutdownOk();
break;
case InferiorRunOk:
m_relistFrames = true;
updateThreads();
notifyInferiorSpontaneousStop();
break;
default:
break;
}
break;
default:
qDebug("unexpected ProcessEvent");
break;
}
break;
default:
break;
};
}
} // namespace Internal
} // namespace Debugger

View File

@@ -1,136 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef DEBUGGER_LLDBENGINE_GUEST_H
#define DEBUGGER_LLDBENGINE_GUEST_H
#include "ipcengineguest.h"
#include <QQueue>
#include <QVariant>
#include <QThread>
#include <QStringList>
#include <lldb/API/LLDB.h>
#if defined(HAVE_LLDB_PRIVATE)
#include "pygdbmiemu.h"
#endif
Q_DECLARE_METATYPE (lldb::SBListener *)
Q_DECLARE_METATYPE (lldb::SBEvent *)
namespace Debugger {
namespace Internal {
class LldbEventListener : public QObject
{
Q_OBJECT
public slots:
void listen(lldb::SBListener *listener);
signals:
// lldb API uses non thread safe implicit sharing with no explicit copy feature
// additionally the scope is undefined, hence this signal needs to be connected BlockingQueued
// whutever, works for now.
void lldbEvent(lldb::SBEvent *ev);
};
class LldbEngineGuest : public IPCEngineGuest
{
Q_OBJECT
public:
explicit LldbEngineGuest();
~LldbEngineGuest();
void nuke();
void setupEngine();
void setupInferior(const QString &executable, const QStringList &arguments,
const QStringList &environment);
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 ContextData &data);
void executeRunToFunction(const QString &functionName);
void executeJumpToLine(const ContextData &data);
void activateFrame(qint64);
void selectThread(qint64);
void disassemble(quint64 pc);
void addBreakpoint(BreakpointModelId id, const BreakpointParameters &bp);
void removeBreakpoint(BreakpointModelId id);
void changeBreakpoint(BreakpointModelId id, const BreakpointParameters &bp);
void requestUpdateWatchData(const WatchData &data,
const WatchUpdateFlags &flags);
void fetchFrameSource(qint64 frame);
private:
bool m_running;
QList<QByteArray> m_arguments;
QList<QByteArray> m_environment;
QThread m_wThread;
LldbEventListener *m_worker;
lldb::SBDebugger *m_lldb;
lldb::SBTarget *m_target;
lldb::SBProcess *m_process;
lldb::SBListener *m_listener;
lldb::SBFrame m_currentFrame;
lldb::SBThread m_currentThread;
bool m_relistFrames;
QHash<QString, lldb::SBValue> m_localesCache;
QHash<BreakpointModelId, lldb::SBBreakpoint> m_breakpoints;
QHash<qint64, QString> m_frame_to_file;
void updateThreads();
void getWatchDataR(lldb::SBValue v, int level,
const QByteArray &p_iname, QList<WatchData> &wd);
#if defined(HAVE_LLDB_PRIVATE)
PythonLLDBToGdbMiHack * py;
#endif
private slots:
void lldbEvent(lldb::SBEvent *ev);
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGER_LLDBENGINE_H
#define SYNC_INFERIOR

View File

@@ -1,151 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "lldbengineguest.h"
#include <QLocalSocket>
#include <QCoreApplication>
#include <QSocketNotifier>
#include <QQueue>
#include <cstdio>
// #define DO_STDIO_DEBUG 1
#ifdef DO_STDIO_DEBUG
#define D_STDIO0(x) qDebug(x)
#define D_STDIO1(x,a1) qDebug(x,a1)
#define D_STDIO2(x,a1,a2) qDebug(x,a1,a2)
#define D_STDIO3(x,a1,a2,a3) qDebug(x,a1,a2,a3)
#else
#define D_STDIO0(x)
#define D_STDIO1(x,a1)
#define D_STDIO2(x,a1,a2)
#define D_STDIO3(x,a1,a2,a3)
#endif
class Stdio : public QIODevice
{
Q_OBJECT
public:
QSocketNotifier notify;
Stdio()
: QIODevice()
, notify(fileno(stdin), QSocketNotifier::Read)
, buckethead(0)
{
setvbuf(stdin , NULL , _IONBF , 0);
setvbuf(stdout , NULL , _IONBF , 0);
setOpenMode(QIODevice::ReadWrite | QIODevice::Unbuffered);
connect(&notify, SIGNAL(activated(int)), this, SLOT(activated()));
}
virtual qint64 bytesAvailable () const
{
qint64 r = QIODevice::bytesAvailable();
foreach (const QByteArray &bucket, buckets)
r += bucket.size();
r-= buckethead;
return r;
}
virtual qint64 readData (char * data, qint64 maxSize)
{
D_STDIO1("readData %lli",maxSize);
qint64 size = maxSize;
while (size > 0) {
if (!buckets.size()) {
D_STDIO1("done prematurely with %lli", maxSize - size);
return maxSize - size;
}
QByteArray &bucket = buckets.head();
if ((size + buckethead) >= bucket.size()) {
int d = bucket.size() - buckethead;
D_STDIO3("read (over bucket) d: %i buckethead: %i bucket.size(): %i",
d, buckethead, bucket.size());
memcpy(data, bucket.data() + buckethead, d);
data += d;
size -= d;
buckets.dequeue();
buckethead = 0;
} else {
D_STDIO1("read (in bucket) size: %lli", size);
memcpy(data, bucket.data() + buckethead, size);
data += size;
buckethead += size;
size = 0;
}
}
D_STDIO1("done with %lli",(maxSize - size));
return maxSize - size;
}
virtual qint64 writeData (const char * data, qint64 maxSize)
{
return ::write(fileno(stdout), data, maxSize);
}
QQueue<QByteArray> buckets;
int buckethead;
private slots:
void activated()
{
QByteArray a;
a.resize(1000);
int ret = ::read(fileno(stdin), a.data(), 1000);
if (ret == 0)
::exit(0);
assert(ret <= 1000);
D_STDIO1("activated %i", ret);
a.resize(ret);
buckets.enqueue(a);
emit readyRead();
}
};
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
qDebug() << "guest engine operational";
Debugger::Internal::LldbEngineGuest lldb;
Stdio stdio;
lldb.setHostDevice(&stdio);
return app.exec();
}
extern "C" {
extern const unsigned char lldbVersionString[] __attribute__ ((used)) = "@(#)PROGRAM:lldb PROJECT:lldb-26" "\n";
extern const double lldbVersionNumber __attribute__ ((used)) = (double)26.;
extern const double LLDBVersionNumber __attribute__ ((used)) = (double)26.;
}
#include "main.moc"

View File

@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>org.qt-project.qtcreator-lldb</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Qt Creator LLDB Guest</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>SecTaskAccess</key>
<array>
<string>allowed</string>
<string>safe</string>
</array>
</dict>
</plist>

View File

@@ -1,2 +0,0 @@
WITH_LLDB = $$(WITH_LLDB)
macx: !isEmpty(WITH_LLDB) : SUBDIRS += $$PWD/qtcreator-lldb.pro

View File

@@ -1,61 +0,0 @@
WITH_LLDB = $$(WITH_LLDB)
!macx: error (This can only be built on mac)
!exists($${WITH_LLDB}/include/lldb/lldb-enumerations.h): error(please see the README for build instructions)
QT = core network
include(../../../../../qtcreator.pri)
TEMPLATE = app
CONFIG -= app_bundle
CONFIG += debug
TARGET = qtcreator-lldb
DEPENDPATH += . .. ../.. ../../..
INCLUDEPATH += . .. ../.. ../../..
DESTDIR = $$IDE_LIBEXEC_PATH
MOC_DIR=.tmp
OBJECTS_DIR=.tmp
HEADERS += ../ipcengineguest.h \
../debuggerstreamops.h \
../breakpoint.h \
../watchdata.h \
../stackframe.h \
../disassemblerlines.h \
lldbengineguest.h
SOURCES += ../ipcengineguest.cpp \
../debuggerstreamops.cpp \
../breakpoint.cpp \
../watchdata.cpp \
../stackframe.cpp \
../disassemblerlines.cpp \
lldbengineguest.cpp \
main.cpp
LIBS += -sectcreate __TEXT __info_plist $$PWD/qtcreator-lldb.plist
POSTL = rm -rf \'$${IDE_LIBEXEC_PATH}/LLDB.framework\' $$escape_expand(\\n\\t) \
$$QMAKE_COPY_DIR $${WITH_LLDB}/build/Release/* \'$$IDE_LIBEXEC_PATH\' $$escape_expand(\\n\\t) \
install_name_tool -change '@rpath/LLDB.framework/Versions/A/LLDB' '@executable_path/LLDB.framework/Versions/A/LLDB' $(TARGET) $$escape_expand(\\n\\t) \
codesign -s lldb_codesign $(TARGET)
!isEmpty(QMAKE_POST_LINK):QMAKE_POST_LINK = $$escape_expand(\\n\\t)$$QMAKE_POST_LINK
QMAKE_POST_LINK = $$POSTL $$QMAKE_POST_LINK
silent:QMAKE_POST_LINK = @echo signing $@ && $$QMAKE_POST_LINK
LIBS += -framework Security -framework Python
DEFINES += __STDC_LIMIT_MACROS __STDC_CONSTANT_MACROS
INCLUDEPATH += $${WITH_LLDB}/include $${WITH_LLDB}/llvm/include/
LIBS += -F$${WITH_LLDB}/build/Release -framework LLDB
# include (lldb.pri)
# DEFINES += HAVE_LLDB_PRIVATE
# HEADERS += pygdbmiemu.h
# SOURCES += pygdbmiemu.cpp

View File

@@ -1,637 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "ipcengineguest.h"
#include "ipcenginehost.h"
#include "breakpoint.h"
#include "stackframe.h"
#include "threaddata.h"
#include "debuggerstreamops.h"
#include <utils/qtcassert.h>
#include <QLocalSocket>
#include <QSysInfo>
#include <QDebug>
#include <QFileInfo>
#include <QTimer>
#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 *host)
{
m_local_host = host;
}
void IPCEngineGuest::setHostDevice(QIODevice *device)
{
if (m_device) {
disconnect(m_device, SIGNAL(readyRead()), this, SLOT(readyRead()));
delete m_device;
}
m_device = device;
if (m_device)
connect(m_device, SIGNAL(readyRead()), SLOT(readyRead()));
}
void IPCEngineGuest::rpcCall(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');
QLocalSocket *sock = qobject_cast<QLocalSocket *>(m_device);
if (sock)
sock->flush();
}
}
void IPCEngineGuest::readyRead()
{
if (!m_nextMessagePayloadSize) {
if (quint64(m_device->bytesAvailable()) < 3 * sizeof(quint64))
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')) {
qDebug("IPC Error: corrupted frame");
showMessage(QLatin1String("[guest] IPC Error: corrupted frame"), LogError);
nuke();
return;
}
payload.chop(1);
rpcCallback(m_nextMessageFunction, payload);
m_nextMessagePayloadSize = 0;
if (quint64(m_device->bytesAvailable ()) >= 3 * sizeof(quint64))
QTimer::singleShot(0, this, SLOT(readyRead()));
}
void IPCEngineGuest::rpcCallback(quint64 f, QByteArray payload)
{
switch (f) {
default:
qDebug("IPC Error: unhandled id in host to guest call");
showMessage(QLatin1String("IPC Error: unhandled id in host to guest call"), LogError);
nuke();
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);
ContextData data;
s >> data.fileName;
s >> data.lineNumber;
executeRunToLine(data);
}
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);
ContextData data;
s >> data.fileName;
s >> data.lineNumber;
executeJumpToLine(data);
}
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);
BreakpointModelId id;
BreakpointParameters d;
s >> id;
s >> d;
addBreakpoint(id, d);
}
break;
case IPCEngineHost::RemoveBreakpoint:
{
QDataStream s(payload);
SET_NATIVE_BYTE_ORDER(s);
BreakpointModelId id;
s >> id;
removeBreakpoint(id);
}
break;
case IPCEngineHost::ChangeBreakpoint:
{
QDataStream s(payload);
SET_NATIVE_BYTE_ORDER(s);
BreakpointModelId id;
BreakpointParameters d;
s >> id;
s >> d;
changeBreakpoint(id, d);
}
break;
case IPCEngineHost::RequestUpdateWatchData:
{
QDataStream s(payload);
SET_NATIVE_BYTE_ORDER(s);
WatchData data;
s >> data;
requestUpdateWatchData(data);
}
break;
case IPCEngineHost::FetchFrameSource:
{
QDataStream s(payload);
SET_NATIVE_BYTE_ORDER(s);
qint64 id;
s >> id;
fetchFrameSource(id);
}
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 DisassemblerLines &da)
{
QByteArray p;
{
QDataStream s(&p, QIODevice::WriteOnly);
SET_NATIVE_BYTE_ORDER(s);
s << pc;
s << da;
}
rpcCall(Disassembled, p);
}
void IPCEngineGuest::notifyAddBreakpointOk(BreakpointModelId id)
{
QByteArray p;
{
QDataStream s(&p, QIODevice::WriteOnly);
SET_NATIVE_BYTE_ORDER(s);
s << id;
}
rpcCall(NotifyAddBreakpointOk, p);
}
void IPCEngineGuest::notifyAddBreakpointFailed(BreakpointModelId id)
{
QByteArray p;
{
QDataStream s(&p, QIODevice::WriteOnly);
SET_NATIVE_BYTE_ORDER(s);
s << id;
}
rpcCall(NotifyAddBreakpointFailed, p);
}
void IPCEngineGuest::notifyRemoveBreakpointOk(BreakpointModelId id)
{
QByteArray p;
{
QDataStream s(&p, QIODevice::WriteOnly);
SET_NATIVE_BYTE_ORDER(s);
s << id;
}
rpcCall(NotifyRemoveBreakpointOk, p);
}
void IPCEngineGuest::notifyRemoveBreakpointFailed(BreakpointModelId id)
{
QByteArray p;
{
QDataStream s(&p, QIODevice::WriteOnly);
SET_NATIVE_BYTE_ORDER(s);
s << id;
}
rpcCall(NotifyRemoveBreakpointFailed, p);
}
void IPCEngineGuest::notifyChangeBreakpointOk(BreakpointModelId id)
{
QByteArray p;
{
QDataStream s(&p, QIODevice::WriteOnly);
SET_NATIVE_BYTE_ORDER(s);
s << id;
}
rpcCall(NotifyChangeBreakpointOk, p);
}
void IPCEngineGuest::notifyChangeBreakpointFailed(BreakpointModelId id)
{
QByteArray p;
{
QDataStream s(&p, QIODevice::WriteOnly);
SET_NATIVE_BYTE_ORDER(s);
s << id;
}
rpcCall(NotifyChangeBreakpointFailed, p);
}
void IPCEngineGuest::notifyBreakpointAdjusted(BreakpointModelId id,
const BreakpointParameters &bp)
{
QByteArray p;
{
QDataStream s(&p, QIODevice::WriteOnly);
SET_NATIVE_BYTE_ORDER(s);
s << id << bp;
}
rpcCall(NotifyBreakpointAdjusted, p);
}
void IPCEngineGuest::updateWatchData(bool fullCycle, const QList<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);
}
void IPCEngineGuest::frameSourceFetched(qint64 id, const QString &name, const QString &source)
{
QByteArray p;
{
QDataStream s(&p, QIODevice::WriteOnly);
SET_NATIVE_BYTE_ORDER(s);
s << id;
s << name;
s << source;
}
rpcCall(FrameSourceFetched, p);
}
} // namespace Internal
} // namespace Debugger

View File

@@ -1,191 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef IPCENGINEGUEST_H
#define IPCENGINEGUEST_H
#include <debugger/breakhandler.h>
#include <debugger/debuggerengine.h>
#include <debugger/disassemblerlines.h>
#include <debugger/stackhandler.h>
#include <debugger/threadshandler.h>
#include <QQueue>
#include <QThread>
#include <QVariant>
namespace Debugger {
namespace Internal {
class IPCEngineHost;
class IPCEngineGuest : public QObject
{
Q_OBJECT
public:
IPCEngineGuest();
virtual ~IPCEngineGuest();
void setLocalHost(IPCEngineHost *);
void setHostDevice(QIODevice *);
virtual void nuke() = 0;
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 ContextData &data) = 0;
virtual void executeRunToFunction(const QString &functionName) = 0;
virtual void executeJumpToLine(const ContextData &data) = 0;
virtual void activateFrame(qint64 token) = 0;
virtual void selectThread(qint64 token) = 0;
virtual void disassemble(quint64 pc) = 0;
virtual void addBreakpoint(BreakpointModelId id, const BreakpointParameters &bp) = 0;
virtual void removeBreakpoint(BreakpointModelId id) = 0;
virtual void changeBreakpoint(BreakpointModelId id, const BreakpointParameters &bp) = 0;
virtual void requestUpdateWatchData(const WatchData &data,
const WatchUpdateFlags & flags = WatchUpdateFlags()) = 0;
virtual void fetchFrameSource(qint64 frame) = 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,
FrameSourceFetched = 48
};
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 = quint64(-1));
void showStatusMessage(const QString &msg, quint64 timeout = quint64(-1));
void currentFrameChanged(qint64 token);
void currentThreadChanged(qint64 token);
void listFrames(const StackFrames &);
void listThreads(const Threads &);
void disassembled(quint64 pc, const DisassemblerLines &da);
void notifyAddBreakpointOk(BreakpointModelId id);
void notifyAddBreakpointFailed(BreakpointModelId id);
void notifyRemoveBreakpointOk(BreakpointModelId id);
void notifyRemoveBreakpointFailed(BreakpointModelId id);
void notifyChangeBreakpointOk(BreakpointModelId id);
void notifyChangeBreakpointFailed(BreakpointModelId id);
void notifyBreakpointAdjusted(BreakpointModelId id, const BreakpointParameters &bp);
void updateWatchData(bool fullCycle, const QList<WatchData> &);
void frameSourceFetched(qint64 frame, const QString &name, const QString &sourceCode);
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 // IPCENGINEGUEST_H

View File

@@ -1,661 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "ipcenginehost.h"
#include "ipcengineguest.h"
#include <debugger/debuggerstartparameters.h>
#include <debugger/breakhandler.h>
#include <debugger/breakpoint.h>
#include <debugger/disassemblerlines.h>
#include <debugger/moduleshandler.h>
#include <debugger/registerhandler.h>
#include <debugger/stackhandler.h>
#include <debugger/watchhandler.h>
#include <debugger/watchutils.h>
#include <debugger/threadshandler.h>
#include <debugger/disassembleragent.h>
#include <debugger/memoryagent.h>
#include <debugger/debuggerstreamops.h>
#include <debugger/debuggercore.h>
#include <utils/qtcassert.h>
#include <QSysInfo>
#include <QDebug>
#include <QFileInfo>
#include <QTimer>
#include <QLocalSocket>
#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_localGuest(0)
, m_nextMessagePayloadSize(0)
, m_cookie(1)
, m_device(0)
{
connect(this, SIGNAL(stateChanged(Debugger::DebuggerState)), SLOT(m_stateChanged(Debugger::DebuggerState)));
}
IPCEngineHost::~IPCEngineHost()
{
delete m_device;
}
void IPCEngineHost::setLocalGuest(IPCEngineGuest *guest)
{
m_localGuest = guest;
}
void IPCEngineHost::setGuestDevice(QIODevice *device)
{
if (m_device) {
disconnect(m_device, SIGNAL(readyRead()), this, SLOT(readyRead()));
delete m_device;
}
m_device = device;
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.toStringList();
}
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 ContextData &data)
{
QByteArray p;
{
QDataStream s(&p, QIODevice::WriteOnly);
SET_NATIVE_BYTE_ORDER(s);
s << data.fileName;
s << quint64(data.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 ContextData &data)
{
QByteArray p;
{
QDataStream s(&p, QIODevice::WriteOnly);
SET_NATIVE_BYTE_ORDER(s);
s << data.fileName;
s << quint64(data.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(ThreadId id)
{
resetLocation();
QTC_ASSERT(id.isValid(), return);
QByteArray p;
{
QDataStream s(&p, QIODevice::WriteOnly);
SET_NATIVE_BYTE_ORDER(s);
s << id.raw();
}
rpcCall(SelectThread, p);
}
void IPCEngineHost::fetchDisassembler(DisassemblerAgent *v)
{
quint64 address = v->location().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::insertBreakpoint(BreakpointModelId id)
{
breakHandler()->notifyBreakpointInsertProceeding(id);
QByteArray p;
{
QDataStream s(&p, QIODevice::WriteOnly);
SET_NATIVE_BYTE_ORDER(s);
s << id;
s << breakHandler()->breakpointData(id);
}
rpcCall(AddBreakpoint, p);
}
void IPCEngineHost::removeBreakpoint(BreakpointModelId id)
{
breakHandler()->notifyBreakpointRemoveProceeding(id);
QByteArray p;
{
QDataStream s(&p, QIODevice::WriteOnly);
SET_NATIVE_BYTE_ORDER(s);
s << id;
}
rpcCall(RemoveBreakpoint, p);
}
void IPCEngineHost::changeBreakpoint(BreakpointModelId id)
{
breakHandler()->notifyBreakpointChangeProceeding(id);
QByteArray p;
{
QDataStream s(&p, QIODevice::WriteOnly);
SET_NATIVE_BYTE_ORDER(s);
s << id;
s << breakHandler()->breakpointData(id);
}
rpcCall(RemoveBreakpoint, p);
}
void IPCEngineHost::updateWatchData(const WatchData &data,
const WatchUpdateFlags &flags)
{
Q_UNUSED(flags);
QByteArray p;
{
QDataStream s(&p, QIODevice::WriteOnly);
SET_NATIVE_BYTE_ORDER(s);
s << data;
}
rpcCall(RequestUpdateWatchData, p);
}
void IPCEngineHost::fetchFrameSource(qint64 id)
{
QByteArray p;
{
QDataStream s(&p, QIODevice::WriteOnly);
SET_NATIVE_BYTE_ORDER(s);
s << id;
}
rpcCall(FetchFrameSource, p);
}
void IPCEngineHost::rpcCallback(quint64 f, QByteArray payload)
{
switch (f) {
default: {
showMessage(QLatin1String("IPC Error: unhandled id in guest to host call"));
const QString logMessage = tr("Fatal engine shutdown. Incompatible binary or IPC error.");
showMessage(logMessage, LogError);
showStatusMessage(logMessage);
}
nuke();
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);
if (!sh->currentFrame().isUsable() || QFileInfo(sh->currentFrame().file).exists())
gotoLocation(Location(sh->currentFrame(), true));
else if (!m_sourceAgents.contains(sh->currentFrame().file))
fetchFrameSource(token);
foreach (SourceAgent *agent, m_sourceAgents.values())
agent->updateLocationMarker();
}
break;
case IPCEngineGuest::CurrentThreadChanged:
{
QDataStream s(payload);
SET_NATIVE_BYTE_ORDER(s);
quint64 token;
s >> token;
threadsHandler()->setCurrentThread(ThreadId(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;
DisassemblerLines lines;
s >> pc;
s >> lines;
DisassemblerAgent *view = m_frameToDisassemblerAgent.take(pc);
if (view)
view->setContents(lines);
}
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->insertData(wd);
}
break;
case IPCEngineGuest::NotifyAddBreakpointOk:
{
attemptBreakpointSynchronization();
QDataStream s(payload);
SET_NATIVE_BYTE_ORDER(s);
quint64 d;
s >> d;
BreakpointModelId id = BreakpointModelId::fromInternalId(d);
breakHandler()->notifyBreakpointInsertOk(id);
}
break;
case IPCEngineGuest::NotifyAddBreakpointFailed:
{
QDataStream s(payload);
SET_NATIVE_BYTE_ORDER(s);
quint64 d;
s >> d;
BreakpointModelId id = BreakpointModelId::fromInternalId(d);
breakHandler()->notifyBreakpointInsertFailed(id);
}
break;
case IPCEngineGuest::NotifyRemoveBreakpointOk:
{
QDataStream s(payload);
SET_NATIVE_BYTE_ORDER(s);
quint64 d;
s >> d;
BreakpointModelId id = BreakpointModelId::fromInternalId(d);
breakHandler()->notifyBreakpointRemoveOk(id);
}
break;
case IPCEngineGuest::NotifyRemoveBreakpointFailed:
{
QDataStream s(payload);
SET_NATIVE_BYTE_ORDER(s);
quint64 d;
s >> d;
BreakpointModelId id = BreakpointModelId::fromInternalId(d);
breakHandler()->notifyBreakpointRemoveFailed(id);
}
break;
case IPCEngineGuest::NotifyChangeBreakpointOk:
{
QDataStream s(payload);
SET_NATIVE_BYTE_ORDER(s);
quint64 d;
s >> d;
BreakpointModelId id = BreakpointModelId::fromInternalId(d);
breakHandler()->notifyBreakpointChangeOk(id);
}
break;
case IPCEngineGuest::NotifyChangeBreakpointFailed:
{
QDataStream s(payload);
SET_NATIVE_BYTE_ORDER(s);
quint64 d;
s >> d;
BreakpointModelId id = BreakpointModelId::fromInternalId(d);
breakHandler()->notifyBreakpointChangeFailed(id);
}
break;
case IPCEngineGuest::NotifyBreakpointAdjusted:
{
QDataStream s(payload);
SET_NATIVE_BYTE_ORDER(s);
quint64 dd;
BreakpointParameters d;
s >> dd >> d;
BreakpointModelId id = BreakpointModelId::fromInternalId(dd);
breakHandler()->notifyBreakpointAdjusted(id, d);
}
break;
case IPCEngineGuest::FrameSourceFetched:
{
QDataStream s(payload);
SET_NATIVE_BYTE_ORDER(s);
qint64 token;
QString path;
QString source;
s >> token >> path >> source;
SourceAgent *agent = new SourceAgent(this);
agent->setSourceProducerName(startParameters().connParams.host);
agent->setContent(path, source);
m_sourceAgents.insert(path, agent);
agent->updateLocationMarker();
}
break;
}
}
void IPCEngineHost::m_stateChanged(Debugger::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_localGuest) {
QMetaObject::invokeMethod(m_localGuest,
"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');
QLocalSocket *sock = qobject_cast<QLocalSocket *>(m_device);
if (sock)
sock->flush();
}
}
void IPCEngineHost::readyRead()
{
QDataStream s(m_device);
SET_NATIVE_BYTE_ORDER(s);
if (!m_nextMessagePayloadSize) {
if (quint64(m_device->bytesAvailable ()) < 3 * sizeof(quint64))
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"));
nuke();
return;
}
rpcCallback(m_nextMessageFunction, payload);
m_nextMessagePayloadSize = 0;
if (quint64(m_device->bytesAvailable()) >= 3 * sizeof(quint64))
QTimer::singleShot(0, this, SLOT(readyRead()));
}
} // namespace Internal
} // namespace Debugger

View File

@@ -1,140 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef DEBUGGER_IPCENGINE_HOST_H
#define DEBUGGER_IPCENGINE_HOST_H
#include <debugger/debuggerengine.h>
#include <debugger/threadshandler.h>
#include <debugger/stackhandler.h>
#include <debugger/breakhandler.h>
#include <debugger/sourceagent.h>
#include <QQueue>
#include <QVariant>
#include <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,
FetchFrameSource = 26
};
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 ContextData &data);
void executeRunToFunction(const QString &functionName);
void executeJumpToLine(const ContextData &data);
void activateFrame(int index);
void selectThread(ThreadId index);
void fetchDisassembler(DisassemblerAgent *);
bool acceptsBreakpoint(BreakpointModelId) const { return true; } // FIXME
void insertBreakpoint(BreakpointModelId id);
void removeBreakpoint(BreakpointModelId id);
void changeBreakpoint(BreakpointModelId id);
void updateWatchData(const WatchData &data,
const WatchUpdateFlags &flags = WatchUpdateFlags());
void fetchFrameSource(qint64 id);
bool hasCapability(unsigned) const { return false; }
void rpcCall(Function f, QByteArray payload = QByteArray());
protected:
virtual void nuke() = 0;
public slots:
void rpcCallback(quint64 f, QByteArray payload = QByteArray());
private slots:
void m_stateChanged(Debugger::DebuggerState state);
void readyRead();
private:
IPCEngineGuest *m_localGuest;
quint64 m_nextMessageCookie;
quint64 m_nextMessageFunction;
quint64 m_nextMessagePayloadSize;
quint64 m_cookie;
QIODevice *m_device;
QHash<quint64, DisassemblerAgent *> m_frameToDisassemblerAgent;
QHash<QString, SourceAgent *> m_sourceAgents;
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGER_LLDBENGINE_H

View File

@@ -1,232 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "lldbenginehost.h"
#include <debugger/debuggerstartparameters.h>
#include <debugger/debuggeractions.h>
#include <debugger/debuggerconstants.h>
#include <debugger/debuggerdialogs.h>
#include <debugger/debuggerplugin.h>
#include <debugger/debuggerstringutils.h>
#include <debugger/breakhandler.h>
#include <debugger/breakpoint.h>
#include <debugger/moduleshandler.h>
#include <debugger/registerhandler.h>
#include <debugger/stackhandler.h>
#include <debugger/watchhandler.h>
#include <debugger/watchutils.h>
#include <debugger/threadshandler.h>
#include <debugger/disassembleragent.h>
#include <debugger/memoryagent.h>
#include <coreplugin/icore.h>
#include <utils/qtcassert.h>
#include <QDebug>
#include <QProcess>
#include <QFileInfo>
#include <QThread>
#include <QCoreApplication>
namespace Debugger {
namespace Internal {
SshIODevice::SshIODevice(QSsh::SshRemoteProcessRunner *r)
: runner(r)
, buckethead(0)
{
setOpenMode(QIODevice::ReadWrite | QIODevice::Unbuffered);
connect (runner, SIGNAL(processStarted()), this, SLOT(processStarted()));
connect(runner, SIGNAL(readyReadStandardOutput()), this, SLOT(outputAvailable()));
connect(runner, SIGNAL(readyReadStandardError()), this, SLOT(errorOutputAvailable()));
}
SshIODevice::~SshIODevice()
{
delete runner;
}
qint64 SshIODevice::bytesAvailable () const
{
qint64 r = QIODevice::bytesAvailable();
foreach (const QByteArray &bucket, buckets)
r += bucket.size();
r-= buckethead;
return r;
}
qint64 SshIODevice::writeData (const char * data, qint64 maxSize)
{
if (proc == 0) {
startupbuffer += QByteArray::fromRawData(data, maxSize);
return maxSize;
}
proc->write(data, maxSize);
return maxSize;
}
qint64 SshIODevice::readData (char * data, qint64 maxSize)
{
if (proc == 0)
return 0;
qint64 size = maxSize;
while (size > 0) {
if (!buckets.size())
return maxSize - size;
QByteArray &bucket = buckets.head();
if ((size + buckethead) >= bucket.size()) {
int d = bucket.size() - buckethead;
memcpy(data, bucket.data() + buckethead, d);
data += d;
size -= d;
buckets.dequeue();
buckethead = 0;
} else {
memcpy(data, bucket.data() + buckethead, size);
data += size;
buckethead += size;
size = 0;
}
}
return maxSize - size;
}
void SshIODevice::processStarted()
{
runner->writeDataToProcess(startupbuffer);
}
void SshIODevice::outputAvailable()
{
buckets.enqueue(runner->readAllStandardOutput());
emit readyRead();
}
void SshIODevice::errorOutputAvailable()
{
fprintf(stderr, "%s", runner->readAllStandardError().data());
}
LldbEngineHost::LldbEngineHost(const DebuggerStartParameters &startParameters)
:IPCEngineHost(startParameters), m_ssh(0)
{
showMessage(QLatin1String("setting up coms"));
setObjectName(QLatin1String("LLDBEngine"));
if (startParameters.startMode == StartRemoteEngine)
{
m_guestProcess = 0;
QSsh::SshRemoteProcessRunner * const runner = new QSsh::SshRemoteProcessRunner;
connect (runner, SIGNAL(connectionError(QSsh::SshError)),
this, SLOT(sshConnectionError(QSsh::SshError)));
runner->run(startParameters.serverStartScript.toUtf8(), startParameters.connParams);
setGuestDevice(new SshIODevice(runner));
} else {
m_guestProcess = new QProcess(this);
connect(m_guestProcess, SIGNAL(finished(int,QProcess::ExitStatus)),
this, SLOT(finished(int,QProcess::ExitStatus)));
connect(m_guestProcess, SIGNAL(readyReadStandardError()), this,
SLOT(stderrReady()));
QString a = Core::ICore::resourcePath() + QLatin1String("/qtcreator-lldb");
if (getenv("QTC_LLDB_GUEST") != 0)
a = QString::fromLocal8Bit(getenv("QTC_LLDB_GUEST"));
showStatusMessage(QString(QLatin1String("starting %1")).arg(a));
m_guestProcess->start(a, QStringList(), QIODevice::ReadWrite | QIODevice::Unbuffered);
m_guestProcess->setReadChannel(QProcess::StandardOutput);
if (!m_guestProcess->waitForStarted()) {
showStatusMessage(tr("qtcreator-lldb failed to start: %1").arg(m_guestProcess->errorString()));
notifyEngineSpontaneousShutdown();
return;
}
setGuestDevice(m_guestProcess);
}
}
LldbEngineHost::~LldbEngineHost()
{
showMessage(QLatin1String("tear down qtcreator-lldb"));
if (m_guestProcess) {
disconnect(m_guestProcess, SIGNAL(finished(int,QProcess::ExitStatus)),
this, SLOT(finished(int,QProcess::ExitStatus)));
m_guestProcess->terminate();
m_guestProcess->kill();
}
if (m_ssh && m_ssh->isProcessRunning()) {
// TODO: openssh doesn't do that
m_ssh->sendSignalToProcess(QSsh::SshRemoteProcess::KillSignal);
}
}
void LldbEngineHost::nuke()
{
stderrReady();
showMessage(QLatin1String("Nuke engaged. Bug in Engine/IPC or incompatible IPC versions. "), LogError);
showStatusMessage(tr("Fatal engine shutdown. Consult debugger log for details."));
m_guestProcess->terminate();
m_guestProcess->kill();
notifyEngineSpontaneousShutdown();
}
void LldbEngineHost::sshConnectionError(QSsh::SshError e)
{
showStatusMessage(tr("SSH connection error: %1").arg(e));
}
void LldbEngineHost::finished(int, QProcess::ExitStatus status)
{
showMessage(QString(QLatin1String("guest went bye bye. exit status: %1 and code: %2"))
.arg(status).arg(m_guestProcess->exitCode()), LogError);
nuke();
}
void LldbEngineHost::stderrReady()
{
fprintf(stderr,"%s", m_guestProcess->readAllStandardError().data());
}
DebuggerEngine *createLldbLibEngine(const DebuggerStartParameters &startParameters)
{
return new LldbEngineHost(startParameters);
}
} // namespace Internal
} // namespace Debugger

View File

@@ -1,88 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef DEBUGGER_LLDBENGINE_HOST_H
#define DEBUGGER_LLDBENGINE_HOST_H
#include "ipcenginehost.h"
#include <ssh/ssherrors.h>
#include <ssh/sshconnection.h>
#include <ssh/sshremoteprocess.h>
#include <ssh/sshremoteprocessrunner.h>
#include <QProcess>
#include <QQueue>
namespace Debugger {
namespace Internal {
class SshIODevice : public QIODevice
{
Q_OBJECT
public:
SshIODevice(QSsh::SshRemoteProcessRunner *r);
~SshIODevice();
virtual qint64 bytesAvailable () const;
virtual qint64 writeData (const char * data, qint64 maxSize);
virtual qint64 readData (char * data, qint64 maxSize);
private slots:
void processStarted();
void outputAvailable();
void errorOutputAvailable();
private:
QSsh::SshRemoteProcessRunner *runner;
QSsh::SshRemoteProcess::Ptr proc;
int buckethead;
QQueue<QByteArray> buckets;
QByteArray startupbuffer;
};
class LldbEngineHost : public IPCEngineHost
{
Q_OBJECT
public:
explicit LldbEngineHost(const DebuggerStartParameters &startParameters);
~LldbEngineHost();
private:
QProcess *m_guestProcess;
QSsh::SshRemoteProcessRunner *m_ssh;
protected:
void nuke();
private slots:
void sshConnectionError(QSsh::SshError);
void finished(int, QProcess::ExitStatus);
void stderrReady();
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGER_LLDBENGINE_HOST_H

View File

@@ -1,20 +0,0 @@
WITH_LLDB = $$(WITH_LLDB)
HEADERS += $$PWD/ipcenginehost.h \
$$PWD/lldbenginehost.h
SOURCES += $$PWD/ipcenginehost.cpp \
$$PWD/lldbenginehost.cpp
INCLUDEPATH+=
FORMS +=
RESOURCES +=
!isEmpty(WITH_LLDB) {
DEFINES += WITH_LLDB
HEADERS += $$PWD/lldboptionspage.h
SOURCES += $$PWD/lldboptionspage.cpp
FORMS += $$PWD/lldboptionspagewidget.ui
}

View File

@@ -1,109 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "lldboptionspage.h"
#include <debugger/debuggerconstants.h>
#include <debugger/debuggerinternalconstants.h>
#include <coreplugin/icore.h>
#include <QCoreApplication>
#include <QUrl>
#include <QTextStream>
#include <QMessageBox>
#include <QDesktopServices>
namespace Debugger {
namespace Internal {
LldbOptionsPageWidget::LldbOptionsPageWidget(QWidget *parent, QSettings *s_)
: QWidget(parent)
, s(s_)
{
m_ui.setupUi(this);
load();
}
void LldbOptionsPageWidget::save()
{
s->beginGroup(QLatin1String("LLDB"));
s->setValue(QLatin1String("enabled"), m_ui.enableLldb->isChecked ());
s->setValue(QLatin1String("gdbEmu"), m_ui.gdbEmu->isChecked ());
s->endGroup();
}
void LldbOptionsPageWidget::load()
{
s->beginGroup(QLatin1String("LLDB"));
m_ui.enableLldb->setChecked(s->value(QLatin1String("enabled"), false).toBool());
m_ui.gdbEmu->setChecked(s->value(QLatin1String("gdbEmu"), true).toBool());
s->endGroup();
}
// ---------- LldbOptionsPage
LldbOptionsPage::LldbOptionsPage()
{
// m_options->fromSettings(Core::ICore::settings());
setId("F.Lldb");
setDisplayName(tr("LLDB"));
setCategory(Debugger::Constants::DEBUGGER_SETTINGS_CATEGORY);
setDisplayCategory(QCoreApplication::translate("Debugger", Constants::DEBUGGER_SETTINGS_TR_CATEGORY));
setCategoryIcon(QLatin1String(Constants::DEBUGGER_COMMON_SETTINGS_CATEGORY_ICON));
}
QWidget *LldbOptionsPage::createPage(QWidget *parent)
{
m_widget = new LldbOptionsPageWidget(parent, Core::ICore::settings());
return m_widget;
}
void LldbOptionsPage::apply()
{
if (!m_widget)
return;
m_widget->save();
}
void LldbOptionsPage::finish()
{
}
bool LldbOptionsPage::matches(const QString &s) const
{
return QString(s.toLower()).contains(QLatin1String("lldb"));
}
void addLldbOptionPages(QList<Core::IOptionsPage *> *opts)
{
opts->push_back(new LldbOptionsPage);
}
} // namespace Internal
} // namespace Debugger

View File

@@ -1,80 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef LLDBOPTIONSPAGE_H
#define LLDBOPTIONSPAGE_H
#include <coreplugin/dialogs/ioptionspage.h>
#include "ui_lldboptionspagewidget.h"
#include <QWidget>
#include <QPointer>
#include <QSharedPointer>
#include <QSettings>
namespace Debugger {
namespace Internal {
class LldbOptionsPageWidget : public QWidget
{
Q_OBJECT
public:
explicit LldbOptionsPageWidget(QWidget *parent, QSettings *s);
public slots:
void save();
void load();
private:
Ui::LldbOptionsPageWidget m_ui;
QSettings *s;
};
class LldbOptionsPage : public Core::IOptionsPage
{
Q_OBJECT
public:
LldbOptionsPage();
// IOptionsPage
QWidget *createPage(QWidget *parent);
void apply();
void finish();
bool matches(const QString &) const;
private:
QPointer<LldbOptionsPageWidget> m_widget;
};
} // namespace Internal
} // namespace Debugger
#endif // LLDBOPTIONSPAGE_H

View File

@@ -1,59 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Debugger::Internal::LldbOptionsPageWidget</class>
<widget class="QWidget" name="Debugger::Internal::LldbOptionsPageWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>522</width>
<height>512</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout"/>
</item>
<item>
<widget class="QGroupBox" name="enableLldb">
<property name="title">
<string>Enable LLDB</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QCheckBox" name="gdbEmu">
<property name="text">
<string>Use GDB Python dumpers</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>203</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -87,5 +87,3 @@ SUBDIRS += debugger/dumper.pro
linux-* { linux-* {
SUBDIRS += debugger/ptracepreload.pro SUBDIRS += debugger/ptracepreload.pro
} }
include (debugger/lldblib/guest/qtcreator-lldb.pri)