forked from qt-creator/qt-creator
debugger: special handling of char *argv[] in l&w
It's nicer this way.
This commit is contained in:
@@ -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:
|
||||||
|
@@ -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();
|
||||||
|
Reference in New Issue
Block a user