forked from qt-creator/qt-creator
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:
239
share/qtcreator/dumper/bridge.py
Normal file
239
share/qtcreator/dumper/bridge.py
Normal 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
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user