From 538b09efc801e80c64df7ab9f07121c15bf47fae Mon Sep 17 00:00:00 2001
From: hjk <qtc-committer@nokia.com>
Date: Wed, 29 Jun 2011 11:48:12 +0200
Subject: [PATCH] debugger: add missing bridge.py

Change-Id: I7e236964007462ca203b898db06e15f77857916b
Reviewed-on: http://codereview.qt.nokia.com/1036
Reviewed-by: hjk <qthjk@ovi.com>
---
 share/qtcreator/dumper/bridge.py              | 239 ++++++++++++++++++
 .../gdbdebugger/simple/simple_gdbtest_app.cpp |  26 ++
 2 files changed, 265 insertions(+)
 create mode 100644 share/qtcreator/dumper/bridge.py

diff --git a/share/qtcreator/dumper/bridge.py b/share/qtcreator/dumper/bridge.py
new file mode 100644
index 00000000000..43c67f6f75f
--- /dev/null
+++ b/share/qtcreator/dumper/bridge.py
@@ -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
diff --git a/tests/manual/gdbdebugger/simple/simple_gdbtest_app.cpp b/tests/manual/gdbdebugger/simple/simple_gdbtest_app.cpp
index 7283d7e8f56..c490f0b4193 100644
--- a/tests/manual/gdbdebugger/simple/simple_gdbtest_app.cpp
+++ b/tests/manual/gdbdebugger/simple/simple_gdbtest_app.cpp
@@ -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();
-- 
GitLab