forked from qt-creator/qt-creator
Change-Id: I7e236964007462ca203b898db06e15f77857916b Reviewed-on: http://codereview.qt.nokia.com/1036 Reviewed-by: hjk <qthjk@ovi.com>
240 lines
8.3 KiB
Python
240 lines
8.3 KiB
Python
|
|
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
|