diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index 8ac4413d512b1c00a2b92f4afe38e7634a1f7ad2..f1ef9e709bc7595437f7ea1945282013b379d418 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -30,44 +30,19 @@ import atexit import inspect -import json import os import platform import re -import select import sys import subprocess import threading +import lldb currentDir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) sys.path.insert(1, currentDir) from dumper import * -lldbCmd = 'lldb' -if len(sys.argv) > 1: - lldbCmd = sys.argv[1] - -proc = subprocess.Popen(args=[lldbCmd, '-P'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) -(path, error) = proc.communicate() - -if error.startswith('lldb: invalid option -- P'): - sys.stdout.write('msg=\'Could not run "%s -P". Trying to find lldb.so from Xcode.\'@\n' % lldbCmd) - proc = subprocess.Popen(args=['xcode-select', '--print-path'], - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - (path, error) = proc.communicate() - if len(error): - path = '/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/Resources/Python/' - sys.stdout.write('msg=\'Could not run "xcode-select --print-path"@\n') - sys.stdout.write('msg=\'Using hardcoded fallback at %s\'@\n' % path) - else: - path = path.strip() + '/../SharedFrameworks/LLDB.framework/Versions/A/Resources/Python/' - sys.stdout.write('msg=\'Using fallback at %s\'@\n' % path) - -sys.path.insert(1, path.strip()) - -import lldb - ####################################################################### # # Helpers @@ -667,6 +642,9 @@ class Dumper(DumperBase): else: self.target = self.debugger.CreateTarget(None, None, None, True, error) + if self.target.IsValid(): + self.handleBreakpoints(args) + state = "inferiorsetupok" if self.target.IsValid() else "inferiorsetupfailed" self.report('state="%s",msg="%s",exe="%s"' % (state, error, self.executable_)) @@ -1193,7 +1171,7 @@ class Dumper(DumperBase): def report(self, stuff): with self.outputLock: - sys.stdout.write(stuff + "@\n") + sys.stdout.write("@\n" + stuff + "@\n") def reportStatus(self, msg): self.report('statusmessage="%s"' % msg) @@ -1573,7 +1551,7 @@ class Dumper(DumperBase): self.report('success="%d",output="%s",error="%s"' % (success, output, error)) def addExtraDumper(self, args): - addDumperModule(args['path']) + self.addDumperModule(args['path']) self.report('ok') def updateData(self, args): @@ -1662,14 +1640,6 @@ class Dumper(DumperBase): self.reportError(error) self.reportVariables() - def execute(self, args): - getattr(self, args['cmd'])(args) - self.report('token="%s"' % args['token']) - if 'continuation' in args: - cont = args['continuation'] - self.report('continuation="%s"' % cont) - - def convertHash(args): if sys.version_info[0] == 3: return args @@ -1693,36 +1663,19 @@ def convertHash(args): return cargs -def doit(): - - db = Dumper() - db.report('lldbversion="%s"' % lldb.SBDebugger.GetVersionString()) - db.reportState("enginesetupok") - - line = sys.stdin.readline() - while line: - try: - db.execute(convertHash(json.loads(line))) - except: - (exType, exValue, exTraceback) = sys.exc_info() - showException("MAIN LOOP", exType, exValue, exTraceback) - line = sys.stdin.readline() - - # Used in dumper auto test. # Usage: python lldbbridge.py /path/to/testbinary comma-separated-inames class Tester(Dumper): - def __init__(self): + def __init__(self, binary, expandedINames): Dumper.__init__(self) lldb.theDumper = self - self.expandedINames = set(sys.argv[3].split(',')) + self.expandedINames = set(expandedINames) self.passExceptions = True self.loadDumperFiles() error = lldb.SBError() - self.target = self.debugger.CreateTarget(sys.argv[2], - None, None, True, error) + self.target = self.debugger.CreateTarget(binary, None, None, True, error) if error.GetType(): warn("ERROR: %s" % error) @@ -1730,6 +1683,7 @@ class Tester(Dumper): s = threading.Thread(target=self.testLoop, args=[]) s.start() + s.join(30) def testLoop(self): # Disable intermediate reporting. @@ -1801,11 +1755,3 @@ class Tester(Dumper): #self.report("ENV=%s" % os.environ.items()) #self.report("DUMPER=%s" % self.qqDumpers) lldb.SBDebugger.Destroy(self.debugger) - - -if __name__ == "__main__": - if len(sys.argv) > 2: - Tester() - else: - doit() - diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index 16d2190ecf1148784102b3606deb6443853497b0..427e4a975ada9f63aff3539a25727b9b4482d1c8 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -129,10 +129,9 @@ void LldbEngine::runCommand(const Command &command) QTC_ASSERT(m_lldbProc.state() == QProcess::Running, notifyEngineIll()); ++m_lastToken; QByteArray token = QByteArray::number(m_lastToken); - QByteArray cmd = "{\"cmd\":\"" + command.function + "\"," - + command.args + "\"token\":" + token + "}\n"; - showMessage(_(token + cmd), LogInput); - m_lldbProc.write(cmd); + QByteArray cmd = command.function + "({" + command.args + "})"; + showMessage(_(token + cmd + '\n'), LogInput); + m_lldbProc.write("sc db." + cmd + "\n"); } void LldbEngine::debugLastCommand() @@ -246,16 +245,12 @@ void LldbEngine::startLldb() connect(this, &LldbEngine::outputReady, this, &LldbEngine::handleResponse, Qt::QueuedConnection); - QStringList args; - args.append(_("-i")); - args.append(ICore::resourcePath() + _("/debugger/lldbbridge.py")); - args.append(m_lldbCmd); - showMessage(_("STARTING LLDB: python ") + args.join(QLatin1Char(' '))); + showMessage(_("STARTING LLDB: ") + m_lldbCmd); m_lldbProc.setEnvironment(startParameters().environment.toStringList()); if (!startParameters().workingDirectory.isEmpty()) m_lldbProc.setWorkingDirectory(startParameters().workingDirectory); - m_lldbProc.start(_("python"), args); + m_lldbProc.start(m_lldbCmd); if (!m_lldbProc.waitForStarted()) { const QString msg = tr("Unable to start LLDB \"%1\": %2") @@ -265,6 +260,21 @@ void LldbEngine::startLldb() if (!msg.isEmpty()) ICore::showWarningWithOptions(tr("Adapter start failed."), msg); } + + showMessage(_("ADAPTER STARTED")); + showStatusMessage(tr("Setting up inferior...")); + + const QByteArray dumperSourcePath = + ICore::resourcePath().toLocal8Bit() + "/debugger/"; + + m_lldbProc.write("sc sys.path.insert(1, '" + dumperSourcePath + "')\n"); + m_lldbProc.write("sc from lldbbridge import *\n"); + m_lldbProc.write("sc print(dir())\n"); + m_lldbProc.write("sc db = Dumper()\n"); + m_lldbProc.write("sc db.report('lldbversion=\"%s\"' % lldb.SBDebugger.GetVersionString())\n"); + + showMessage(_("ENGINE SUCCESSFULLY STARTED")); + notifyEngineSetupOk(); } void LldbEngine::setupInferior() @@ -299,6 +309,8 @@ void LldbEngine::setupInferior() cmd.arg("useTerminal", sp.useTerminal); cmd.arg("startMode", sp.startMode); + attemptBreakpointSynchronizationHelper(&cmd); + cmd.beginList("processArgs"); foreach (const QString &arg, args.toUnixArgs()) cmd.arg(arg.toUtf8().toHex()); @@ -338,19 +350,7 @@ void LldbEngine::setupInferior() void LldbEngine::runEngine() { - QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); - - Command cmd("handleBreakpoints"); - if (attemptBreakpointSynchronizationHelper(&cmd)) { - runEngine2(); - } else { - cmd.arg("continuation", "runEngine2"); - runCommand(cmd); - } -} - -void LldbEngine::runEngine2() -{ + QTC_ASSERT(state() == EngineRunRequested, qDebug() << state(); return); showStatusMessage(tr("Running requested..."), 5000); runCommand("runEngine"); } @@ -446,8 +446,6 @@ void LldbEngine::handleResponse(const QByteArray &response) refreshDisassembly(item); else if (name == "memory") refreshMemory(item); - else if (name == "continuation") - runContinuation(item); else if (name == "full-backtrace") showFullBacktrace(item); else if (name == "statusmessage") { @@ -465,12 +463,6 @@ void LldbEngine::showFullBacktrace(const GdbMi &data) QString::fromUtf8(QByteArray::fromHex(data.data()))); } -void LldbEngine::runContinuation(const GdbMi &data) -{ - const QByteArray target = data.data(); - QMetaObject::invokeMethod(this, target, Qt::QueuedConnection); -} - void LldbEngine::executeRunToLine(const ContextData &data) { resetLocation(); diff --git a/src/plugins/debugger/lldb/lldbengine.h b/src/plugins/debugger/lldb/lldbengine.h index 81be06af4979950461ade30dc32af1df237544e7..dd20dfebb9c33e423c34b76519af64125c72e299 100644 --- a/src/plugins/debugger/lldb/lldbengine.h +++ b/src/plugins/debugger/lldb/lldbengine.h @@ -161,7 +161,6 @@ private: Q_SLOT void readLldbStandardOutput(); Q_SLOT void readLldbStandardError(); Q_SLOT void handleResponse(const QByteArray &data); - Q_SLOT void runEngine2(); Q_SLOT void updateAll(); Q_SLOT void updateStack(); Q_SLOT void updateLocals(); @@ -184,7 +183,6 @@ private: void refreshAddedBreakpoint(const GdbMi &bkpts); void refreshChangedBreakpoint(const GdbMi &bkpts); void refreshRemovedBreakpoint(const GdbMi &bkpts); - void runContinuation(const GdbMi &data); void showFullBacktrace(const GdbMi &data); typedef void (LldbEngine::*LldbCommandContinuation)(); diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 94d3ff32e2e96498fb0ac4d9ef584470abd84aa3..ed0b92788f9428edf9f94c5546fa2d5bb3db02a9 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -1210,13 +1210,11 @@ void tst_Dumpers::dumper() expanded += iname; } - QByteArray exe; + QByteArray exe = m_debuggerBinary; QStringList args; QByteArray cmds; if (m_debuggerEngine == GdbEngine) { - exe = m_debuggerBinary; - const QFileInfo gdbBinaryFile(QString::fromLatin1(exe)); const QByteArray uninstalledData = gdbBinaryFile.absolutePath().toLocal8Bit() + "/data-directory/python"; @@ -1245,7 +1243,6 @@ void tst_Dumpers::dumper() cmds += "quit\n"; } else if (m_debuggerEngine == CdbEngine) { - exe = m_debuggerBinary; args << QLatin1String("-aqtcreatorcdbext.dll") << QLatin1String("-G") << QLatin1String("-xi") @@ -1258,15 +1255,19 @@ void tst_Dumpers::dumper() cmds += "!qtcreatorcdbext.locals -t -D -e " + expanded + " -v -c 0\n" "q\n"; } else if (m_debuggerEngine == LldbEngine) { - exe = "python"; - args << QLatin1String(dumperDir + "/lldbbridge.py") - << QString::fromUtf8(m_debuggerBinary) - << t->buildPath + QLatin1String("/doit") - << QString::fromUtf8(expanded); QFile fullLldb(t->buildPath + QLatin1String("/lldbcommand.txt")); fullLldb.setPermissions(QFile::ReadOwner|QFile::WriteOwner|QFile::ExeOwner|QFile::ReadGroup|QFile::ReadOther); fullLldb.open(QIODevice::WriteOnly); - fullLldb.write(exe + ' ' + args.join(QLatin1String(" ")).toUtf8()); + fullLldb.write(exe + ' ' + args.join(QLatin1String(" ")).toUtf8() + '\n'); + + cmds = "sc import sys\n" + "sc sys.path.insert(1, '" + dumperDir + "')\n" + "sc from lldbbridge import *\n" + "sc print(dir())\n" + "sc Tester('" + t->buildPath.toLatin1() + "/doit', '" + expanded + "')\n" + "quit\n"; + + fullLldb.write(cmds); fullLldb.close(); }