diff --git a/src/libs/qtcreatorcdbext/common.h b/src/libs/qtcreatorcdbext/common.h
index 1fd427368fec863cb7cd06858fd6fca968222c81..3263d69351d125bac5f96ff0f4e39a91a0cfc407 100644
--- a/src/libs/qtcreatorcdbext/common.h
+++ b/src/libs/qtcreatorcdbext/common.h
@@ -46,8 +46,6 @@
 #include <wdbgexts.h>
 #include <dbgeng.h>
 
-static const char creatorOutputPrefixC[] = "QtCreatorExt: ";
-
 typedef IDebugControl CIDebugControl;
 typedef IDebugSymbols3 CIDebugSymbols;
 typedef IDebugSymbolGroup2 CIDebugSymbolGroup;
diff --git a/src/libs/qtcreatorcdbext/eventcallback.h b/src/libs/qtcreatorcdbext/eventcallback.h
index b066923dd25332a6b89f3d34e28b519b03e676e4..d6e9b9daa0f03c2fcd15f60a00eaf9b8198c541e 100644
--- a/src/libs/qtcreatorcdbext/eventcallback.h
+++ b/src/libs/qtcreatorcdbext/eventcallback.h
@@ -37,8 +37,8 @@
 #include "common.h"
 #include "extensioncontext.h"
 
-/* IDebugEventCallbacks event handler wrapping IDebugEventCallbacks to catch some output */
-
+/* IDebugEventCallbacks event handler wrapping the original IDebugEventCallbacks
+ * to catch and store exceptions (report crashes as stop reasons). */
 class EventCallback : public IDebugEventCallbacks
 {
 public:
diff --git a/src/libs/qtcreatorcdbext/extensioncontext.h b/src/libs/qtcreatorcdbext/extensioncontext.h
index 4a7ee97682286f3252b52894058e233cc21ff5ad..309f95e3799be7ce114f47ba32c29ab3c5f5c23e 100644
--- a/src/libs/qtcreatorcdbext/extensioncontext.h
+++ b/src/libs/qtcreatorcdbext/extensioncontext.h
@@ -85,11 +85,11 @@ public:
     // register as '.idle_cmd' to notify creator about stop
     void notifyIdle();
 
-    // Return symbol group for frame (cache as long as frame does not change).
+    // Return symbol group for frame (cached as long as frame/thread do not change).
     SymbolGroup *symbolGroup(CIDebugSymbols *symbols, ULONG threadId, int frame, std::string *errorMessage);
     int symbolGroupFrame() const;
 
-    // Stop reason is reported with the next idle notification
+    // Set a stop reason to be reported with the next idle notification (exception).
     void setStopReason(const StopReasonMap &, const std::string &reason = std::string());
 
 private:
@@ -109,6 +109,7 @@ private:
 };
 
 // Context for extension commands to be instantiated on stack in a command handler.
+// Provides the IDebug objects on demand.
 class ExtensionCommandContext
 {
     ExtensionCommandContext(const ExtensionCommandContext&);
diff --git a/src/libs/qtcreatorcdbext/knowntype.h b/src/libs/qtcreatorcdbext/knowntype.h
index 34fb12f53058988f28de00265a30a935b943f544..bd173fbecd407e826189299c2695f2f6819e744f 100644
--- a/src/libs/qtcreatorcdbext/knowntype.h
+++ b/src/libs/qtcreatorcdbext/knowntype.h
@@ -34,10 +34,11 @@
 #ifndef KNOWNTYPE_H
 #define KNOWNTYPE_H
 
-// Helpers for detecting types
+// Enumeration describing a type.
 enum KnownType
 {
     KT_Unknown =0,
+    // Flags to be used in type values.
     KT_POD_Type = 0x10000,
     KT_Qt_Type = 0x20000,
     KT_Qt_PrimitiveType = 0x40000,
@@ -46,7 +47,7 @@ enum KnownType
     KT_ContainerType = 0x200000,
     KT_HasSimpleDumper = 0x400000,
     KT_HasComplexDumper = 0x800000, // Non-container complex dumper
-    // PODs
+    // Types: PODs
     KT_Char = KT_POD_Type + 1,
     KT_UnsignedChar = KT_POD_Type + 2,
     KT_IntType = KT_POD_Type + 3,         // any signed short, long, int
@@ -54,7 +55,7 @@ enum KnownType
     KT_FloatType = KT_POD_Type + 5,       // float, double
     KT_POD_PointerType = KT_POD_Type + 6,     // pointer to some POD
     KT_PointerType = KT_POD_Type + 7,     // pointer to class or complex type
-    // Qt Basic
+    // Types: Qt Basic
     KT_QChar = KT_Qt_Type + KT_Qt_MovableType + KT_HasSimpleDumper + 1,
     KT_QByteArray = KT_Qt_Type + KT_Qt_MovableType + KT_HasSimpleDumper + 2,
     KT_QString = KT_Qt_Type + KT_Qt_MovableType + KT_HasSimpleDumper + 3,
@@ -75,7 +76,7 @@ enum KnownType
     KT_QAtomicInt = KT_Qt_Type + KT_HasSimpleDumper + 19,
     KT_QObject = KT_Qt_Type + KT_HasSimpleDumper + KT_HasComplexDumper + 20,
     KT_QWidget = KT_Qt_Type + KT_HasSimpleDumper + KT_HasComplexDumper + 21,
-    // Various QT movable types
+    // Types: Various QT movable types
     KT_QPen = KT_Qt_Type + KT_Qt_MovableType + 30,
     KT_QUrl = KT_Qt_Type + KT_Qt_MovableType + 31,
     KT_QIcon = KT_Qt_Type + KT_Qt_MovableType + 32,
@@ -134,7 +135,7 @@ enum KnownType
     KT_QPatternist_ItemSequenceCacheCell = KT_Qt_Type + KT_Qt_MovableType + 86,
     KT_QNetworkHeadersPrivate_RawHeaderPair = KT_Qt_Type + KT_Qt_MovableType + 87,
     KT_QPatternist_AccelTree_BasicNodeData = KT_Qt_Type + KT_Qt_MovableType + 88,
-    // Qt primitive types
+    // Types: Qt primitive types
     KT_QFixed = KT_Qt_Type + KT_Qt_PrimitiveType + 90,
     KT_QTextItem = KT_Qt_Type + KT_Qt_PrimitiveType + 91,
     KT_QFixedSize = KT_Qt_Type + KT_Qt_PrimitiveType + 92,
@@ -144,7 +145,7 @@ enum KnownType
     KT_QTextUndoCommand = KT_Qt_Type + KT_Qt_PrimitiveType + 96,
     KT_QGlyphJustification = KT_Qt_Type + KT_Qt_PrimitiveType + 97,
     KT_QPainterPath_Element = KT_Qt_Type + KT_Qt_PrimitiveType + 98,
-    // Qt Containers
+    // Types: Qt Containers
     KT_QStringList = KT_Qt_Type + KT_ContainerType + KT_HasSimpleDumper + 1,
     KT_QList = KT_Qt_Type + KT_ContainerType + KT_HasSimpleDumper + 2,
     KT_QLinkedList = KT_Qt_Type + KT_ContainerType + KT_HasSimpleDumper + 3,
@@ -156,10 +157,10 @@ enum KnownType
     KT_QMultiHash = KT_Qt_Type + KT_ContainerType + KT_HasSimpleDumper + 9,
     KT_QMap = KT_Qt_Type + KT_ContainerType + KT_HasSimpleDumper + 10,
     KT_QMultiMap = KT_Qt_Type + KT_ContainerType + KT_HasSimpleDumper + 11,
-    // STL
+    // Types: STL
     KT_StdString = KT_STL_Type + KT_HasSimpleDumper + 1,
     KT_StdWString = KT_STL_Type + KT_HasSimpleDumper + 2,
-    // STL containers
+    // Types: STL containers
     KT_StdVector =  KT_STL_Type + KT_ContainerType + KT_HasSimpleDumper + 1,
     KT_StdList =  KT_STL_Type + KT_ContainerType + KT_HasSimpleDumper + 2,
     KT_StdStack =  KT_STL_Type + KT_ContainerType + KT_HasSimpleDumper + 3,
diff --git a/src/libs/qtcreatorcdbext/outputcallback.cpp b/src/libs/qtcreatorcdbext/outputcallback.cpp
index 5b01ffa46c64aa078e14fee88321e6ce9655aa8d..2e6e273dec6e37f0ce54128110d518fd4c2adfe5 100644
--- a/src/libs/qtcreatorcdbext/outputcallback.cpp
+++ b/src/libs/qtcreatorcdbext/outputcallback.cpp
@@ -97,6 +97,6 @@ STDMETHODIMP OutputCallback::Output(
     // Base encode as GDBMI is not really made for wide chars
     std::ostringstream str;
     base64Encode(str, reinterpret_cast<const unsigned char *>(text), sizeof(wchar_t) * std::wcslen(text));
-    ExtensionContext::instance().report('E', 0, 0, "debuggee_output", str.str().c_str());
+    ExtensionContext::instance().reportLong('E', 0, "debuggee_output", str.str().c_str());
     return S_OK;
 }
diff --git a/src/libs/qtcreatorcdbext/outputcallback.h b/src/libs/qtcreatorcdbext/outputcallback.h
index acab292564b35c4463839933bbd1580ad23dfd95..cad4a663eecc534bcdeec98ac4e306960db14c63 100644
--- a/src/libs/qtcreatorcdbext/outputcallback.h
+++ b/src/libs/qtcreatorcdbext/outputcallback.h
@@ -36,6 +36,8 @@
 
 #include "common.h"
 
+/* OutputCallback catches DEBUG_OUTPUT_DEBUGGEE and reports it
+ * base64-encoded back to Qt Creator. */
 class OutputCallback : public IDebugOutputCallbacksWide
 {
 public:
diff --git a/src/libs/qtcreatorcdbext/qtcreatorcdbextension.cpp b/src/libs/qtcreatorcdbext/qtcreatorcdbextension.cpp
index dab97cb1aa7597937a012818c50d2d42200f1f2c..79ecf83b8a1e3dedd95716b7641c97f97ef8d4ea 100644
--- a/src/libs/qtcreatorcdbext/qtcreatorcdbextension.cpp
+++ b/src/libs/qtcreatorcdbext/qtcreatorcdbextension.cpp
@@ -44,7 +44,8 @@
 #include <list>
 #include <iterator>
 
-/* QtCreatorCDB ext is an extension loaded into CDB.exe (see cdbengine2.cpp):
+/* QtCreatorCDB ext is an extension loaded into CDB.exe (see cdbengine.cpp)
+ * providing:
  * - Notification about the state of the debugging session:
  *   + idle: (hooked with .idle_cmd) debuggee stopped
  *   + accessible: Debuggee stopped, cdb.exe accepts commands
diff --git a/src/libs/qtcreatorcdbext/stringutils.h b/src/libs/qtcreatorcdbext/stringutils.h
index 4bad5b5f427a07130980e5002d0b3bbc415d8775..fc3e4bc815a5990031ac27c3a43c5cd9b4eb17ec 100644
--- a/src/libs/qtcreatorcdbext/stringutils.h
+++ b/src/libs/qtcreatorcdbext/stringutils.h
@@ -39,11 +39,12 @@
 #include <map>
 #include <functional>
 
-void trimFront(std::string &s);
-void trimBack(std::string &s);
+void trimFront(std::string &s); // Strip blanks off front
+void trimBack(std::string &s);  // Strip blanks off back
+// Simplify blanks, that is " A \tB " -> "A B".
 void simplify(std::string &s);
 
-// Split by character separator.
+// Split a token sequence in a string by character separator.
 template <class Iterator>
 void split(const std::string &s, char sep, Iterator it)
 {
diff --git a/src/libs/qtcreatorcdbext/symbolgroupnode.h b/src/libs/qtcreatorcdbext/symbolgroupnode.h
index 014ca96252e2c3c4fc2c5f03ce3056b1899c08af..e8ece3a50f77dbd07c30ea83e53a93c188bf56cd 100644
--- a/src/libs/qtcreatorcdbext/symbolgroupnode.h
+++ b/src/libs/qtcreatorcdbext/symbolgroupnode.h
@@ -50,7 +50,9 @@ class SymbolGroup;
 struct SymbolGroupValueContext;
 class SymbolGroupNode;
 
-// All parameters for GDBMI dumping in one struct.
+// All parameters for GDBMI dumping of a symbol group in one struct.
+// The debugging engine passes maps of type names/inames to special
+// integer values indicating hex/dec, etc.
 struct DumpParameters
 {
     typedef std::map<std::string, int> FormatMap; // type or iname to format
@@ -75,7 +77,7 @@ struct DumpParameters
     FormatMap individualFormats;
 };
 
-// Base class for a node of SymbolGroup, handling the list of children.
+// Abstract base class for a node of SymbolGroup providing the child list interface.
 class AbstractSymbolGroupNode
 {
     AbstractSymbolGroupNode(const AbstractSymbolGroupNode&);
@@ -93,7 +95,7 @@ public:
     // 'iname' used as an internal id.
     const std::string &iName() const { return m_iname; }
     // Full iname 'local.x.foo': WARNING: this returns the absolute path not
-    // taking reference nodes into account.
+    // taking reference nodes into account by recursing up the parents.
     std::string absoluteFullIName() const;
 
     virtual const AbstractSymbolGroupNodePtrVector &children() const = 0;
@@ -169,11 +171,11 @@ private:
  * consisting of:
  * - 'Simple' dumping done when running the DumpVisitor. This produces one
  *   line of formatted output shown for the class. These values
- *   values should are displayed, while still allowing for expansion of the structure
+ *   values are always displayed, while still allowing for expansion of the structure
  *   in the debugger.
  *   It also pre-determines some information for complex dumping (type, container).
  * - 'Complex' dumping: Obscures the symbol group children by fake children, for
- *   example container children, run when calling SymbolGroup::dump with an iname.
+ *   example container children, to be run when calling SymbolGroup::dump with an iname.
  *   The fake children are appended to the child list (other children are just marked as
  *   obscured for GDBMI dumping so that SymbolGroupValue expressions still work as before).
  * The dumping is mostly based on SymbolGroupValue expressions.
@@ -270,9 +272,9 @@ private:
 };
 
 // Artificial node referencing another (real) SymbolGroupNode (added symbol or
-// symbol from within a linked list structure. Forwards dumping to referenced node
-// using its own name.
-class ReferenceSymbolGroupNode  : public AbstractSymbolGroupNode
+// symbol from within an expanded linked list structure). Forwards the
+// dumping to the referenced node using its own name.
+class ReferenceSymbolGroupNode : public AbstractSymbolGroupNode
 {
 public:
     explicit ReferenceSymbolGroupNode(const std::string &name,
@@ -296,7 +298,8 @@ private:
     SymbolGroupNode * const m_referencedNode;
 };
 
-// Base class for a [fake] map node with a fake array index and key/value entries.
+// A [fake] map node with a fake array index and key/value entries consisting
+// of ReferenceSymbolGroupNode.
 class MapNodeSymbolGroupNode : public BaseSymbolGroupNode
 {
 private:
@@ -329,7 +332,7 @@ private:
  * or by expanding the whole structure).
  * visit() is not called for the (invisible) root node, but starting with the
  * root's children with depth=0.
- * Return true from visit() to terminate the recursion. */
+ * Return VisitStop from visit() to terminate the recursion. */
 
 class SymbolGroupNodeVisitor {
     SymbolGroupNodeVisitor(const SymbolGroupNodeVisitor&);
@@ -392,7 +395,8 @@ private:
     const std::string m_filter;
 };
 
-// GDBMI dump output visitor.
+// GDBMI dump output visitor used to report locals values back to the
+// debugging engine.
 class DumpSymbolGroupNodeVisitor : public SymbolGroupNodeVisitor {
 public:
     explicit DumpSymbolGroupNodeVisitor(std::ostream &os,
diff --git a/src/libs/qtcreatorcdbext/symbolgroupvalue.h b/src/libs/qtcreatorcdbext/symbolgroupvalue.h
index 2c6d49866846b56ce0eaceff1e14a343f5fd61c5..49672b7b5a79b02338ddd09fa84e251dd29d0579 100644
--- a/src/libs/qtcreatorcdbext/symbolgroupvalue.h
+++ b/src/libs/qtcreatorcdbext/symbolgroupvalue.h
@@ -45,7 +45,7 @@ class AbstractSymbolGroupNode;
 class SymbolGroupNode;
 class SymbolGroup;
 
-// Structure to pass all IDebug interfaces used for SymbolGroupValue
+// Structure to pass all IDebug interfaces required for SymbolGroupValue
 struct SymbolGroupValueContext
 {
     SymbolGroupValueContext(CIDebugDataSpaces *ds, CIDebugSymbols *s) : dataspaces(ds), symbols(s) {}
@@ -56,8 +56,14 @@ struct SymbolGroupValueContext
 };
 
 /* SymbolGroupValue: Flyweight tied to a SymbolGroupNode
- * providing a convenient operator[] + value getters for notation of dumpers.
- * Inaccesible members return a SymbolGroupValue in state 'invalid'. */
+ * providing a convenient operator[] (name, index) and value
+ * getters for notation of dumpers.
+ * Inaccessible members return a SymbolGroupValue in state 'invalid'.
+ * Example:
+ *   SymbolGroupValue container(symbolGroupNode, symbolGroupValueContext);
+ *   if (SymbolGroupValue sizeV = container["d"]["size"])
+ *     int size = sizeV.intValue()
+ * etc. */
 
 class SymbolGroupValue
 {
@@ -141,7 +147,8 @@ private:
 // For debugging purposes
 std::ostream &operator<<(std::ostream &, const SymbolGroupValue &v);
 
-// Qt Information: Namespace and module.
+// Qt Information determined on demand: Namespace, modules and basic class
+// names containing the module for fast lookup.
 struct QtInfo
 {
     static const QtInfo &get(const SymbolGroupValueContext &ctx);
@@ -196,6 +203,7 @@ unsigned dumpSimpleType(SymbolGroupNode  *n, const SymbolGroupValueContext &ctx,
                         int *containerSizeIn = 0,
                         void **specialInfoIn = 0);
 
+// Non-container complex dumpers (QObjects/QVariants).
 std::vector<AbstractSymbolGroupNode *>
     dumpComplexType(SymbolGroupNode *node, int type, void *specialInfo,
                     const SymbolGroupValueContext &ctx);
diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp
index 60c5da7ed18a9c65929dfb5c83237a8d0c564ec0..713e1acc921c39bf79f92571306f2b68c9758aa7 100644
--- a/src/plugins/debugger/cdb/cdbengine.cpp
+++ b/src/plugins/debugger/cdb/cdbengine.cpp
@@ -95,29 +95,30 @@ enum { debugBreakpoints = 0 };
 
 /* CdbEngine version 2: Run the CDB process on pipes and parse its output.
  * The engine relies on a CDB extension Qt Creator provides as an extension
- * library (32/64bit). It serves to:
+ * library (32/64bit), which is loaded into cdb.exe. It serves to:
  * - Notify the engine about the state of the debugging session:
- *   + idle: (hooked with .idle_cmd) debuggee stopped
+ *   + idle: (hooked up with .idle_cmd) debuggee stopped
  *   + accessible: Debuggee stopped, cdb.exe accepts commands
  *   + inaccessible: Debuggee runs, no way to post commands
  *   + session active/inactive: Lost debuggee, terminating.
- * - Hook up with output/event callbacks and produce formatted output
+ * - Hook up with output/event callbacks and produce formatted output to be able
+ *   to catch application output and exceptions.
  * - Provide some extension commands that produce output in a standardized (GDBMI)
  *   format that ends up in handleExtensionMessage().
  *   + pid     Return debuggee pid for interrupting.
  *   + locals  Print locals from SymbolGroup
  *   + expandLocals Expand locals in symbol group
  *   + registers, modules, threads
- * Commands can be posted:
- * postCommand: Does not expect a reply
- * postBuiltinCommand: Run a builtin-command producing free-format, multiline output
- * that is captured by enclosing it in special tokens using the 'echo' command and
- * then invokes a callback with a CdbBuiltinCommand structure.
- * postExtensionCommand: Run a command provided by the extension producing
- * one-line output and invoke a callback with a CdbExtensionCommand structure. */
+ * Commands can be posted by calling:
+ * 1) postCommand(): Does not expect a reply
+ * 2) postBuiltinCommand(): Run a builtin-command producing free-format, multiline output
+ *    that is captured by enclosing it in special tokens using the 'echo' command and
+ *    then invokes a callback with a CdbBuiltinCommand structure.
+ * 3) postExtensionCommand(): Run a command provided by the extension producing
+ *    one-line output and invoke a callback with a CdbExtensionCommand structure
+ *    (output is potentially split up in chunks). */
 
 using namespace ProjectExplorer;
-using namespace Debugger::Internal;
 
 namespace Debugger {
 namespace Internal {
@@ -899,7 +900,9 @@ void CdbEngine::assignValueInDebugger(const WatchData *w, const QString &expr, c
     ByteArrayInputStream str(cmd);
     str << m_extensionCommandPrefixBA << "assign " << w->iname << '=' << value.toString();
     postCommand(cmd, 0);
-    updateLocalVariable(w->iname);
+    // Update all locals in case we change a union or something pointed to
+    // that affects other variables, too.
+    updateLocals();
 }
 
 void CdbEngine::handleThreads(const CdbExtensionCommandPtr &reply)
@@ -1034,9 +1037,26 @@ void CdbEngine::activateFrame(int index)
         } else {
             assemblerAction->trigger(); // Seems to trigger update
         }
+    } else {
+        gotoLocation(frame);
+        updateLocals();
+    }
+}
+
+void CdbEngine::updateLocals()
+{
+    const int frameIndex = stackHandler()->currentIndex();
+    if (frameIndex < 0) {
+        watchHandler()->beginCycle();
+        watchHandler()->endCycle();
+        return;
+    }
+    const StackFrame frame = stackHandler()->currentFrame();
+    if (!frame.isUsable()) {
+        watchHandler()->beginCycle();
+        watchHandler()->endCycle();
         return;
     }
-    gotoLocation(frame);
     // Watchers: Initial expand, get uninitialized and query
     QByteArray arguments;
     ByteArrayInputStream str(arguments);
@@ -1068,7 +1088,7 @@ void CdbEngine::activateFrame(int index)
         }
     }
     // Required arguments: frame
-    str << blankSeparator << index;
+    str << blankSeparator << frameIndex;
     watchHandler()->beginCycle();
     postExtensionCommand("locals", arguments, 0, &CdbEngine::handleLocals);
 }
diff --git a/src/plugins/debugger/cdb/cdbengine.h b/src/plugins/debugger/cdb/cdbengine.h
index 6edce64f14533ba01a8bc0d431b35b9001526f50..c11e9c955fc46fa20eb3bdcd7c49b3406faf55a6 100644
--- a/src/plugins/debugger/cdb/cdbengine.h
+++ b/src/plugins/debugger/cdb/cdbengine.h
@@ -179,6 +179,7 @@ private:
 
     QString normalizeFileName(const QString &f);
     void updateLocalVariable(const QByteArray &iname);
+    void updateLocals();
     int elapsedLogTime() const;
     void addLocalsOptions(ByteArrayInputStream &s) const;