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