debugger: add missing bridge.py

Change-Id: I7e236964007462ca203b898db06e15f77857916b
Reviewed-on: http://codereview.qt.nokia.com/1036
Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
hjk
2011-06-29 11:48:12 +02:00
committed by hjk
parent 36a3028b9d
commit 538b09efc8
2 changed files with 265 additions and 0 deletions

View File

@@ -0,0 +1,239 @@
try:
import lldb_bridge
except:
pass
#try:
if True:
import gdb
def registerCommand(name, func):
class Command(gdb.Command):
def __init__(self):
super(Command, self).__init__(name, gdb.COMMAND_OBSCURE)
def invoke(self, args, from_tty):
output = func(args)
try:
print(output)
except:
out = ""
for c in output:
cc = ord(c)
if cc > 127:
out += "\\\\%d" % cc
elif cc < 0:
out += "\\\\%d" % (cc + 256)
else:
out += c
print(out)
Command()
def isGoodGdb():
#return gdb.VERSION.startswith("6.8.50.2009") \
# and gdb.VERSION != "6.8.50.20090630-cvs"
return 'parse_and_eval' in __builtin__.dir(gdb)
def parseAndEvaluate(exp):
if isGoodGdb():
return gdb.parse_and_eval(exp)
# Work around non-existing gdb.parse_and_eval as in released 7.0
gdb.execute("set logging redirect on")
gdb.execute("set logging on")
try:
gdb.execute("print %s" % exp)
except:
gdb.execute("set logging off")
gdb.execute("set logging redirect off")
return None
gdb.execute("set logging off")
gdb.execute("set logging redirect off")
return gdb.history(0)
def listOfLocals(varList):
frame = gdb.selected_frame()
try:
frame = gdb.selected_frame()
#warn("FRAME %s: " % frame)
except RuntimeError, error:
warn("FRAME NOT ACCESSIBLE: %s" % error)
return []
except:
warn("FRAME NOT ACCESSIBLE FOR UNKNOWN REASONS")
return []
# New in 7.2
hasBlock = 'block' in __builtin__.dir(frame)
items = []
#warn("HAS BLOCK: %s" % hasBlock)
if hasBlock and isGoodGdb():
#warn("IS GOOD: %s " % varList)
try:
block = frame.block()
#warn("BLOCK: %s " % block)
except RuntimeError, error:
warn("BLOCK IN FRAME NOT ACCESSIBLE: %s" % error)
return items
except:
warn("BLOCK NOT ACCESSIBLE FOR UNKNOWN REASONS")
return items
shadowed = {}
while True:
if block is None:
warn("UNEXPECTED 'None' BLOCK")
break
for symbol in block:
name = symbol.print_name
if name == "__in_chrg":
continue
# "NotImplementedError: Symbol type not yet supported in
# Python scripts."
#warn("SYMBOL %s: " % symbol.value)
#warn("SYMBOL %s (%s): " % (symbol, name))
if name in shadowed:
level = shadowed[name]
name1 = "%s <shadowed %s>" % (name, level)
shadowed[name] = level + 1
else:
name1 = name
shadowed[name] = 1
#warn("SYMBOL %s (%s, %s)): " % (symbol, name, symbol.name))
item = Item(0, "local", name1, name1)
try:
item.value = frame.read_var(name, block) # this is a gdb value
except:
try:
item.value = frame.read_var(name) # this is a gdb value
except:
# RuntimeError: happens for
# void foo() { std::string s; std::wstring w; }
# ValueError: happens for (as of 2010/11/4)
# a local struct as found e.g. in
# gcc sources in gcc.c, int execute()
continue
#warn("ITEM %s: " % item.value)
items.append(item)
# The outermost block in a function has the function member
# FIXME: check whether this is guaranteed.
if not block.function is None:
break
block = block.superblock
else:
# Assuming gdb 7.0 release or 6.8-symbianelf.
filename, file = createTempFile()
#warn("VARLIST: %s " % varList)
#warn("FILENAME: %s " % filename)
gdb.execute("set logging off")
gdb.execute("set logging redirect off")
gdb.execute("set logging file %s" % filename)
gdb.execute("set logging redirect on")
gdb.execute("set logging on")
try:
gdb.execute("info args")
# We cannot use "info locals" as at least 6.8-symbianelf
# aborts as soon as we hit unreadable memory.
# gdb.execute("interpreter mi '-stack-list-locals 0'")
# results in &"Recursive internal problem.\n", so we have
# the frontend pass us the list of locals.
# There are two cases, either varList is empty, so we have
# to fetch the list here, or it is not empty with the
# first entry being a dummy.
if len(varList) == 0:
gdb.execute("info locals")
else:
varList = varList[1:]
except:
pass
gdb.execute("set logging off")
gdb.execute("set logging redirect off")
try:
temp = open(filename, "r")
for line in temp:
if len(line) == 0 or line.startswith(" "):
continue
# The function parameters
pos = line.find(" = ")
if pos < 0:
continue
varList.append(line[0:pos])
temp.close()
except:
pass
removeTempFile(filename, file)
#warn("VARLIST: %s " % varList)
for name in varList:
#warn("NAME %s " % name)
item = Item(0, "local", name, name)
try:
item.value = frame.read_var(name) # this is a gdb value
except RuntimeError:
pass
#continue
except:
# Something breaking the list, like intermediate gdb warnings
# like 'Warning: can't find linker symbol for virtual table for
# `std::less<char const*>' value\n\nwarning: found
# `myns::QHashData::shared_null' instead [...]
# that break subsequent parsing. Chicken out and take the
# next "usable" line.
continue
items.append(item)
return items
def catchCliOutput(command):
try:
return gdb.execute(command, to_string=True).split("\n")
except:
pass
filename, file = createTempFile()
gdb.execute("set logging off")
gdb.execute("set logging redirect off")
gdb.execute("set logging file %s" % filename)
gdb.execute("set logging redirect on")
gdb.execute("set logging on")
msg = ""
try:
gdb.execute(command)
except RuntimeError, error:
# For the first phase of core file loading this yield
# "No symbol table is loaded. Use the \"file\" command."
msg = str(error)
except:
msg = "Unknown error"
gdb.execute("set logging off")
gdb.execute("set logging redirect off")
if len(msg):
# Having that might confuse result handlers in the gdbengine.
#warn("CLI ERROR: %s " % msg)
return "CLI ERROR: %s " % msg
temp = open(filename, "r")
lines = []
for line in temp:
lines.append(line)
temp.close()
removeTempFile(filename, file)
return lines
#except:
# pass

View File

@@ -2935,8 +2935,34 @@ namespace qc41700 {
} // namespace qc41700
namespace cp42895 {
// http://codepaster.europe.nokia.com/?id=42895
void g(int c, int d)
{
qDebug() << c << d;
// <== break here
// Check there are frames for g and f in the stack view.
dummyStatement(&c, &d);
}
void f(int a, int b)
{
g(a, b);
}
void test42895()
{
f(3, 4);
}
} // namespace cp
int main(int argc, char *argv[])
{
cp42895::test42895();
bug5046::test5046();
bug4904::test4904();
qc41700::test41700();