diff --git a/share/qtcreator/gdbmacros/pdumper.py b/share/qtcreator/gdbmacros/pdumper.py
new file mode 100644
index 0000000000000000000000000000000000000000..9086951e2b9699cd150554082df66350d2be447a
--- /dev/null
+++ b/share/qtcreator/gdbmacros/pdumper.py
@@ -0,0 +1,144 @@
+
+import pdb;
+import sys;
+import linecache
+
+
+class qdebug:
+    def __init__(self,
+            options = Null,
+            expanded = Null,
+            typeformats = Null,
+            individualformats = Null,
+            watchers = Null):
+        self.options = options
+        self.expanded = expanded
+        self.typeformats = typeformats
+        self.individualformats = individualformats
+        self.watchers = watchers
+        self.doit()
+
+    def put(self, value):
+        sys.stdout.write(value)
+
+    def putField(self, name, value):
+        self.put('%s="%s",' % (name, value))
+
+    def putItemCount(self, count):
+        self.put('value="<%s items>",' % count)
+
+    def putEllipsis(self):
+        self.put('{name="<incomplete>",value="",type="",numchild="0"},')
+
+    def cleanType(self, type):
+        t = str(type)
+        if t.startswith("<type '") and t.endswith("'>"):
+            t = t[7:-2]
+        return t
+
+    def putType(self, type, priority = 0):
+        self.putField("type", self.cleanType(type))
+
+    def putAddress(self, addr):
+        self.put('addr="%s",' % cleanAddress(addr))
+
+    def putNumChild(self, numchild):
+        self.put('numchild="%s",' % numchild)
+
+    def putValue(self, value, encoding = None, priority = 0):
+        self.putField("value", value)
+
+    def putName(self, name):
+        self.put('name="%s",' % name)
+
+    def isExpanded(self, item):
+        #warn("IS EXPANDED: %s in %s" % (item.iname, self.expandedINames))
+        if item.iname is None:
+            raise "Illegal iname 'None'"
+        if item.iname.startswith("None"):
+            raise "Illegal iname '%s'" % item.iname
+        #warn("   --> %s" % (item.iname in self.expandedINames))
+        return item.iname in self.expandedINames
+
+    def isExpandedIName(self, iname):
+        return iname in self.expandedINames
+
+    def itemFormat(self, item):
+        format = self.formats.get(str(cleanAddress(item.value.address)))
+        if format is None:
+            format = self.typeformats.get(stripClassTag(str(item.value.type)))
+        return format
+
+    def dumpFrame(self, frame):
+        for var in frame.f_locals.keys():
+            if var == "__file__":
+                continue
+            #if var == "__name__":
+            #    continue
+            if var == "__package__":
+                continue
+            if var == "qdebug":
+                continue
+            if var != '__builtins__':
+                value = frame.f_locals[var]
+                self.dumpValue(value, var, "local.%s" % var)
+
+    def dumpValue(self, value, name, iname):
+        t = type(value)
+        tt = self.cleanType(t)
+        if tt == "module" or tt == "function":
+            return
+        if tt == "list":
+            self.warn("LIST: %s" % dir(value))
+            self.put("{")
+            self.putField("iname", iname)
+            self.putName(name)
+            self.putType(tt)
+            self.putValue(value)
+            self.put("children=[")
+            for i in xrange(len(value)):
+                self.dumpValue(value[i], str(i), "%s.%d" % (iname, i))
+            self.put("]")
+            self.put("},")
+        elif tt != "module" and tt != "function":
+            self.put("{")
+            self.putField("iname", iname)
+            self.putName(name)
+            self.putType(tt)
+            self.putValue(value)
+            self.put("},")
+
+
+    def warn(self, msg):
+        self.putField("warning", msg)
+
+    def doit(self):
+        # Trigger error to get a backtrace.
+        frame = None
+        #self.warn("frame: %s" % frame)
+        try:
+            raise ZeroDivisionError
+        except ZeroDivisionError:
+            frame = sys.exc_info()[2].tb_frame.f_back
+
+        limit = 30
+        n = 0
+        isActive = False
+        while frame is not None and n < limit:
+            #self.warn("frame: %s" % frame.f_locals.keys())
+            lineno = frame.f_lineno
+            code = frame.f_code
+            filename = code.co_filename
+            name = code.co_name
+            if isActive:
+                linecache.checkcache(filename)
+                line = linecache.getline(filename, lineno, frame.f_globals)
+                self.dumpFrame(frame)
+                if name == "<module>":
+                    isActive = False
+            if name == "trace_dispatch":
+                isActive = True
+            frame = frame.f_back
+            n = n + 1
+
+        sys.stdout.flush()
diff --git a/src/plugins/debugger/debugger.pro b/src/plugins/debugger/debugger.pro
index 05c0a0d9c35fda7de0a798dd0239b65fec5c25ee..6bbfe4974399ba84ca79a4e69e6efd3fb94d8593 100644
--- a/src/plugins/debugger/debugger.pro
+++ b/src/plugins/debugger/debugger.pro
@@ -57,6 +57,7 @@ SOURCES += breakhandler.cpp \
     debuggerplugin.cpp \
     debuggerrunner.cpp \
     debuggertooltip.cpp \
