debugger: special handling of char *argv[] in l&w

It's nicer this way.
This commit is contained in:
hjk
2009-12-07 09:14:35 +01:00
parent 69c9a06342
commit d2ab8762e9
2 changed files with 71 additions and 35 deletions

View File

@@ -22,6 +22,13 @@ def qmin(n, m):
return n return n
return m return m
def value(expr):
value = gdb.parse_and_eval(expr)
try:
return int(value)
except:
return str(value)
def isSimpleType(typeobj): def isSimpleType(typeobj):
type = str(typeobj) type = str(typeobj)
return type == "bool" \ return type == "bool" \
@@ -122,6 +129,13 @@ def qtNamespace():
except RuntimeError: except RuntimeError:
return "" return ""
def encodeCharArray(p, size):
s = ""
for i in xrange(0, size):
s += "%02x" % int(p.dereference())
p += 1
return s
def encodeByteArray(value): def encodeByteArray(value):
d_ptr = value['d'].dereference() d_ptr = value['d'].dereference()
data = d_ptr['data'] data = d_ptr['data']
@@ -135,11 +149,7 @@ def encodeByteArray(value):
innerType = gdb.lookup_type("char") innerType = gdb.lookup_type("char")
p = gdb.Value(data.cast(innerType.pointer())) p = gdb.Value(data.cast(innerType.pointer()))
s = "" return encodeCharArray(p, size)
for i in xrange(0, size):
s += "%02x" % int(p.dereference())
p += 1
return s
def encodeString(value): def encodeString(value):
d_ptr = value['d'].dereference() d_ptr = value['d'].dereference()
@@ -267,11 +277,41 @@ class FrameCommand(gdb.Command):
continue continue
#warn("ITEM %s: " % item.value) #warn("ITEM %s: " % item.value)
d.beginHash() type = item.value.type
d.put('iname="%s",' % item.iname) if type.code == gdb.TYPE_CODE_PTR \
d.put('addr="%s",' % item.value.address) and name == "argv" and str(type) == "char **":
d.safePutItemHelper(item) # Special handling for char** argv:
d.endHash() n = 0
p = item.value
while not isNull(p.dereference()) and n <= 100:
p += 1
n += 1
d.beginHash()
d.put('iname="%s",' % item.iname)
d.putName(name)
d.putItemCount(select(n <= 100, n, "> 100"))
d.putType(type)
d.putNumChild(n)
if d.isExpanded(item):
p = item.value
d.beginChildren(n)
for i in xrange(0, n):
value = p.dereference()
d.putItemOrPointer(Item(value, item.iname, i, None))
p += 1
if n > 100:
d.putEllipsis()
d.endChildren()
d.endHash()
else:
# A "normal" local variable or parameter
d.beginHash()
d.put('iname="%s",' % item.iname)
d.put('addr="%s",' % item.value.address)
d.safePutItemHelper(item)
d.endHash()
# The outermost block in a function has the function member # The outermost block in a function has the function member
# FIXME: check whether this is guaranteed. # FIXME: check whether this is guaranteed.
@@ -292,9 +332,10 @@ class FrameCommand(gdb.Command):
watchers = "" watchers = ""
if len(args) > 3: if len(args) > 3:
watchers = base64.b16decode(args[3], True) watchers = base64.b16decode(args[3], True)
for watcher in watchers.split("$$"): if len(watchers) > 0:
(exp, name) = watcher.split("$") for watcher in watchers.split("$$"):
self.handleWatch(d, exp, name) (exp, name) = watcher.split("$")
self.handleWatch(d, exp, name)
d.pushOutput() d.pushOutput()
watchers = d.safeoutput watchers = d.safeoutput
@@ -305,16 +346,16 @@ class FrameCommand(gdb.Command):
def handleWatch(self, d, exp, name): def handleWatch(self, d, exp, name):
warn("HANDLING WATCH %s, NAME: %s" % (exp, name)) #warn("HANDLING WATCH %s, NAME: %s" % (exp, name))
if exp.startswith("["): if exp.startswith("["):
warn("EVAL: EXP: %s" % exp) #warn("EVAL: EXP: %s" % exp)
d.beginHash() d.beginHash()
d.put('iname="watch.%s",' % name) d.put('iname="watch.%s",' % name)
d.put('name="%s",' % exp) d.put('name="%s",' % exp)
d.put('exp="%s"' % exp) d.put('exp="%s"' % exp)
try: try:
list = eval(exp) list = eval(exp)
warn("EVAL: LIST: %s" % list) #warn("EVAL: LIST: %s" % list)
d.put('value=" "') d.put('value=" "')
d.put('type=" "') d.put('type=" "')
d.put('numchild="%d"' % len(list)) d.put('numchild="%d"' % len(list))
@@ -578,7 +619,7 @@ class Dumper:
def putItemOrPointerHelper(self, item): def putItemOrPointerHelper(self, item):
if item.value.type.code == gdb.TYPE_CODE_PTR \ if item.value.type.code == gdb.TYPE_CODE_PTR \
and str(item.value.type.unqualified) != "char": and str(item.value.type.target()) != "char":
if not isNull(item.value): if not isNull(item.value):
self.putItemOrPointerHelper( self.putItemOrPointerHelper(
Item(item.value.dereference(), item.iname, None, None)) Item(item.value.dereference(), item.iname, None, None))
@@ -639,24 +680,20 @@ class Dumper:
isHandled = True isHandled = True
target = str(type.target().unqualified()) target = str(type.target().unqualified())
#warn("TARGET: %s" % target)
if target == "char" and not isHandled: if target == "char" and not isHandled:
# Display values up to given length directly # Display values up to given length directly
firstNul = -1 firstNul = -1
p = value p = value
for i in xrange(0, 10): for i in xrange(0, 100):
if p.dereference() == 0: if p.dereference() == 0:
# Found terminating NUL # Found terminating NUL
self.putField("valueencoded", "6") self.putField("valueencoded", "6")
self.put(',value="') self.put(',value="')
p = value self.put(encodeCharArray(value, i))
for j in xrange(0, i):
self.put('%02x' % int(p.dereference()))
p += 1
self.put('"') self.put('"')
self.putNumChild(0) self.putNumChild(0)
isHandled = True isHandled = True
break return
p += 1 p += 1
if not isHandled: if not isHandled:

