From d2ab8762e930fcb4422184d8858c64e56279dd3d Mon Sep 17 00:00:00 2001 From: hjk <qtc-committer@nokia.com> Date: Mon, 7 Dec 2009 09:14:35 +0100 Subject: [PATCH] debugger: special handling of char *argv[] in l&w It's nicer this way. --- share/qtcreator/gdbmacros/dumper.py | 85 +++++++++++++++++++++-------- tests/auto/debugger/tst_gdb.cpp | 21 ++++--- 2 files changed, 71 insertions(+), 35 deletions(-) diff --git a/share/qtcreator/gdbmacros/dumper.py b/share/qtcreator/gdbmacros/dumper.py index 3f4ff20a8a1..258784746a4 100644 --- a/share/qtcreator/gdbmacros/dumper.py +++ b/share/qtcreator/gdbmacros/dumper.py @@ -22,6 +22,13 @@ def qmin(n, m): return n return m +def value(expr): + value = gdb.parse_and_eval(expr) + try: + return int(value) + except: + return str(value) + def isSimpleType(typeobj): type = str(typeobj) return type == "bool" \ @@ -122,6 +129,13 @@ def qtNamespace(): except RuntimeError: return "" +def encodeCharArray(p, size): + s = "" + for i in xrange(0, size): + s += "%02x" % int(p.dereference()) + p += 1 + return s + def encodeByteArray(value): d_ptr = value['d'].dereference() data = d_ptr['data'] @@ -135,11 +149,7 @@ def encodeByteArray(value): innerType = gdb.lookup_type("char") p = gdb.Value(data.cast(innerType.pointer())) - s = "" - for i in xrange(0, size): - s += "%02x" % int(p.dereference()) - p += 1 - return s + return encodeCharArray(p, size) def encodeString(value): d_ptr = value['d'].dereference() @@ -267,11 +277,41 @@ class FrameCommand(gdb.Command): continue #warn("ITEM %s: " % item.value) - d.beginHash() - d.put('iname="%s",' % item.iname) - d.put('addr="%s",' % item.value.address) - d.safePutItemHelper(item) - d.endHash() + type = item.value.type + if type.code == gdb.TYPE_CODE_PTR \ + and name == "argv" and str(type) == "char **": + # Special handling for char** argv: + 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 # FIXME: check whether this is guaranteed. @@ -292,9 +332,10 @@ class FrameCommand(gdb.Command): watchers = "" if len(args) > 3: watchers = base64.b16decode(args[3], True) - for watcher in watchers.split("$$"): - (exp, name) = watcher.split("$") - self.handleWatch(d, exp, name) + if len(watchers) > 0: + for watcher in watchers.split("$$"): + (exp, name) = watcher.split("$") + self.handleWatch(d, exp, name) d.pushOutput() watchers = d.safeoutput @@ -305,16 +346,16 @@ class FrameCommand(gdb.Command): 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("["): - warn("EVAL: EXP: %s" % exp) + #warn("EVAL: EXP: %s" % exp) d.beginHash() d.put('iname="watch.%s",' % name) d.put('name="%s",' % exp) d.put('exp="%s"' % exp) try: list = eval(exp) - warn("EVAL: LIST: %s" % list) + #warn("EVAL: LIST: %s" % list) d.put('value=" "') d.put('type=" "') d.put('numchild="%d"' % len(list)) @@ -578,7 +619,7 @@ class Dumper: def putItemOrPointerHelper(self, item): 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): self.putItemOrPointerHelper( Item(item.value.dereference(), item.iname, None, None)) @@ -639,24 +680,20 @@ class Dumper: isHandled = True target = str(type.target().unqualified()) - #warn("TARGET: %s" % target) if target == "char" and not isHandled: # Display values up to given length directly firstNul = -1 p = value - for i in xrange(0, 10): + for i in xrange(0, 100): if p.dereference() == 0: # Found terminating NUL self.putField("valueencoded", "6") self.put(',value="') - p = value - for j in xrange(0, i): - self.put('%02x' % int(p.dereference())) - p += 1 + self.put(encodeCharArray(value, i)) self.put('"') self.putNumChild(0) isHandled = True - break + return p += 1 if not isHandled: diff --git a/tests/auto/debugger/tst_gdb.cpp b/tests/auto/debugger/tst_gdb.cpp index 3f8b9b9fffc..f13bde84af4 100644 --- a/tests/auto/debugger/tst_gdb.cpp +++ b/tests/auto/debugger/tst_gdb.cpp @@ -278,9 +278,6 @@ private: Thread m_thread; }; -//QMutex m_mutex; -//QWaitCondition m_waitCondition; - QByteArray buffer; QSemaphore freeBytes(1); QSemaphore usedBytes(0); @@ -569,13 +566,6 @@ void tst_Gdb::check(const QByteArray &label, const QByteArray &expected0, qWarning() << label << "..."; 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 "; usedBytes.acquire(); //qDebug() << "\n1 AQUIRED USED "; @@ -602,7 +592,16 @@ void tst_Gdb::check(const QByteArray &label, const QByteArray &expected0, "children=[" + expected0 + "]}"; 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(','); bool ok = l1.size() == l2.size(); -- GitLab