Commit aa39916c authored by hjk's avatar hjk
Browse files

Debugger: Invert LLDB/Python startup order



Instead of starting LLDB through a Python script this now starts
LLDB directly. This did not work a while ago but seems fine nowaday.

Change-Id: I20e915070cd6addf260817c311f4160d010aa861
Reviewed-by: default avatarEike Ziller <eike.ziller@theqtcompany.com>
Reviewed-by: default avatarhjk <hjk@theqtcompany.com>
parent b23182fc
......@@ -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()
......@@ -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();
......
......@@ -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)();
......
......@@ -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();
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment