diff --git a/share/qtcreator/gdbmacros/dumper.py b/share/qtcreator/gdbmacros/dumper.py
index 59b7f340bb1d286baab0e20abe78854f383ad1db..e2647d9ec86b528f87e323bc72d6cbc2c6437bee 100644
--- a/share/qtcreator/gdbmacros/dumper.py
+++ b/share/qtcreator/gdbmacros/dumper.py
@@ -32,8 +32,8 @@ def isGoodGdb():
     return 'parse_and_eval' in dir(gdb)
 
 def cleanAddress(addr):
-    # we cannot use str(addr) as it yields rubbish for char pointers
-    # that might trigger Unicode encoding errors
+    # We cannot use str(addr) as it yields rubbish for char pointers
+    # that might trigger Unicode encoding errors.
     return addr.cast(gdb.lookup_type("void").pointer())
 
 def parseAndEvaluate(exp):
@@ -50,17 +50,27 @@ def parseAndEvaluate(exp):
     gdb.execute("set logging off")
     return gdb.history(0)
 
-def listOfLocals():
+def listOfLocals(varList):
     try:
         frame = gdb.selected_frame()
         #warn("FRAME %s: " % frame)
     except RuntimeError:
+        warn("FRAME NOT ACCESSIBLE")
         return []
 
+    # gdb-6.8-symbianelf fails here
+    hasBlock = 'block' in dir(frame)
+
     items = []
-    if isGoodGdb():
-        # archer-tromey-python
-        block = frame.block()
+    if hasBlock and isGoodGdb():
+        warn("IS GOOD: %s " % varList)
+        try:
+            block = frame.block()
+            #warn("BLOCK: %s " % block)
+        except:
+            warn("BLOCK NOT ACCESSIBLE")
+            return items
+
         while True:
             if block is None:
                 warn("UNEXPECTED 'None' BLOCK")
@@ -94,31 +104,55 @@ def listOfLocals():
         # Assuming gdb 7.0 release or 6.8-symbianelf.
         file = tempfile.mkstemp(prefix="gdbpy_")
         filename = file[1]
+        #warn("VARLIST: %s " % varList)
+        #warn("VARLIST: %s " % len(varList))
         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")
-        gdb.execute("info locals")
-        gdb.execute("info args")
+        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")
+
         file = open(filename, "r")
         for line in file:
             if len(line) == 0 or line.startswith(" "):
                 continue
+            # The function parameters
             pos = line.find(" = ")
             if pos < 0:
                 continue
-            name = line[0:pos]
+            varList.append(line[0:pos])
+        file.close()
+        os.remove(filename)
+
+        #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:
-                continue
+                pass
+                #continue
             items.append(item)
-        file.close()
-        os.remove(filename)
 
     return items
 
@@ -155,8 +189,8 @@ def isStringType(d, typeobj):
         or type == "wstring"
 
 def warn(message):
-    if verbosity > 0:
-        print "XXX: %s " % message.encode("latin1")
+    if True or verbosity > 0:
+        print "XXX: %s\n" % message.encode("latin1")
     pass
 
 def check(exp):
@@ -317,13 +351,24 @@ class FrameCommand(gdb.Command):
 
     def invoke(self, arg, from_tty):
         args = arg.split(' ')
+
         #warn("ARG: %s" % arg)
         #warn("ARGS: %s" % args)
         options = args[0].split(",")
+        varList = args[1][1:]
+        if len(varList) == 0:
+            varList = []
+        else:
+            varList = varList.split(",")
+        expandedINames = set(args[2].split(","))
+        watchers = ""
+        if len(args) > 3:
+            watchers = base64.b16decode(args[3], True)
+        #warn("WATCHERS: %s" % watchers)
+
         useFancy = "fancy" in options
-        expandedINames = set()
-        if len(args) > 1:
-            expandedINames = set(args[1].split(","))
+
+        #warn("VARIABLES: %s" % varList)
         #warn("EXPANDED INAMES: %s" % expandedINames)
         module = sys.modules[__name__]
         self.dumpers = {}
@@ -337,7 +382,7 @@ class FrameCommand(gdb.Command):
                     output += '"' + key[7:] + '"'
             output += "],"
             #output += "qtversion=[%d,%d,%d]"
-            output += "qtversion=[4,6,0],"
+            #output += "qtversion=[4,6,0],"
             output += "namespace=\"%s\"," % qtNamespace()
             output += "dumperversion=\"2.0\","
             output += "sizes=[],"
@@ -349,7 +394,6 @@ class FrameCommand(gdb.Command):
 
         if useFancy:
             for key, value in module.__dict__.items():
-                #if callable(value):
                 if key.startswith("qdump__"):
                     self.dumpers[key[7:]] = value
 
@@ -365,14 +409,28 @@ class FrameCommand(gdb.Command):
         #
         # Locals
         #
-        for item in listOfLocals():
+        for item in listOfLocals(varList):
             #warn("ITEM NAME %s: " % item.name)
-            #warn("ITEM VALUE %s: " % item.value)
+            try:
+                #warn("ITEM VALUE %s: " % item.value)
+                # Throw on funny stuff, catch below.
+                dummy = str(item.value)
+            except:
+                # Locals with failing memory access.
+                d.beginHash()
+                d.put('iname="%s",' % item.iname)
+                d.put('name="%s",' % item.name)
+                d.put('addr="<not accessible>",')
+                d.put('value="<not accessible>",')
+                d.put('type="%s",' % item.value.type)
+                d.put('numchild="0"');
+                d.endHash()
+                continue
 
             type = item.value.type
             if type.code == gdb.TYPE_CODE_PTR \
                     and item.name == "argv" and str(type) == "char **":
-                # Special handling for char** argv:
+                # Special handling for char** argv.
                 n = 0
                 p = item.value
                 while not isNull(p.dereference()) and n <= 100:
@@ -398,7 +456,7 @@ class FrameCommand(gdb.Command):
                 d.endHash()
 
             else:
-                # A "normal" local variable or parameter
+                # A "normal" local variable or parameter.
                 try:
                     addr = cleanAddress(item.value.address)
                     d.beginHash()
@@ -407,9 +465,8 @@ class FrameCommand(gdb.Command):
                     d.safePutItemHelper(item)
                     d.endHash()
                 except AttributeError:
-                    # thrown by cleanAddreas with message
-                    # "'NoneType' object has no attribute 'cast'"
-                    # for optimized-out values
+                    # Thrown by cleanAddress with message "'NoneType' object
+                    # has no attribute 'cast'" for optimized-out values.
                     d.beginHash()
                     d.put('iname="%s",' % item.iname)
                     d.put('name="%s",' % item.name)
@@ -426,9 +483,6 @@ class FrameCommand(gdb.Command):
         # Watchers
         #
         d.safeoutput = ""
-        watchers = ""
-        if len(args) > 2:
-            watchers = base64.b16decode(args[2], True)
         if len(watchers) > 0:
             for watcher in watchers.split("##"):
                 (exp, iname) = watcher.split("#")
@@ -764,7 +818,8 @@ class Dumper:
         #warn("REAL VALUE: %s " % item.value)
         #try:
         #    warn("REAL VALUE: %s " % item.value)