+    idebuggerengine.cpp \
     moduleshandler.cpp \
     moduleswindow.cpp \
     outputcollector.cpp \
diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h
index c1bc7b57f0e5fe147fdef0a27d45a54ce1aa36d9..2093e54346ff13fd6f1169d76370ca25d47bb276 100644
--- a/src/plugins/debugger/gdb/gdbengine.h
+++ b/src/plugins/debugger/gdb/gdbengine.h
@@ -141,11 +141,6 @@ private: ////////// Gdb Process Management //////////
     void handleInferiorShutdown(const GdbResponse &response);
     void handleGdbExit(const GdbResponse &response);
 
-    void showDebuggerInput(int channel, const QString &msg)
-        { m_manager->showDebuggerInput(channel, msg); }
-    void showDebuggerOutput(int channel, const QString &msg)
-        { m_manager->showDebuggerOutput(channel, msg); }
-
 private slots:
     void handleGdbFinished(int, QProcess::ExitStatus status);
     void handleGdbError(QProcess::ProcessError error);
diff --git a/src/plugins/debugger/gdb/pythongdbengine.cpp b/src/plugins/debugger/gdb/pythongdbengine.cpp
index 112b172d73f888b5108facee359367f3e53fea52..3edf26905ac4ef280b50aafecee4efa69da03528 100644
--- a/src/plugins/debugger/gdb/pythongdbengine.cpp
+++ b/src/plugins/debugger/gdb/pythongdbengine.cpp
@@ -55,10 +55,9 @@ void GdbEngine::updateLocalsPython(const QByteArray &varList)
     //m_toolTipExpression.clear();
     WatchHandler *handler = m_manager->watchHandler();
 
-    QByteArray expanded = handler->formatRequests();
-    if (expanded.isEmpty())
-        expanded.append("defaults,");
-    expanded.chop(1);
+    QByteArray expanded = "expanded:" + handler->expansionRequests() + ' ';
+    expanded += "typeformats:" + handler->typeFormatRequests() + ' ';
+    expanded += "formats:" + handler->individualFormatRequests();
 
     QByteArray watchers;
     if (!m_toolTipExpression.isEmpty())
diff --git a/src/plugins/debugger/idebuggerengine.cpp b/src/plugins/debugger/idebuggerengine.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..de8d7eefe1af2fc83511919a7069f91021dbd153
--- /dev/null
+++ b/src/plugins/debugger/idebuggerengine.cpp
@@ -0,0 +1,71 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "idebuggerengine.h"
+#include "debuggermanager.h"
+
+
+namespace Debugger {
+namespace Internal {
+
+void IDebuggerEngine::fetchMemory(MemoryViewAgent *, QObject *,
+        quint64 addr, quint64 length)
+{
+    Q_UNUSED(addr);
+    Q_UNUSED(length);
+}
+
+void IDebuggerEngine::setRegisterValue(int regnr, const QString &value)
+{
+    Q_UNUSED(regnr);
+    Q_UNUSED(value);
+}
+
+bool IDebuggerEngine::checkConfiguration(int toolChain,
+    QString *errorMessage, QString *settingsPage) const
+{
+    Q_UNUSED(toolChain);
+    Q_UNUSED(errorMessage);
+    Q_UNUSED(settingsPage);
+    return true;
+}
+
+void IDebuggerEngine::showDebuggerInput(int channel, const QString &msg)
+{
+    m_manager->showDebuggerInput(channel, msg);
+}
+
+void IDebuggerEngine::showDebuggerOutput(int channel, const QString &msg)
+{
+    m_manager->showDebuggerOutput(channel, msg);
+}
+
+} // namespace Internal
+} // namespace Debugger
+
diff --git a/src/plugins/debugger/idebuggerengine.h b/src/plugins/debugger/idebuggerengine.h
index 3cf48f5a14fdf6d41f39705cbecd6329b78c34b7..f093376325397069ee98c06ecaa20368dcf06988 100644
--- a/src/plugins/debugger/idebuggerengine.h
+++ b/src/plugins/debugger/idebuggerengine.h
@@ -113,18 +113,23 @@ public:
     virtual void reloadFullStack() = 0;
 
     virtual void watchPoint(const QPoint &) {}
