Commit 2e9b8406 authored by hjk's avatar hjk

Debugger: Claim a few more capabilities for LLDB engine

This will need further fine tuning.

Change-Id: Ia8926a73adfdf3de313cd379c4d6452b0af56ca0
Reviewed-by: default avatarhjk <hjk121@nokiamail.com>
parent f4efd3f6
......@@ -841,6 +841,7 @@ qqEditable = {}
qqStripForFormat = {}
def stripForFormat(typeName):
global qqStripForFormat
if typeName in qqStripForFormat:
return qqStripForFormat[typeName]
stripped = ""
......@@ -860,42 +861,31 @@ def stripForFormat(typeName):
qqStripForFormat[typeName] = stripped
return stripped
def bbsetup(args = ''):
typeCache = {}
module = sys.modules[__name__]
for key, value in module.__dict__.items():
if key.startswith("qdump__"):
name = key[7:]
qqDumpers[name] = value
qqFormats[name] = qqFormats.get(name, "")
elif key.startswith("qform__"):
name = key[7:]
def registerDumper(function):
global qqDumpers, qqFormats, qqEditable
try:
funcname = function.func_name
if funcname.startswith("qdump__"):
type = funcname[7:]
qqDumpers[type] = function
qqFormats[type] = qqFormats.get(type, "")
elif funcname.startswith("qform__"):
type = funcname[7:]
formats = ""
try:
formats = value()
formats = function()
except:
pass
qqFormats[name] = formats
elif key.startswith("qedit__"):
name = key[7:]
qqFormats[type] = formats
elif funcname.startswith("qedit__"):
type = funcname[7:]
try:
qqEditable[name] = value
qqEditable[type] = function
except:
pass
result = "dumpers=["
#qqNs = qtNamespace() # This is too early
for key, value in qqFormats.items():
if qqEditable.has_key(key):
result += '{type="%s",formats="%s",editable="true"},' % (key, value)
else:
result += '{type="%s",formats="%s"},' % (key, value)
result += ']'
#result += ',namespace="%s"' % qqNs
result += ',hasInferiorThreadList="%s"' % int(hasInferiorThreadList())
return result
registerCommand("bbsetup", bbsetup)
except:
pass
#######################################################################
#
......@@ -904,6 +894,7 @@ registerCommand("bbsetup", bbsetup)
#######################################################################
def bbedit(args):
global qqEditable
(type, expr, value) = args.split(",")
type = base64.b16decode(type, True)
ns = qtNamespace()
......@@ -1431,6 +1422,8 @@ class Dumper:
self.putNumChild(0)
return
global qqDumpers, qqFormats
type = value.type.unqualified()
typeName = str(type)
tryDynamic &= self.useDynamicType
......@@ -1666,8 +1659,8 @@ class Dumper:
return
# Fall back to plain pointer printing.
warn("GENERIC PLAIN POINTER: %s" % value.type)
warn("ADDR PLAIN POINTER: %s" % value.address)
#warn("GENERIC PLAIN POINTER: %s" % value.type)
#warn("ADDR PLAIN POINTER: %s" % value.address)
self.putType(typeName)
self.putField("aaa", "1")
#self.put('addr="0x%x",' % long(value.address))
......@@ -1733,6 +1726,7 @@ class Dumper:
return
#warn(" STRIPPED: %s" % nsStrippedType)
#warn(" DUMPERS: %s" % qqDumpers)
#warn(" DUMPERS: %s" % (nsStrippedType in qqDumpers))
dumper = qqDumpers.get(nsStrippedType, None)
if not dumper is None:
......@@ -1942,44 +1936,6 @@ def threadnames(arg):
registerCommand("threadnames", threadnames)
#######################################################################
#
# Import plain gdb pretty printers
#
#######################################################################
class PlainDumper:
def __init__(self, printer):
self.printer = printer
def __call__(self, d, value):
printer = self.printer.gen_printer(value)
lister = getattr(printer, "children", None)
children = [] if lister is None else list(lister())
d.putType(self.printer.name)
val = printer.to_string().encode("hex")
d.putValue(val, Hex2EncodedLatin1)
d.putValue(printer.to_string())
d.putNumChild(len(children))
if d.isExpanded():
with Children(d):
for child in children:
d.putSubItem(child[0], child[1])
def importPlainDumper(printer):
name = printer.name.replace("::", "__")
qqDumpers[name] = PlainDumper(printer)
qqFormats[name] = ""
def importPlainDumpers(args):
for obj in gdb.objfiles():
for printers in obj.pretty_printers + gdb.pretty_printers:
for printer in printers.subprinters:
importPlainDumper(printer)
registerCommand("importPlainDumpers", importPlainDumpers)
#######################################################################
#
# Mixed C++/Qml debugging
......
import binascii
import gdb
import inspect
import os
import sys
import traceback
import gdb
cdbLoaded = False
lldbLoaded = False
......@@ -333,8 +334,72 @@ class ScanStackCommand(gdb.Command):
ScanStackCommand()
def bbsetup(args = ''):
global qqDumpers, qqFormats, qqEditable, typeCache
typeCache = {}
module = sys.modules[__name__]
for key, value in module.__dict__.items():
registerDumper(value)
result = "dumpers=["
#qqNs = qtNamespace() # This is too early
for key, value in qqFormats.items():
if qqEditable.has_key(key):
result += '{type="%s",formats="%s",editable="true"},' % (key, value)
else:
result += '{type="%s",formats="%s"},' % (key, value)
result += ']'
#result += ',namespace="%s"' % qqNs
result += ',hasInferiorThreadList="%s"' % int(hasInferiorThreadList())
return result
registerCommand("bbsetup", bbsetup)
#######################################################################
#
# Import plain gdb pretty printers
#
#######################################################################
class PlainDumper:
def __init__(self, printer):
self.printer = printer
def __call__(self, d, value):
printer = self.printer.gen_printer(value)
lister = getattr(printer, "children", None)
children = [] if lister is None else list(lister())
d.putType(self.printer.name)
val = printer.to_string().encode("hex")
d.putValue(val, Hex2EncodedLatin1)
d.putValue(printer.to_string())
d.putNumChild(len(children))
if d.isExpanded():
with Children(d):
for child in children:
d.putSubItem(child[0], child[1])
def importPlainDumper(printer):
global qqDumpers, qqFormats
name = printer.name.replace("::", "__")
qqDumpers[name] = PlainDumper(printer)
qqFormats[name] = ""
def importPlainDumpers(args):
return
for obj in gdb.objfiles():
for printers in obj.pretty_printers + gdb.pretty_printers:
for printer in printers.subprinters:
importPlainDumper(printer)
registerCommand("importPlainDumpers", importPlainDumpers)
gdbLoaded = True
currentDir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
execfile(os.path.join(currentDir, "dumper.py"))
execfile(os.path.join(currentDir, "qttypes.py"))
bbsetup()
......@@ -49,10 +49,9 @@ SimpleValueCode = None # LLDB only
#warn("LOADING LLDB")
# Data members
SimpleValueCode, \
StructCode, \
PointerCode \
= range(3)
SimpleValueCode = 100
StructCode = 101
PointerCode = 102
# Breakpoints. Keep synchronized with BreakpointType in breakpoint.h
UnknownType = 0
......@@ -95,6 +94,9 @@ class Type:
def unqualified(self):
return self
def strip_typedefs(self):
return self
class Value:
def __init__(self, var):
self.raw = var
......@@ -106,6 +108,9 @@ class Value:
def __str__(self):
return str(self.raw.value)
def __getitem__(self, name):
return None if self.raw is None else self.raw.GetChildMemberWithName(name)
def fields(self):
return [Value(self.raw.GetChildAtIndex(i)) for i in range(self.raw.num_children)]
......@@ -397,10 +402,22 @@ lldb.debugger.HandleCommand("settings set interpreter.prompt-on-quit off")
lldb.debugger.HandleCommand("settings set frame-format ''")
lldb.debugger.HandleCommand("settings set thread-format ''")
lldbLoaded = True
execfile(os.path.join(currentDir, "dumper.py"))
execfile(os.path.join(currentDir, "qttypes.py"))
def importPlainDumpers(args):
pass
def bbsetup(args = ''):
global qqDumpers, qqFormats, qqEditable
typeCache = {}
items = globals()
for key in items:
registerDumper(items[key])
bbsetup()
print "result={state=\"enginesetupok\"}"
lldbLoaded = True
print "result={state=\"enginesetupok\",dumpers=\"%s\"}" % qqDumpers.keys()
......@@ -1033,7 +1033,37 @@ void LldbEngine::refreshLocation(const GdbMi &reportedLocation)
bool LldbEngine::hasCapability(unsigned cap) const
{
return cap & (ReloadModuleCapability|BreakConditionCapability);
if (cap & (ReverseSteppingCapability
| AutoDerefPointersCapability
| DisassemblerCapability
| RegisterCapability
| ShowMemoryCapability
| JumpToLineCapability
| ReloadModuleCapability
| ReloadModuleSymbolsCapability
| BreakOnThrowAndCatchCapability
| BreakConditionCapability
| TracePointCapability
| ReturnFromFunctionCapability
| CreateFullBacktraceCapability
| WatchpointByAddressCapability
| WatchpointByExpressionCapability
| AddWatcherCapability
| WatchWidgetsCapability
| ShowModuleSymbolsCapability
| ShowModuleSectionsCapability
| CatchCapability
| OperateByInstructionCapability
| RunToLineCapability
| WatchComplexExpressionsCapability
| MemoryAddressCapability))
return true;
if (startParameters().startMode == AttachCore)
return false;
//return cap == SnapshotCapability;
return false;
}
DebuggerEngine *createLldbEngine(const DebuggerStartParameters &startParameters)
......
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