forked from qt-creator/qt-creator
Debugger: Move some 'mixed native' code to DumperBase
Prepares reuse in LLDB. Change-Id: I2238a94937411b80a9ec84ab738aba2146bba50e Reviewed-by: hjk <hjk@theqtcompany.com>
This commit is contained in:
@@ -1712,6 +1712,60 @@ class DumperBase:
|
||||
sys.path.insert(1, head)
|
||||
self.dumpermodules.append(os.path.splitext(tail)[0])
|
||||
|
||||
def sendQmlCommand(self, command, data = ""):
|
||||
data += '"version":"1","command":"%s"' % command
|
||||
data = data.replace('"', '\\"')
|
||||
expr = 'qt_v4DebuggerHook("{%s}")' % data
|
||||
try:
|
||||
res = self.parseAndEvaluate(expr)
|
||||
#print("QML command ok, RES: %s, CMD: %s" % (res, expr))
|
||||
except RuntimeError as error:
|
||||
#print("QML command failed: %s: %s" % (expr, error))
|
||||
res = None
|
||||
return res
|
||||
|
||||
def prepareQmlStep(self, _):
|
||||
self.sendQmlCommand('prepareStep')
|
||||
|
||||
def removeQmlBreakpoint(self, args):
|
||||
fullName = args['fileName']
|
||||
lineNumber = args['lineNumber']
|
||||
#print("Remove QML breakpoint %s:%s" % (fullName, lineNumber))
|
||||
bp = self.sendQmlCommand('removeBreakpoint',
|
||||
'"fullName":"%s","lineNumber":"%s",'
|
||||
% (fullName, lineNumber))
|
||||
if bp is None:
|
||||
#print("Direct QML breakpoint removal failed: %s.")
|
||||
return 0
|
||||
#print("Removing QML breakpoint: %s" % bp)
|
||||
return int(bp)
|
||||
|
||||
def insertQmlBreakpoint(self, args):
|
||||
fullName = args['fileName']
|
||||
lineNumber = args['lineNumber']
|
||||
print("Insert QML breakpoint %s:%s" % (fullName, lineNumber))
|
||||
bp = self.doInsertQmlBreakPoint(fullName, lineNumber)
|
||||
res = self.sendQmlCommand('prepareStep')
|
||||
#if res is None:
|
||||
# print("Resetting stepping failed.")
|
||||
return str(bp)
|
||||
|
||||
def doInsertQmlBreakPoint(self, fullName, lineNumber):
|
||||
pos = fullName.rfind('/')
|
||||
engineName = "qrc:/" + fullName[pos+1:]
|
||||
bp = self.sendQmlCommand('insertBreakpoint',
|
||||
'"fullName":"%s","lineNumber":"%s","engineName":"%s",'
|
||||
% (fullName, lineNumber, engineName))
|
||||
if bp is None:
|
||||
#print("Direct QML breakpoint insertion failed.")
|
||||
#print("Make pending.")
|
||||
self.createResolvePendingBreakpointsHookBreakpoint(fullName, lineNumber)
|
||||
return 0
|
||||
|
||||
print("Resolving QML breakpoint: %s" % bp)
|
||||
return int(bp)
|
||||
|
||||
|
||||
# Some "Enums"
|
||||
|
||||
# Encodings. Keep that synchronized with DebuggerEncoding in debuggerprotocol.h
|
||||
|
||||
@@ -274,6 +274,7 @@ class Dumper(DumperBase):
|
||||
self.typesToReport = {}
|
||||
self.qtNamespaceToReport = None
|
||||
self.qmlEngines = []
|
||||
self.qmlBreakpoints = []
|
||||
|
||||
def prepare(self, args):
|
||||
self.output = []
|
||||
@@ -1811,6 +1812,29 @@ class Dumper(DumperBase):
|
||||
|
||||
return ''.join(self.output)
|
||||
|
||||
def createResolvePendingBreakpointsHookBreakpoint(self, fullName, lineNumber):
|
||||
class Resolver(gdb.Breakpoint):
|
||||
def __init__(self, dumper, fullName, lineNumber):
|
||||
self.dumper = dumper
|
||||
self.fullName = fullName
|
||||
self.lineNumber = lineNumber
|
||||
spec = "qt_v4ResolvePendingBreakpointsHook"
|
||||
print("Preparing hook to resolve pending QML breakpoint at %s:%s"
|
||||
% (self.fullName, self.lineNumber))
|
||||
super(Resolver, self).\
|
||||
__init__(spec, gdb.BP_BREAKPOINT, internal=True, temporary=False)
|
||||
|
||||
def stop(self):
|
||||
bp = self.dumper.doInsertQmlBreakPoint(self.fullName, self.lineNumber)
|
||||
print("Resolving QML breakpoint %s:%s -> %s"
|
||||
% (self.fullName, self.lineNumber, bp))
|
||||
self.enabled = False
|
||||
return False
|
||||
|
||||
self.qmlBreakpoints.append(Resolver(self, fullName, lineNumber))
|
||||
|
||||
|
||||
|
||||
class CliDumper(Dumper):
|
||||
def __init__(self):
|
||||
Dumper.__init__(self)
|
||||
@@ -1916,7 +1940,6 @@ class CliDumper(Dumper):
|
||||
self.putItem(value)
|
||||
return self.output
|
||||
|
||||
|
||||
def pp(args):
|
||||
return theDumper.run(args)
|
||||
|
||||
@@ -2056,78 +2079,3 @@ class TriggeredBreakpointHookBreakpoint(gdb.Breakpoint):
|
||||
|
||||
TriggeredBreakpointHookBreakpoint()
|
||||
|
||||
|
||||
class ResolvePendingBreakpointsHookBreakpoint(gdb.Breakpoint):
|
||||
def __init__(self, fullName, lineNumber):
|
||||
self.fullName = fullName
|
||||
self.lineNumber = lineNumber
|
||||
spec = "qt_v4ResolvePendingBreakpointsHook"
|
||||
print("Preparing hook to resolve pending QML breakpoint at %s:%s"
|
||||
% (self.fullName, self.lineNumber))
|
||||
super(ResolvePendingBreakpointsHookBreakpoint, self).\
|
||||
__init__(spec, gdb.BP_BREAKPOINT, internal=True, temporary=False)
|
||||
|
||||
def stop(self):
|
||||
bp = doInsertQmlBreakPoint(self.fullName, self.lineNumber)
|
||||
print("Resolving QML breakpoint %s:%s -> %s"
|
||||
% (self.fullName, self.lineNumber, bp))
|
||||
self.enabled = False
|
||||
return False
|
||||
|
||||
def sendQmlCommand(command, data = ""):
|
||||
data += '"version":"1","command":"%s"' % command
|
||||
data = data.replace('"', '\\"')
|
||||
expr = 'qt_v4DebuggerHook("{%s}")' % data
|
||||
try:
|
||||
res = gdb.parse_and_eval(expr)
|
||||
print("QML command ok, RES: %s, CMD: %s" % (res, expr))
|
||||
gdb.execute("p qt_v4Output")
|
||||
except RuntimeError as error:
|
||||
print("QML command failed: gdb.parse_and_eval(%s): %s" % (expr, error))
|
||||
res = None
|
||||
return res
|
||||
|
||||
def doInsertQmlBreakPoint(fullName, lineNumber):
|
||||
pos = fullName.rfind('/')
|
||||
engineName = "qrc:/" + fullName[pos+1:]
|
||||
bp = sendQmlCommand('insertBreakpoint',
|
||||
'"fullName":"%s","lineNumber":"%s","engineName":"%s",'
|
||||
% (fullName, lineNumber, engineName))
|
||||
if bp is None:
|
||||
print("Direct QML breakpoint insertion failed.")
|
||||
print("Make pending.")
|
||||
ResolvePendingBreakpointsHookBreakpoint(fullName, lineNumber)
|
||||
return 0
|
||||
|
||||
print("Resolving QML breakpoint: %s" % bp)
|
||||
return int(bp)
|
||||
|
||||
def insertQmlBreakpoint(arg):
|
||||
(fullName, lineNumber) = arg.split(' ')
|
||||
print("Insert QML breakpoint %s:%s" % (fullName, lineNumber))
|
||||
bp = doInsertQmlBreakPoint(fullName, lineNumber)
|
||||
res = sendQmlCommand('prepareStep')
|
||||
if res is None:
|
||||
print("Resetting stepping failed.")
|
||||
return str(bp)
|
||||
|
||||
registerCommand("insertQmlBreakpoint", insertQmlBreakpoint)
|
||||
|
||||
def removeQmlBreakpoint(arg):
|
||||
(fullName, lineNumber) = arg.split(' ')
|
||||
print("Remove QML breakpoint %s:%s" % (fullName, lineNumber))
|
||||
bp = sendQmlCommand('removeBreakpoint',
|
||||
'"fullName":"%s","lineNumber":"%s",'
|
||||
% (fullName, lineNumber))
|
||||
if bp is None:
|
||||
print("Direct QML breakpoint removal failed: %s.")
|
||||
return 0
|
||||
print("Removing QML breakpoint: %s" % bp)
|
||||
return int(bp)
|
||||
|
||||
registerCommand("removeQmlBreakpoint", removeQmlBreakpoint)
|
||||
|
||||
def prepareQmlStep(arg):
|
||||
sendQmlCommand('prepareStep')
|
||||
|
||||
registerCommand("prepareQmlStep", prepareQmlStep)
|
||||
|
||||
@@ -853,6 +853,12 @@ void GdbEngine::maybeHandleInferiorPidChanged(const QString &pid0)
|
||||
notifyInferiorPid(pid);
|
||||
}
|
||||
|
||||
void GdbEngine::runCommand(const DebuggerCommand &command)
|
||||
{
|
||||
QByteArray cmd = command.function + "({" + command.args + "})";
|
||||
postCommand("python theDumper." + cmd);
|
||||
}
|
||||
|
||||
void GdbEngine::postCommand(const QByteArray &command, GdbCommandCallback callback,
|
||||
const char *callbackName, const QVariant &cookie)
|
||||
{
|
||||
@@ -2054,7 +2060,7 @@ void GdbEngine::executeStep()
|
||||
notifyInferiorRunRequested();
|
||||
showStatusMessage(tr("Step requested..."), 5000);
|
||||
if (isNativeMixedActive()) {
|
||||
postCommand("prepareQmlStep 0");
|
||||
runCommand("prepareQmlStep");
|
||||
postCommand("-exec-continue", RunRequest, CB(handleExecuteContinue));
|
||||
return;
|
||||
}
|
||||
@@ -2752,8 +2758,11 @@ void GdbEngine::insertBreakpoint(Breakpoint bp)
|
||||
QVariant vid = QVariant::fromValue(bp);
|
||||
|
||||
if (!data.isCppBreakpoint()) {
|
||||
postCommand("insertQmlBreakpoint " + data.fileName.toUtf8() + ' '
|
||||
+ QByteArray::number(data.lineNumber));
|
||||
DebuggerCommand cmd("insertQmlBreakpoint");
|
||||
cmd.arg("fileName", data.fileName);
|
||||
cmd.arg("lineNumber", data.lineNumber);
|
||||
cmd.arg("condition", data.condition);
|
||||
runCommand(cmd);
|
||||
bp.notifyBreakpointInsertOk();
|
||||
return;
|
||||
}
|
||||
@@ -2902,8 +2911,10 @@ void GdbEngine::removeBreakpoint(Breakpoint bp)
|
||||
|
||||
const BreakpointParameters &data = bp.parameters();
|
||||
if (!data.isCppBreakpoint()) {
|
||||
postCommand("removeQmlBreakpoint " + data.fileName.toUtf8() + ' '
|
||||
+ QByteArray::number(data.lineNumber));
|
||||
DebuggerCommand cmd("removeQmlBreakpoint");
|
||||
cmd.arg("fileName", data.fileName);
|
||||
cmd.arg("lineNumber", data.lineNumber);
|
||||
runCommand(cmd);
|
||||
bp.notifyBreakpointRemoveOk();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -196,6 +196,7 @@ private: ////////// Gdb Command Management //////////
|
||||
// watch model updates before everything is finished.
|
||||
void flushCommand(const GdbCommand &cmd);
|
||||
protected:
|
||||
void runCommand(const DebuggerCommand &command);
|
||||
void postCommand(const QByteArray &command,
|
||||
GdbCommandFlags flags,
|
||||
GdbCommandCallback callback = 0,
|
||||
|
||||
Reference in New Issue
Block a user