-        #except UnicodeEncodeError:
+        #except:
+        #    #UnicodeEncodeError:
         #    warn("REAL VALUE: <unprintable>")
 
         value = item.value
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index 61ad74dcd4ea1884bf125e6514df23871e86813b..9450c741993872c1e4a926ee15d46e7c2e88f5cf 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -743,7 +743,7 @@ void GdbEngine::postCommand(const QByteArray &command, GdbCommandFlags flags,
 void GdbEngine::postCommandHelper(const GdbCommand &cmd)
 {
     if (!stateAcceptsGdbCommands(state())) {
-        PENDING_DEBUG(_("NO GDB PROCESS RUNNING, CMD IGNORED: ") + cmd.command);
+        PENDING_DEBUG(_("NO GDB PROCESS RUNNING, CMD IGNORED: " + cmd.command));
         debugMessage(_("NO GDB PROCESS RUNNING, CMD IGNORED: %1 %2")
             .arg(_(cmd.command)).arg(state()));
         return;
@@ -1019,6 +1019,7 @@ void GdbEngine::executeDebuggerCommand(const QString &command)
 // Called from CoreAdapter and AttachAdapter
 void GdbEngine::updateAll()
 {
+    PENDING_DEBUG("UPDATING ALL\n");
     QTC_ASSERT(state() == InferiorUnrunnable || state() == InferiorStopped, /**/);
     tryLoadDebuggingHelpers();
     reloadModulesInternal();
@@ -2469,12 +2470,14 @@ void GdbEngine::handleStackSelectThread(const GdbResponse &)
 
 void GdbEngine::reloadFullStack()
 {
+    PENDING_DEBUG("RELOAD FULL STACK");
     postCommand("-stack-list-frames", WatchUpdate, CB(handleStackListFrames),
         QVariant::fromValue<StackCookie>(StackCookie(true, true)));
 }
 
 void GdbEngine::reloadStack(bool forceGotoLocation)
 {
+    PENDING_DEBUG("RELOAD STACK");
     QByteArray cmd = "-stack-list-frames";
     int stackDepth = theDebuggerAction(MaximalStackDepth)->value().toInt();
     if (stackDepth && !m_gdbAdapter->isTrkAdapter())
@@ -2485,6 +2488,7 @@ void GdbEngine::reloadStack(bool forceGotoLocation)
     // access the memory belonging to the lower frames. But as we know
     // this sometimes happens, ask the second time immediately instead
     // of waiting for the first request to fail.
+    // FIXME: Seems to work with 6.8.
     if (m_gdbAdapter->isTrkAdapter())
         postCommand(cmd, WatchUpdate);
     postCommand(cmd, WatchUpdate, CB(handleStackListFrames),
@@ -3640,52 +3644,12 @@ void GdbEngine::updateLocals(const QVariant &cookie)
 {
     m_pendingRequests = 0;
     if (isSynchroneous()) {
-        m_processedNames.clear();
-        manager()->watchHandler()->beginCycle();
-        //m_toolTipExpression.clear();
-        WatchHandler *handler = m_manager->watchHandler();
-
-        QByteArray expanded;
-        QSet<QByteArray> expandedINames = handler->expandedINames();
-        QSetIterator<QByteArray> jt(expandedINames);
-        while (jt.hasNext()) {
-            expanded.append(jt.next());
-            expanded.append(',');
-        }
-        if (expanded.isEmpty())
-            expanded.append("defaults,");
-        expanded.chop(1);
-
-        QByteArray watchers;
-        if (!m_toolTipExpression.isEmpty())
-            watchers += m_toolTipExpression.toLatin1()
-                + "#" + tooltipINameForExpression(m_toolTipExpression.toLatin1());
-
-        QHash<QByteArray, int> watcherNames = handler->watcherNames();
-        QHashIterator<QByteArray, int> it(watcherNames);
-        while (it.hasNext()) {
-            it.next();
-            if (!watchers.isEmpty())
-                watchers += "##";
-            if (it.key() == WatchHandler::watcherEditPlaceHolder().toLatin1())
-                watchers += "<Edit>#watch." + QByteArray::number(it.value());
-            else
-                watchers += it.key() + "#watch." + QByteArray::number(it.value());
+        if (m_gdbAdapter->isTrkAdapter()) {
+            postCommand("-stack-list-locals 0",
+                WatchUpdate, CB(handleStackListLocals0));
+        } else {
+            updateLocalsSync(QByteArray());
         }
-
-        QByteArray options;
-        if (theDebuggerBoolSetting(UseDebuggingHelpers))
-            options += "fancy,";
-        if (theDebuggerBoolSetting(AutoDerefPointers))
-            options += "autoderef,";
-        if (options.isEmpty())
-            options += "defaults,";
-        options.chop(1);
-
-        postCommand("-interpreter-exec console \"bb "
-            + options + ' ' + expanded + ' ' + watchers.toHex() + '"',
-            Discardable,
-            CB(handleStackFrame));
     } else {
         m_processedNames.clear();
 
@@ -3710,6 +3674,69 @@ void GdbEngine::updateLocals(const QVariant &cookie)
     }
 }
 
+void GdbEngine::handleStackListLocals0(const GdbResponse &response)
+{
+    if (response.resultClass == GdbResultDone) {
+        // 44^done,data={locals=[name="model",name="backString",...]}
+        QByteArray varList = "vars"; // Dummy entry, will be stripped by dumper.
+        foreach (const GdbMi &child, response.data.findChild("locals").children()) {
+            varList.append(',');
+            varList.append(child.data());
+        }
+        updateLocalsSync(varList);
+    }
+}
+
+void GdbEngine::updateLocalsSync(const QByteArray &varList)
+{
+    m_processedNames.clear();
+    manager()->watchHandler()->beginCycle();
+    //m_toolTipExpression.clear();
+    WatchHandler *handler = m_manager->watchHandler();
+
+    QByteArray expanded;
+    QSet<QByteArray> expandedINames = handler->expandedINames();
+    QSetIterator<QByteArray> jt(expandedINames);
+    while (jt.hasNext()) {
+        expanded.append(jt.next());
+        expanded.append(',');
+    }
+    if (expanded.isEmpty())
+        expanded.append("defaults,");
+    expanded.chop(1);
+
+    QByteArray watchers;
+    if (!m_toolTipExpression.isEmpty())
+        watchers += m_toolTipExpression.toLatin1()
+            + "#" + tooltipINameForExpression(m_toolTipExpression.toLatin1());
+
+    QHash<QByteArray, int> watcherNames = handler->watcherNames();
+    QHashIterator<QByteArray, int> it(watcherNames);
+    while (it.hasNext()) {
+        it.next();
+        if (!watchers.isEmpty())
+            watchers += "##";
+        if (it.key() == WatchHandler::watcherEditPlaceHolder().toLatin1())
+            watchers += "<Edit>#watch." + QByteArray::number(it.value());
+        else
+            watchers += it.key() + "#watch." + QByteArray::number(it.value());
+    }
+
+    QByteArray options;
+    if (theDebuggerBoolSetting(UseDebuggingHelpers))
+        options += "fancy,";
+    if (theDebuggerBoolSetting(AutoDerefPointers))
+        options += "autoderef,";
+    if (options.isEmpty())
+        options += "defaults,";
+    options.chop(1);
+
+    postCommand("bb " + options + " @" + varList + ' '
+            + expanded + ' ' + watchers.toHex(),
+        WatchUpdate, CB(handleStackFrame));
+}
+
+
 void GdbEngine::handleStackFrame(const GdbResponse &response)
 {
     if (response.resultClass == GdbResultDone) {
diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h
index e7fb08ab2015d2b40c2a1a73ec86a49fcf87e020..8123827b6345d527f586bf89faa828fce5997da2 100644
--- a/src/plugins/debugger/gdb/gdbengine.h
+++ b/src/plugins/debugger/gdb/gdbengine.h
@@ -450,6 +450,7 @@ private: ////////// View & Data Stuff //////////
 
     void updateLocals(const QVariant &cookie = QVariant());
     void handleStackListLocals(const GdbResponse &response);
+    void handleStackListLocals0(const GdbResponse &response);
     WatchData localVariable(const GdbMi &item,
                             const QStringList &uninitializedVariables,
                             QMap<QByteArray, int> *seen);
@@ -484,6 +485,8 @@ private: ////////// Convenience Functions //////////
         int buttons = 0);
     void debugMessage(const QString &msg);
     QMainWindow *mainWindow() const;
+
+    void updateLocalsSync(const QByteArray &varList);
 };
 
 } // namespace Internal