View File

@@ -278,9 +278,6 @@ private:
Thread m_thread; Thread m_thread;
}; };
//QMutex m_mutex;
//QWaitCondition m_waitCondition;
QByteArray buffer; QByteArray buffer;
QSemaphore freeBytes(1); QSemaphore freeBytes(1);
QSemaphore usedBytes(0); QSemaphore usedBytes(0);
@@ -569,13 +566,6 @@ void tst_Gdb::check(const QByteArray &label, const QByteArray &expected0,
qWarning() << label << "..."; qWarning() << label << "...";
writeToGdb("bb " + N(int(fancy)) + " 1 " + expanded); writeToGdb("bb " + N(int(fancy)) + " 1 " + expanded);
//m_mutex.lock();
//m_waitCondition.wait(&m_mutex);
//QByteArray ba = m_thread.m_output;
//m_thread.m_output.clear();
//m_mutex.unlock();
//GdbMi locals;
//qDebug() << "\n1 ABOUT TO AQUIRE USED "; //qDebug() << "\n1 ABOUT TO AQUIRE USED ";
usedBytes.acquire(); usedBytes.acquire();
//qDebug() << "\n1 AQUIRED USED "; //qDebug() << "\n1 AQUIRED USED ";
@@ -602,7 +592,16 @@ void tst_Gdb::check(const QByteArray &label, const QByteArray &expected0,
"children=[" + expected0 + "]}"; "children=[" + expected0 + "]}";
int line = m_thread.m_line; int line = m_thread.m_line;
QByteArrayList l1 = actual.split(','); QByteArrayList l1_0 = actual.split(',');
QByteArrayList l1;
for (int i = 0; i != l1_0.size(); ++i) {
const QByteArray &ba = l1_0.at(i);
if (ba.startsWith("watchers={iname"))
break;
if (!ba.startsWith("addr"))
l1.append(ba);
}
QByteArrayList l2 = expected.split(','); QByteArrayList l2 = expected.split(',');
bool ok = l1.size() == l2.size(); bool ok = l1.size() == l2.size();