Commit f5200167 authored by hjk's avatar hjk
Browse files

Debugger: Work on LLDB dumpers



54 passed, 122 failed (lldb 300.99/gcc)

Change-Id: I71e1666c542406b126214c2b9b8b56193bcbcf76
Reviewed-by: default avatarhjk <hjk121@nokiamail.com>
parent e967049f
......@@ -136,7 +136,7 @@ def registerDumper(function):
pass
def warn(message):
print 'XXX="%s",' % message.encode("latin1").replace('"', "'")
print '\nWARNING="%s",\n' % message.encode("latin1").replace('"', "'")
def showException(msg, exType, exValue, exTraceback):
warn("**** CAUGHT EXCEPTION: %s ****" % msg)
......@@ -316,7 +316,12 @@ def simpleEncoding(typeobj):
# return Hex2EncodedInt1
#if code == IntCode:
if code == lldb.eTypeClassBuiltin:
if str(typeobj).find("unsigned") >= 0:
name = str(typeobj)
if name == "float":
return Hex2EncodedFloat4
if name == "double":
return Hex2EncodedFloat8
if name.find("unsigned") >= 0:
if size == 1:
return Hex2EncodedUInt1
if size == 2:
......@@ -334,11 +339,6 @@ def simpleEncoding(typeobj):
return Hex2EncodedInt4
if size == 8:
return Hex2EncodedInt8
#if code == FloatCode:
# if size == 4:
# return Hex2EncodedFloat4
# if size == 8:
# return Hex2EncodedFloat8
return None
class Children:
......@@ -485,6 +485,7 @@ class Dumper:
self.ns = ""
self.autoDerefPointers = True
self.useDynamicType = True
self.useFancy = True
self.currentIName = None
self.currentValuePriority = -100
......@@ -605,6 +606,18 @@ class Dumper:
return True
return self.stripNamespaceFromType(type.GetName()) in movableTypes
def putIntItem(self, name, value):
with SubItem(self, name):
self.putValue(value)
self.putType("int")
self.putNumChild(0)
def putBoolItem(self, name, value):
with SubItem(self, name):
self.putValue(value)
self.putType("bool")
self.putNumChild(0)
def putNumChild(self, numchild):
#warn("NUM CHILD: '%s' '%s'" % (numchild, self.currentChildNumChild))
#if numchild != self.currentChildNumChild:
......@@ -668,6 +681,13 @@ class Dumper:
return xrange(0, self.currentNumChild)
return xrange(min(self.currentMaxNumChild, self.currentNumChild))
def putPlainChildren(self, value):
self.putEmptyValue(-99)
self.putNumChild(1)
if self.currentIName in self.expandedINames:
with Children(self):
self.putFields(value)
def lookupType(self, name):
#warn("LOOKUP: %s" % self.target.FindFirstType(name))
return self.target.FindFirstType(name)
......@@ -785,19 +805,12 @@ class Dumper:
result += '],hasmore="%s"},' % hasmore
self.report(result)
# Convenience function.
def putItemCount(self, count, maximum = 1000000000):
# This needs to override the default value, so don't use 'put' directly.
if count > maximum:
self.putValue('<>%s items>' % maximum)
else:
self.putValue('<%s items>' % count)
def putType(self, type, priority = 0):
# Higher priority values override lower ones.
if priority >= self.currentTypePriority:
self.currentType = str(type)
self.currentTypePriority = priority
#warn("TYPE: %s PRIORITY: %s" % (type, priority))
def putBetterType(self, type):
try:
......@@ -805,6 +818,7 @@ class Dumper:
except:
self.currentType = str(type)
self.currentTypePriority = self.currentTypePriority + 1
#warn("BETTER TYPE: %s PRIORITY: %s" % (type, self.currentTypePriority))
def readRawMemory(self, base, size):
if size == 0:
......@@ -900,17 +914,33 @@ class Dumper:
# Pointers
if value.GetType().IsPointerType() and self.autoDerefPointers:
self.putItem(value.Dereference())
if isNull(value):
self.putType(typeName)
self.putValue("0x0")
self.putNumChild(0)
return
origType = value.GetType()
innerType = value.GetType().GetPointeeType()
self.putType(innerType)
savedCurrentChildType = self.currentChildType
self.currentChildType = str(innerType)
self.putItem(value.dereference())
self.currentChildType = savedCurrentChildType
self.put('origaddr="%s",' % value.address)
return
stripped = self.stripNamespaceFromType(typeName).replace("::", "__")
#warn("VALUE: %s" % value)
#warn("STRIPPED: %s" % stripped)
#warn("DUMPABLE: %s" % (stripped in qqDumpers))
if stripped in qqDumpers:
self.putType(typeName)
qqDumpers[stripped](self, value)
return
#warn("FANCY: %s" % self.useFancy)
if self.useFancy:
stripped = self.stripNamespaceFromType(typeName).replace("::", "__")
#warn("STRIPPED: %s" % stripped)
#warn("DUMPABLE: %s" % (stripped in qqDumpers))
if stripped in qqDumpers:
self.putType(typeName)
qqDumpers[stripped](self, value)
return
# Normal value
v = value.GetValue()
......@@ -1258,18 +1288,25 @@ class Dumper:
self.options = args
def setWatchers(self, args):
self.currentWatchers = args['watchers']
#self.currentWatchers = args['watchers']
warn("WATCHERS %s" % self.currentWatchers)
self.reportData()
def updateData(self, args):
self.expandedINames = set(args['expanded'].split(','))
self.autoDerefPointers = int(args['autoderef'])
self.useDynamicType = int(args['dyntype'])
# Keep always True for now.
#self.passExceptions = args['pe']
self.useDynamicType = int(args['dyntype'])
#self.reportData()
warn("UPDATE 1")
if 'expanded' in args:
self.expandedINames = set(args['expanded'].split(','))
if 'autoderef' in args:
self.autoDerefPointers = int(args['autoderef'])
if 'dyntype' in args:
self.useDynamicType = int(args['dyntype'])
if 'fancy' in args:
self.useFancy = int(args['fancy'])
if 'passexceptions' in args:
self.passExceptions = int(args['passexceptions'])
self.passExceptions = True # FIXME
self.reportVariables(args)
warn("UPDATE 2")
def disassemble(self, args):
frame = self.currentFrame();
......
......@@ -433,8 +433,8 @@ def qdump__QFixed(d, value):
def qdump__QFiniteStack(d, value):
alloc = value["_alloc"]
size = value["_size"]
alloc = int(value["_alloc"])
size = int(value["_size"])
check(0 <= size and size <= alloc and alloc <= 1000 * 1000 * 1000)
d.putItemCount(size)
d.putNumChild(size)
......@@ -483,7 +483,7 @@ def qdump__QHash(d, value):
val = value.cast(hashDataType)
bucket = val["buckets"]
e = val.cast(hashNodeType)
for n in xrange(val["numBuckets"] - 1, -1, -1):
for n in xrange(int(val["numBuckets"]) - 1, -1, -1):
n = n - 1
if n < 0:
break
......@@ -497,8 +497,8 @@ def qdump__QHash(d, value):
if next["next"]:
return next
d = node.cast(hashDataType.pointer()).dereference()
numBuckets = d["numBuckets"]
start = (node["h"] % numBuckets) + 1
numBuckets = int(d["numBuckets"])
start = (int(node["h"]) % numBuckets) + 1
bucket = d["buckets"] + start
for n in xrange(numBuckets - start):
if bucket.dereference() != next:
......@@ -511,7 +511,7 @@ def qdump__QHash(d, value):
d_ptr = value["d"]
e_ptr = value["e"]
size = d_ptr["size"]
size = int(d_ptr["size"])
hashDataType = d_ptr.type
hashNodeType = e_ptr.type
......@@ -644,7 +644,7 @@ def qform__QImage():
def qdump__QImage(d, value):
try:
painters = value["painters"]
painters = int(value["painters"])
except:
d.putPlainChildren(value)
return
......@@ -696,7 +696,7 @@ def qdump__QImage(d, value):
def qdump__QLinkedList(d, value):
d_ptr = value["d"]
e_ptr = value["e"]
n = d_ptr["size"]
n = int(d_ptr["size"])
check(0 <= n and n <= 100*1000*1000)
checkRef(d_ptr["ref"])
d.putItemCount(n)
......@@ -762,7 +762,7 @@ def qdump__QMapNode(d, value):
def qdumpHelper__Qt4_QMap(d, value, forceLong):
d_ptr = value["d"].dereference()
e_ptr = value["e"].dereference()
n = d_ptr["size"]
n = int(d_ptr["size"])
check(0 <= n and n <= 100*1000*1000)
checkRef(d_ptr["ref"])
......@@ -810,7 +810,7 @@ def qdumpHelper__Qt4_QMap(d, value, forceLong):
def qdumpHelper__Qt5_QMap(d, value, forceLong):
d_ptr = value["d"].dereference()
n = d_ptr["size"]
n = int(d_ptr["size"])
check(0 <= n and n <= 100*1000*1000)
checkRef(d_ptr["ref"])
......@@ -1325,7 +1325,7 @@ def qdump__QObject(d, value):
# }
def qdump__QPixmap(d, value):
painters = value["painters"]
painters = int(value["painters"])
check(0 <= painters and painters < 1000)
d_ptr = value["data"]["d"]
if isNull(d_ptr):
......@@ -1466,7 +1466,7 @@ def qdump__QSet(d, value):
d_ptr = value["q_hash"]["d"]
e_ptr = value["q_hash"]["e"]
size = d_ptr["size"]
size = int(d_ptr["size"])
hashDataType = d_ptr.type
hashNodeType = e_ptr.type
......@@ -1897,11 +1897,11 @@ def qdump__QWeakPointer(d, value):
d.putValue("<invalid>")
d.putNumChild(0)
return
weakref = d_ptr["weakref"]["_q_value"]
strongref = d_ptr["strongref"]["_q_value"]
check(int(strongref) >= -1)
check(int(strongref) <= int(weakref))
check(int(weakref) <= 10*1000*1000)
weakref = int(d_ptr["weakref"]["_q_value"])
strongref = int(d_ptr["strongref"]["_q_value"])
check(strongref >= -1)
check(strongref <= weakref)
check(weakref <= 10*1000*1000)
if isSimpleType(val.dereference().type):
d.putNumChild(3)
......@@ -2048,7 +2048,7 @@ def qform__std__map():
def qdump__std__map(d, value):
impl = value["_M_t"]["_M_impl"]
size = impl["_M_node_count"]
size = int(impl["_M_node_count"])
check(0 <= size and size <= 100*1000*1000)
d.putItemCount(size)
d.putNumChild(size)
......@@ -2152,7 +2152,7 @@ def qdump__std__set__const_iterator(d, value):
def qdump__std__set(d, value):
impl = value["_M_t"]["_M_impl"]
size = impl["_M_node_count"]
size = int(impl["_M_node_count"])
check(0 <= size and size <= 100*1000*1000)
d.putItemCount(size)
d.putNumChild(size)
......@@ -2220,6 +2220,13 @@ def qdump__std__string(d, value):
mem = d.readRawMemory(p, size * charType.sizeof)
d.putField("editvalue", mem)
#def qdump__std__string(d, value):
# data = value["__r_"]
# d.putValue("SSSS")
# d.putType("std::string")
# d.putNumChild(1)
# d.putPlainChildren(value)
def qdump__std__shared_ptr(d, value):
i = value["_M_ptr"]
......@@ -2331,7 +2338,7 @@ def qdump__wstring(d, value):
def qdump____gnu_cxx__hash_set(d, value):
ht = value["_M_ht"]
size = ht["_M_num_elements"]
size = int(ht["_M_num_elements"])
check(0 <= size and size <= 1000 * 1000 * 1000)
d.putItemCount(size)
d.putNumChild(size)
......@@ -2401,11 +2408,11 @@ def qdump__boost__shared_ptr(d, value):
return
countedbase = value["pn"]["pi_"].dereference()
weakcount = countedbase["weak_count_"]
usecount = countedbase["use_count_"]
check(int(weakcount) >= 0)
check(int(weakcount) <= int(usecount))
check(int(usecount) <= 10*1000*1000)
weakcount = int(countedbase["weak_count_"])
usecount = int(countedbase["use_count_"])
check(weakcount >= 0)
check(weakcount <= int(usecount))
check(usecount <= 10*1000*1000)
val = value["px"].dereference()
if isSimpleType(val.type):
......
......@@ -699,7 +699,7 @@ void LldbEngine::updateLocals()
{
WatchHandler *handler = watchHandler();
requestUpdateWatchers();
//requestUpdateWatchers();
Command cmd("updateData");
cmd.arg("expanded", handler->expansionRequests());
......@@ -741,7 +741,7 @@ void LldbEngine::updateLocals()
// }
const static bool alwaysVerbose = !qgetenv("QTC_DEBUGGER_PYTHON_VERBOSE").isEmpty();
cmd.arg("passexeptions", alwaysVerbose);
cmd.arg("passexceptions", alwaysVerbose);
cmd.arg("fancy", debuggerCore()->boolSetting(UseDebuggingHelpers));
cmd.arg("autoderef", debuggerCore()->boolSetting(AutoDerefPointers));
cmd.arg("dyntype", debuggerCore()->boolSetting(UseDynamicType));
......
......@@ -556,7 +556,7 @@ void tst_Dumpers::initTestCase()
if (m_debuggerBinary.endsWith("lldb"))
m_debuggerEngine = DumpTestLldbEngine;
m_qmakeBinary = qgetenv("QTC_QMAKE_PATH");
m_qmakeBinary = qgetenv("QTC_QMAKE_PATH_FOR_TEST");
if (m_qmakeBinary.isEmpty())
m_qmakeBinary = "qmake";
......@@ -2744,6 +2744,18 @@ void tst_Dumpers::dumper_data()
% Check("v", "<2 items>", "std::vector<std::string>")
% Check("v.0", "[0]", "\"foo\"", "std::string");
QTest::newRow("StdVector0")
<< Data("#include <vector>\n",
"std::vector<double> v0, v;\n"
"v.push_back(1);\n"
"v.push_back(0);\n"
"v.push_back(2);\n")
% Check("v0", "<0 items>", "std::vector<double>")
% Check("v", "<3 items>", "std::vector<double>")
% Check("v.0", "[0]", "1", "double")
% Check("v.1", "[1]", "0", "double")
% Check("v.2", "[2]", "2", "double");
QTest::newRow("StdVector1")
<< Data("#include <vector>\n",
"std::vector<int *> v0, v;\n"
......
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