From 73fdc207ced14a8082eab0eff6086bcf93b2b9e8 Mon Sep 17 00:00:00 2001 From: hjk <qthjk@ovi.com> Date: Fri, 6 Jan 2012 02:33:02 +0100 Subject: [PATCH] debugger: make dumper more robust in optimized code Change-Id: Ia398caf0fd29e6ac77502d870e8c9b615d4f395e Reviewed-by: hjk <qthjk@ovi.com> --- share/qtcreator/dumper/bridge.py | 45 +++++++++++++++------ share/qtcreator/dumper/dumper.py | 68 +++++++++++++++++++++----------- 2 files changed, 77 insertions(+), 36 deletions(-) diff --git a/share/qtcreator/dumper/bridge.py b/share/qtcreator/dumper/bridge.py index ffbdbfc2e20..9a1ec524dcc 100644 --- a/share/qtcreator/dumper/bridge.py +++ b/share/qtcreator/dumper/bridge.py @@ -119,7 +119,6 @@ try: # "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] @@ -133,19 +132,41 @@ try: item.iname = "local." + name1 item.name = name1 try: - item.value = frame.read_var(name, block) # this is a gdb value + item.value = frame.read_var(name, block) + #warn("READ 1: %s" % item.value) + if not item.value.is_optimized_out: + #warn("ITEM 1: %s" % item.value) + items.append(item) + continue 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() + pass + + try: + item.value = frame.read_var(name) + #warn("READ 2: %s" % item.value) + if not item.value.is_optimized_out: + #warn("ITEM 2: %s" % item.value) + items.append(item) continue - #warn("ITEM %s: " % item.value) - items.append(item) + 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() + pass + + try: + #warn("READ 3: %s %s" % (name, item.value)) + item.value = gdb.parse_and_eval(name) + #warn("ITEM 3: %s" % item.value) + items.append(item) + except: + # Can happen in inlined code (see last line of + # RowPainter::paintChars(): "RuntimeError: + # No symbol \"__val\" in current context.\n" + pass + # The outermost block in a function has the function member # FIXME: check whether this is guaranteed. if not block.function is None: diff --git a/share/qtcreator/dumper/dumper.py b/share/qtcreator/dumper/dumper.py index c7707879bfa..ab3f7c24ec0 100644 --- a/share/qtcreator/dumper/dumper.py +++ b/share/qtcreator/dumper/dumper.py @@ -1391,16 +1391,6 @@ class Dumper: type = value.type.unqualified() typeName = str(type) - try: - if value.is_optimized_out: - self.putValue("<optimized out>") - self.putType(typeName) - self.putNumChild(0) - return - except: - pass - - # FIXME: Gui shows references stripped? #warn(" ") #warn("REAL INAME: %s " % self.currentIName) @@ -1409,44 +1399,65 @@ class Dumper: #warn("REAL VALUE: %s " % value) if type.code == ReferenceCode: - #try: - # This throws "RuntimeError: Attempt to dereference a + try: + # FIXME: This throws "RuntimeError: Attempt to dereference a # generic pointer." with MinGW's gcc 4.5 when it "identifies" - # a "QWidget &" as "void &". - self.putItem(value.cast(type.target())) + # a "QWidget &" as "void &" and with optimized out code. + self.putItem(value.cast(type.target().unqualified())) + return + except RuntimeError: + self.putValue("<optimized out reference>") + self.putType(typeName) + self.putNumChild(0) return - #except RuntimeError: - # pass if type.code == IntCode or type.code == CharCode: self.putAddress(value.address) self.putType(typeName) - self.putValue(int(value)) + if value.is_optimized_out: + self.putValue("<optimized out>") + else: + self.putValue(int(value)) self.putNumChild(0) return if type.code == FloatCode or type.code == BoolCode: self.putAddress(value.address) self.putType(typeName) - self.putValue(value) + if value.is_optimized_out: + self.putValue("<optimized out>") + else: + self.putValue(value) self.putNumChild(0) return if type.code == EnumCode: + self.putAddress(value.address) self.putType(typeName) - self.putValue("%s (%d)" % (value, value)) + if value.is_optimized_out: + self.putValue("<optimized out>") + else: + self.putValue("%s (%d)" % (value, value)) self.putNumChild(0) return if type.code == TypedefCode: - type = type.strip_typedefs() + type = stripTypedefs(type) # The cast can destroy the address? self.putAddress(value.address) # Workaround for http://sourceware.org/bugzilla/show_bug.cgi?id=13380 if type.code == ArrayCode: value = parseAndEvaluate("{%s}%s" % (type, value.address)) else: - value = value.cast(type.strip_typedefs()) + try: + value = value.cast(type) + self.putItem(value) + except: + self.putValue("<optimized out typedef>") + self.putType(typeName) + self.putNumChild(0) + return + self.putItem(value) self.putBetterType(typeName) return @@ -1484,8 +1495,16 @@ class Dumper: if type.code == PointerCode: #warn("POINTER: %s" % value) - if not isAccessible(value): - self.currentValue = None + # This could still be stored in a register and + # potentially dereferencable. + if value.is_optimized_out: + self.putValue("<optimized out>") + + try: + value.dereference() + except: + self.putValue("<optimized out>") + self.putType(typeName) self.putNumChild(0) return @@ -1625,7 +1644,8 @@ class Dumper: if self.useDynamicType: - dtypeName = dynamicTypeName(value) + dtypeName = dynamicTypeName(value.cast(type)) + #dtypeName = str(lookupType(dtypeName)) # Strip const etc. FIXME else: dtypeName = typeName -- GitLab