-    virtual void fetchMemory(MemoryViewAgent *, QObject *, quint64 addr, quint64 length)
-        { Q_UNUSED(addr); Q_UNUSED(length); }
+    virtual void fetchMemory(MemoryViewAgent *, QObject *,
+            quint64 addr, quint64 length);
     virtual void fetchDisassembler(DisassemblerViewAgent *) {}
-    virtual void setRegisterValue(int regnr, const QString &value)
-        { Q_UNUSED(regnr); Q_UNUSED(value); }
-
+    virtual void setRegisterValue(int regnr, const QString &value);
     virtual void addOptionPages(QList<Core::IOptionsPage*> *) const {}
     virtual unsigned debuggerCapabilities() const { return 0; }
-    virtual bool checkConfiguration(int /* toolChain */, QString * /* errorMessage */, QString * /* settingsPage */ = 0) const { return true; }
+
+    virtual bool checkConfiguration(int toolChain,
+        QString *errorMessage, QString *settingsPage = 0) const;
 
     virtual bool isSynchroneous() const { return false; }
     virtual QString qtNamespace() const { return QString(); }
+
+    // Convenience
+    void showDebuggerInput(int channel, const QString &msg);
+    void showDebuggerOutput(int channel, const QString &msg);
+
 protected:
     void showStatusMessage(const QString &msg, int timeout = -1);
     DebuggerState state() const;
diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp
index e4a3bb61ab699dd394492e2c3ade4feabcac3ad8..b4cfd13f26e6acdb9fa1fc4eb606508c17283e1d 100644
--- a/src/plugins/debugger/watchhandler.cpp
+++ b/src/plugins/debugger/watchhandler.cpp
@@ -1390,13 +1390,11 @@ int WatchHandler::format(const QByteArray &iname) const
     return result;
 }
 
-QByteArray WatchHandler::formatRequests() const
+QByteArray WatchHandler::expansionRequests() const
 {
     QByteArray ba;
     //m_locals->formatRequests(&ba, m_locals->m_root);
     //m_watchers->formatRequests(&ba, m_watchers->m_root);
-
-    ba.append("expanded:");
     if (!m_expandedINames.isEmpty()) {
         QSetIterator<QByteArray> jt(m_expandedINames);
         while (jt.hasNext()) {
@@ -1406,9 +1404,12 @@ QByteArray WatchHandler::formatRequests() const
         }
         ba.chop(1);
     }
-    ba.append(' ');
+    return ba;
+}
 
-    ba.append("typeformats:");
+QByteArray WatchHandler::typeFormatRequests() const
+{
+    QByteArray ba;
     if (!m_typeFormats.isEmpty()) {
         QHashIterator<QString, int> it(m_typeFormats);
         while (it.hasNext()) {
@@ -1420,9 +1421,12 @@ QByteArray WatchHandler::formatRequests() const
         }
         ba.chop(1);
     }
-    ba.append(' ');
+    return ba;
+}
 
-    ba.append("formats:");
+QByteArray WatchHandler::individualFormatRequests() const
+{
+    QByteArray ba;
     if (!m_individualFormats.isEmpty()) {
         QHashIterator<QByteArray, int> it(m_individualFormats);
         while (it.hasNext()) {
@@ -1434,8 +1438,6 @@ QByteArray WatchHandler::formatRequests() const
         }
         ba.chop(1);
     }
-    ba.append(' ');
-
     return ba;
 }
 
diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h
index 38bb85c87d43e06f6991aeb0cf1ea2200da9d57c..8890dee507956f5af85a4aed221b48c74f76c52e 100644
--- a/src/plugins/debugger/watchhandler.h
+++ b/src/plugins/debugger/watchhandler.h
@@ -173,7 +173,10 @@ public:
     QStringList watchedExpressions() const;
     QHash<QByteArray, int> watcherNames() const
         { return m_watcherNames; }
-    QByteArray formatRequests() const;
+
+    QByteArray expansionRequests() const;
+    QByteArray typeFormatRequests() const;
+    QByteArray individualFormatRequests() const;
 
     static QString watcherEditPlaceHolder();
     int format(const QByteArray &iname) const;
diff --git a/tests/manual/gdbdebugger/python/math.py b/tests/manual/gdbdebugger/python/math.py
index 5b8fbcce4496e483eb8a663d3667bca2ff51f761..63f3b2a7d52d987beb37d360bee54a7d668daaf6 100644
--- a/tests/manual/gdbdebugger/python/math.py
+++ b/tests/manual/gdbdebugger/python/math.py
@@ -4,6 +4,7 @@ def square(a):
     return a
 
 def cube(a):
+    l = [1, 2, 4]
     x = square(a)
     x = x * a
     x = x + 1