diff --git a/src/plugins/debugger/cdb/cdbstackframecontext.cpp b/src/plugins/debugger/cdb/cdbstackframecontext.cpp
index 258f81d994954846ee5ccc7e115edf0b101c0ad7..0a4cbc1280b62f534cd8f08383c9cc6dfb22878c 100644
--- a/src/plugins/debugger/cdb/cdbstackframecontext.cpp
+++ b/src/plugins/debugger/cdb/cdbstackframecontext.cpp
@@ -36,8 +36,6 @@
 
 #include <QtCore/QDebug>
 
-enum { debug = 0 };
-
 namespace Debugger {
 namespace Internal {
 
@@ -46,7 +44,31 @@ enum { OwnerNewItem, OwnerSymbolGroup, OwnerDumper };
 typedef QSharedPointer<CdbDumperHelper> SharedPointerCdbDumperHelper;
 typedef QList<WatchData> WatchDataList;
 
-// Put a sequence of  WatchData into the model
+// Predicates for parametrizing the symbol group
+inline bool truePredicate(const WatchData & /* whatever */) { return true; }
+inline bool falsePredicate(const WatchData & /* whatever */) { return false; }
+inline bool isDumperPredicate(const WatchData &wd)
+{ return wd.source == OwnerDumper; }
+
+// Match an item that is expanded in the watchhandler.
+class WatchHandlerExpandedPredicate {
+public:
+    explicit inline WatchHandlerExpandedPredicate(const WatchHandler *wh) : m_wh(wh) {}
+    inline bool operator()(const WatchData &wd) { return m_wh->isExpandedIName(wd.iname); }
+private:
+    const WatchHandler *m_wh;
+};
+
+// Match an item by iname
+class MatchINamePredicate {
+public:
+    explicit inline MatchINamePredicate(const QString &iname) : m_iname(iname) {}
+    inline bool operator()(const WatchData &wd) { return wd.iname == m_iname; }
+private:
+    const QString &m_iname;
+};
+
+// Put a sequence of  WatchData into the model for the non-dumper case
 class WatchHandlerModelInserter {
 public:
     explicit WatchHandlerModelInserter(WatchHandler *wh) : m_wh(wh) {}
@@ -62,49 +84,106 @@ private:
     WatchHandler *m_wh;
 };
 
-// Helper to sort apart a sequence of  WatchData using the Dumpers.
+// Put a sequence of  WatchData into the model for the dumper case.
+// Sorts apart a sequence of  WatchData using the Dumpers.
 // Puts the stuff for which there is no dumper in the model
 // as is and sets ownership to symbol group. The rest goes
-// to the dumpers.
-class WatchHandlerSorterInserter {
+// to the dumpers. Additionally, checks for items pointing to a
+// dumpeable type and inserts a fake dereferenced item and value.
+class WatchHandleDumperInserter {
 public:
-    explicit WatchHandlerSorterInserter(WatchHandler *wh,
+    explicit WatchHandleDumperInserter(WatchHandler *wh,
                                         const SharedPointerCdbDumperHelper &dumper);
 
-    inline WatchHandlerSorterInserter & operator*() { return *this; }
-    inline WatchHandlerSorterInserter &operator=(WatchData wd);
-    inline WatchHandlerSorterInserter &operator++() { return *this; }
+    inline WatchHandleDumperInserter & operator*() { return *this; }
+    inline WatchHandleDumperInserter &operator=(WatchData &wd);
+    inline WatchHandleDumperInserter &operator++() { return *this; }
 
 private:
+    bool expandPointerToDumpable(const WatchData &wd, QString *errorMessage);
+
+    const QRegExp m_hexNullPattern;
     WatchHandler *m_wh;
     const SharedPointerCdbDumperHelper m_dumper;
     QList<WatchData> m_dumperResult;
-    QStringList m_dumperINames;
 };
 
-WatchHandlerSorterInserter::WatchHandlerSorterInserter(WatchHandler *wh,
+WatchHandleDumperInserter::WatchHandleDumperInserter(WatchHandler *wh,
                                                        const SharedPointerCdbDumperHelper &dumper) :
+    m_hexNullPattern(QLatin1String("0x0+")),
     m_wh(wh),
-    m_dumper(dumper)
+    m_dumper(dumper)    
 {
+    Q_ASSERT(m_hexNullPattern.isValid());
 }
 
-WatchHandlerSorterInserter &WatchHandlerSorterInserter::operator=(WatchData wd)
+// Is this a non-null pointer to a dumpeable item with a value
+// "0x4343 class QString *" ? - Insert a fake '*' dereferenced item
+// and run dumpers on it. If that succeeds, insert the fake items owned by dumpers,
+// which will trigger the ignore predicate.
+// Note that the symbol context does not create '*' dereferenced items for
+// classes (see note in its header documentation).
+bool WatchHandleDumperInserter::expandPointerToDumpable(const WatchData &wd, QString *errorMessage)
 {
-    // Is this a child belonging to some item handled by dumpers,
-    // such as d-elements of QStrings -> just ignore it.
-    if (const int dumperINamesCount = m_dumperINames.size()) {
-        for (int i = 0; i < dumperINamesCount; i++)
-            if (wd.iname.startsWith(m_dumperINames.at(i)))
-                return *this;
-    }
+    if (debugCDBWatchHandling)
+        qDebug() << ">expandPointerToDumpable" << wd.iname;
+
+    bool handled = false;
+    do {
+        if (!isPointerType(wd.type))
+            break;
+        const int classPos = wd.value.indexOf(" class ");
+        if (classPos == -1)
+            break;
+        const QString hexAddrS = wd.value.mid(0, classPos);
+        if (m_hexNullPattern.exactMatch(hexAddrS))
+            break;
+        const QString type = stripPointerType(wd.value.mid(classPos + 7));
+        WatchData derefedWd;
+        derefedWd.setType(type);
+        derefedWd.setAddress(hexAddrS);
+        derefedWd.name = QString(QLatin1Char('*'));
+        derefedWd.iname = wd.iname + QLatin1String(".*");
+        derefedWd.source = OwnerDumper;
+        const CdbDumperHelper::DumpResult dr = m_dumper->dumpType(derefedWd, true, OwnerDumper, &m_dumperResult, errorMessage);
+        if (dr != CdbDumperHelper::DumpOk)
+            break;
+        // Insert the pointer item with 1 additional child + its dumper results
+        // Note: formal arguments might already be expanded in the symbol group.
+        WatchData ptrWd = wd;
+        ptrWd.source = OwnerDumper;
+        ptrWd.setHasChildren(true);
+        ptrWd.setChildrenUnneeded();
+        m_wh->insertData(ptrWd);
+        foreach(const WatchData &dwd, m_dumperResult)
+            m_wh->insertData(dwd);
+        handled = true;
+    } while (false);
+    if (debugCDBWatchHandling)
+        qDebug() << "<expandPointerToDumpable returns " << handled << *errorMessage;
+    return handled;
+}
+
+WatchHandleDumperInserter &WatchHandleDumperInserter::operator=(WatchData &wd)
+{
+    if (debugCDBWatchHandling)
+        qDebug() << "WatchHandleDumperInserter::operator=" << wd.toString();
+    // Check pointer to dumpeable, dumpeable, insert accordingly.
     QString errorMessage;
+    if (expandPointerToDumpable(wd, &errorMessage)) {
+        // Nasty side effect: Modify owner for the ignore predicate
+        wd.source = OwnerDumper;
+        return *this;
+    }
     switch (m_dumper->dumpType(wd, true, OwnerDumper, &m_dumperResult, &errorMessage)) {
     case CdbDumperHelper::DumpOk:
+        if (debugCDBWatchHandling)
+            qDebug() << "dumper triggered";
         // Discard the original item and insert the dumper results
-        m_dumperINames.push_back(wd.iname + QLatin1Char('.'));
         foreach(const WatchData &dwd, m_dumperResult)
             m_wh->insertData(dwd);
+        // Nasty side effect: Modify owner for the ignore predicate
+        wd.source = OwnerDumper;
         break;
     case CdbDumperHelper::DumpNotHandled:
     case CdbDumperHelper::DumpError:
@@ -133,15 +212,19 @@ bool CdbStackFrameContext::assignValue(const QString &iname, const QString &valu
 bool CdbStackFrameContext::populateModelInitially(WatchHandler *wh, QString *errorMessage)
 {
     if (debugCDBWatchHandling)
-        qDebug() << "populateModelInitially";
+        qDebug() << "populateModelInitially dumpers=" << m_useDumpers;
+    // Recurse down items that are initially expanded in the view, stop processing for
+    // dumper items.
     const bool rc = m_useDumpers ?
         CdbSymbolGroupContext::populateModelInitially(m_symbolContext,
-                                                      wh->expandedINames(),
-                                                      WatchHandlerSorterInserter(wh, m_dumper),                                                      
+                                                      WatchHandleDumperInserter(wh, m_dumper),
+                                                      WatchHandlerExpandedPredicate(wh),
+                                                      isDumperPredicate,
                                                       errorMessage) :
         CdbSymbolGroupContext::populateModelInitially(m_symbolContext,
-                                                      wh->expandedINames(),
                                                       WatchHandlerModelInserter(wh),
+                                                      WatchHandlerExpandedPredicate(wh),
+                                                      falsePredicate,
                                                       errorMessage);
     return rc;
 }
@@ -151,25 +234,32 @@ bool CdbStackFrameContext::completeData(const WatchData &incompleteLocal,
                                         QString *errorMessage)
 {
     if (debugCDBWatchHandling)
-        qDebug() << ">completeData " << incompleteLocal.iname << " src=" << incompleteLocal.source;
+        qDebug() << ">completeData src=" << incompleteLocal.source << incompleteLocal.toString();
 
+    // Expand symbol group items, recurse one level from desired item
     if (!m_useDumpers) {
         return CdbSymbolGroupContext::completeData(m_symbolContext, incompleteLocal,
                                                    WatchHandlerModelInserter(wh),
+                                                   MatchINamePredicate(incompleteLocal.iname),
+                                                   falsePredicate,
                                                    errorMessage);
     }
 
     // Expand dumper items (not implemented)
     if (incompleteLocal.source == OwnerDumper) {
+        if (debugCDBWatchHandling)
+            qDebug() << "ignored dumper item";
         WatchData wd = incompleteLocal;
         wd.setAllUnneeded();
         wh->insertData(wd);
         return true;
     }
 
-    // Expand symbol group items
+    // Expand symbol group items, recurse one level from desired item
     return CdbSymbolGroupContext::completeData(m_symbolContext, incompleteLocal,
-                                               WatchHandlerSorterInserter(wh, m_dumper),
+                                               WatchHandleDumperInserter(wh, m_dumper),
+                                               MatchINamePredicate(incompleteLocal.iname),
+                                               isDumperPredicate,
                                                errorMessage);
 }
 
diff --git a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp
index 14fb16c736a1a80bb8205b80c50347095a14a5b9..12d78c0fc1c2bda8f004379244618371d580b543 100644
--- a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp
+++ b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.cpp
@@ -33,6 +33,7 @@
 #include "watchutils.h"
 
 #include <QtCore/QTextStream>
+#include <QtCore/QRegExp>
 
 enum { debug = 0 };
 
@@ -353,6 +354,20 @@ static inline QString hexSymbolOffset(CIDebugSymbolGroup *sg, unsigned long inde
     return QLatin1String("0x") + QString::number(rc, 16);
 }
 
+// check for "0x000", "0x000 class X"
+static inline bool isNullPointer(const WatchData &wd)
+{
+    if (!isPointerType(wd.type))
+        return false;
+    static const QRegExp hexNullPattern(QLatin1String("0x0+"));
+    Q_ASSERT(hexNullPattern.isValid());
+    const int blankPos = wd.value.indexOf(QLatin1Char(' '));
+    if (blankPos == -1)
+        return hexNullPattern.exactMatch(wd.value);
+    const QString addr = wd.value.mid(0, blankPos);
+    return hexNullPattern.exactMatch(addr);
+}
+
 WatchData CdbSymbolGroupContext::symbolAt(unsigned long index) const
 {
     WatchData wd;
@@ -367,8 +382,10 @@ WatchData CdbSymbolGroupContext::symbolAt(unsigned long index) const
     // Figure out children. The SubElement is only a guess unless the symbol,
     // is expanded, so, we leave this as a guess for later updates.
     // If the symbol has children (expanded or not), we leave the 'Children' flag
-    // in 'needed' state.
-    wd.setHasChildren(m_symbolParameters.at(index).SubElements);
+    // in 'needed' state. Suppress 0-pointers right ("0x000 class X")
+    // here as they only lead to children with memory access errors.
+    const bool hasChildren = m_symbolParameters.at(index).SubElements && !isNullPointer(wd);
+    wd.setHasChildren(hasChildren);
     if (debug > 1)
         qDebug() << Q_FUNC_INFO << index << '\n' << wd.toString();
     return wd;
diff --git a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.h b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.h
index 2c5b6b3e3657528732c22c59693c7437a6f8c448..91ec5fd92400f599b2251d350fa539a2ab8b8dae 100644
--- a/src/plugins/debugger/cdb/cdbsymbolgroupcontext.h
+++ b/src/plugins/debugger/cdb/cdbsymbolgroupcontext.h
@@ -55,7 +55,14 @@ class WatchHandler;
  * "local.string.data" (class member)
  * and maintains a mapping iname -> index.
  * IDebugSymbolGroup2 can "expand" expandable symbols, inserting them into the
- * flat list after their parent. */
+ * flat list after their parent.
+ *
+ * Note the pecularity of IDebugSymbolGroup2 with regard to pointed to items:
+ * 1) A pointer to a POD (say int *) will expand to a pointed-to integer named '*'.
+ * 2) A pointer to a class (QString *), will expand to the class members right away,
+ *    omitting the '*' derefenced item. That is a problem since the dumpers trigger
+ *    only on the derefenced item, so, additional handling is required.
+ */
 
 class CdbSymbolGroupContext
 {
@@ -74,15 +81,29 @@ public:
     bool assignValue(const QString &iname, const QString &value,
                      QString *newValue /* = 0 */, QString *errorMessage);
 
-    template <class OutputIterator>
+    // Initially populate the locals model for a new stackframe.
+    // Write a sequence of WatchData to it, recurse down if the
+    // recursionPredicate agrees. The ignorePredicate can be used
+    // to terminate processing after insertion of an item (if the calling
+    // routine wants to insert another subtree).
+    template <class OutputIterator, class RecursionPredicate, class IgnorePredicate>
     static bool populateModelInitially(CdbSymbolGroupContext *sg,
-                                       QSet<QString> expandedINames,
-                                       OutputIterator it, QString *errorMessage);
-
-    template <class OutputIterator>
+                                       OutputIterator it,
+                                       RecursionPredicate recursionPredicate,
+                                       IgnorePredicate ignorePredicate,
+                                       QString *errorMessage);
+
+    // Complete children of a WatchData item.
+    // Write a sequence of WatchData to it, recurse if the
+    // recursionPredicate agrees. The ignorePredicate can be used
+    // to terminate processing after insertion of an item (if the calling
+    // routine wants to insert another subtree).
+    template <class OutputIterator, class RecursionPredicate, class IgnorePredicate>
     static bool completeData (CdbSymbolGroupContext *sg,
                               WatchData incompleteLocal,
                               OutputIterator it,
+                              RecursionPredicate recursionPredicate,
+                              IgnorePredicate ignorePredicate,
                               QString *errorMessage);
 
     // Retrieve child symbols of prefix as a sequence of WatchData.
diff --git a/src/plugins/debugger/cdb/cdbsymbolgroupcontext_tpl.h b/src/plugins/debugger/cdb/cdbsymbolgroupcontext_tpl.h
index 73e84001f843d3dbf03bccf1ac2899cb44722b1a..ccaba97ee893f600c8afbe0e8d29717fa338a7fb 100644
--- a/src/plugins/debugger/cdb/cdbsymbolgroupcontext_tpl.h
+++ b/src/plugins/debugger/cdb/cdbsymbolgroupcontext_tpl.h
@@ -66,97 +66,72 @@ bool CdbSymbolGroupContext::getChildSymbols(const QString &prefix, OutputIterato
     return true;
 }
 
-template <class OutputIterator>
-        bool insertChildrenRecursion(const QString &iname,
-                                     CdbSymbolGroupContext *sg,
-                                     OutputIterator it,
-                                     int maxRecursionLevel,
-                                     int level,
-                                     QString *errorMessage,
-                                     int *childCount = 0);
-
 // Insert a symbol (and its first level children depending on forceRecursion)
-template <class OutputIterator>
+// The parent symbol is inserted before the children to make dumper handling
+// simpler. In theory, it can happen that the symbol context indicates
+// children but can expand none, which would lead to invalid parent information
+// (expand icon), though (ignore for simplicity).
+template <class OutputIterator, class RecursionPredicate, class IgnorePredicate>
 bool insertSymbolRecursion(WatchData wd,
-                                  CdbSymbolGroupContext *sg,
-                                  OutputIterator it,
-                                  int maxRecursionLevel,
-                                  int level,
-                                  QString *errorMessage)
+                           CdbSymbolGroupContext *sg,
+                           OutputIterator it,
+                           RecursionPredicate recursionPredicate,
+                           IgnorePredicate ignorePredicate,
+                           QString *errorMessage)
 {
-    // Find out whether to recurse (has children or at least knows it has children)
-    // Open next level if specified by recursion depth or child is already expanded
-    // (Sometimes, some root children are already expanded after creating the context).
+    // Find out whether to recurse (has children and predicate agrees)
     const bool hasChildren = wd.hasChildren || wd.isChildrenNeeded();
-    const bool recurse = hasChildren && (level < maxRecursionLevel || sg->isExpanded(wd.iname));
+    const bool recurse = hasChildren && recursionPredicate(wd);
     if (debugSgRecursion)
-        qDebug() << "insertSymbolRecursion" << '\n' << wd.iname << "level=" << level <<  "recurse=" << recurse;
-    bool rc = true;
-    if (recurse) { // Determine number of children and indicate in model
-        int childCount;
-        rc = insertChildrenRecursion(wd.iname, sg, it, maxRecursionLevel, level, errorMessage, &childCount);
-        if (rc) {
-            wd.setHasChildren(childCount > 0);
-            wd.setChildrenUnneeded();
-        }
-    } else {
+        qDebug() << "insertSymbolRecursion" << '\n' << wd.iname << "recurse=" << recurse;
+    if (!recurse) {
         // No further recursion at this level, pretend entry is complete
-        // to the watchmodel
+        // to the watchmodel for the parent to show (only remaining watchhandler-specific
+        // part here).
         if (wd.isChildrenNeeded()) {
             wd.setHasChildren(true);
             wd.setChildrenUnneeded();
         }
+        if (debugSgRecursion)
+            qDebug() << " INSERTING non-recursive: " << wd.toString();
+        *it = wd;
+        ++it;
+        return true;
     }
+    // Recursion: Indicate children unneeded
+    wd.setHasChildren(true);
+    wd.setChildrenUnneeded();
     if (debugSgRecursion)
-        qDebug() << " INSERTING: at " << level << wd.toString();
+        qDebug() << " INSERTING recursive: " << wd.toString();
     *it = wd;
     ++it;
-    return rc;
-}
-
-// Insert the children of prefix.
-template <class OutputIterator>
-        bool insertChildrenRecursion(const QString &iname,
-                                     CdbSymbolGroupContext *sg,
-                                     OutputIterator it,
-                                     int maxRecursionLevel,
-                                     int level,
-                                     QString *errorMessage,
-                                     int *childCountPtr)
-{
-    if (debugSgRecursion > 1)
-        qDebug() << "insertChildrenRecursion" << '\n' << iname << level;
-
+    // Recurse unless the predicate disagrees
+    if (ignorePredicate(wd))
+        return true;
     QList<WatchData> watchList;
     // This implicitly enforces expansion
-    if (!sg->getChildSymbols(iname, WatchDataBackInserter(watchList), errorMessage))
+    if (!sg->getChildSymbols(wd.iname, WatchDataBackInserter(watchList), errorMessage))
         return false;
-
     const int childCount = watchList.size();
-    if (childCountPtr)
-        *childCountPtr = childCount;
-    int succeededChildCount = 0;
     for (int c = 0; c < childCount; c++) {
-        const WatchData &wd = watchList.at(c);
+        const WatchData &cwd = watchList.at(c);
         if (wd.isValid()) { // We sometimes get empty names for deeply nested data
-            if (!insertSymbolRecursion(wd, sg, it, maxRecursionLevel, level + 1, errorMessage))
+            if (!insertSymbolRecursion(cwd, sg, it, recursionPredicate, ignorePredicate, errorMessage))
                 return false;
-            succeededChildCount++;
         }  else {
             const QString msg = QString::fromLatin1("WARNING: Skipping invalid child symbol #%2 (type %3) of '%4'.").
-                                arg(QLatin1String(Q_FUNC_INFO)).arg(c).arg(wd.type, iname);
+                                arg(QLatin1String(Q_FUNC_INFO)).arg(c).arg(cwd.type, wd.iname);
             qWarning("%s\n", qPrintable(msg));
         }
     }
-    if (childCountPtr)
-        *childCountPtr = succeededChildCount;
     return true;
 }
 
-template <class OutputIterator>
+template <class OutputIterator, class RecursionPredicate, class IgnorePredicate>
 bool CdbSymbolGroupContext::populateModelInitially(CdbSymbolGroupContext *sg,
-                                                   QSet<QString> expandedINames,
                                                    OutputIterator it,
+                                                   RecursionPredicate recursionPredicate,
+                                                   IgnorePredicate ignorePredicate,
                                                    QString *errorMessage)
 {
     if (debugSgRecursion)
@@ -166,53 +141,27 @@ bool CdbSymbolGroupContext::populateModelInitially(CdbSymbolGroupContext *sg,
     QList<WatchData> watchList;
     if (!sg->getChildSymbols(sg->prefix(), WatchDataBackInserter(watchList), errorMessage))
         return false;
-    // (Recursively) expand symbols stored as expanded in the history until no more matches
-    // are found.
-    while (!expandedINames.empty()) {
-        unsigned matchCount = 0;
-        for (QSet<QString>::iterator it = expandedINames.begin(); it != expandedINames.end(); ) {
-            // Try to expand. We might hit on a leaf due to name mismatches, ignore errors.
-            unsigned long index;
-            if (sg->lookupPrefix(*it, &index)) {
-                if (!sg->expandSymbol(*it, index, errorMessage))
-                    qWarning("%s\n", qPrintable(*errorMessage));
-                matchCount++;
-                it = expandedINames.erase(it);
-            } else {
-                ++it;
-            }
-        } // loop set
-        if (matchCount == 0)
-            break;
-    }
     // Insert data
     foreach(const WatchData &wd, watchList)
-        if (!insertSymbolRecursion(wd, sg, it, 0, 0, errorMessage))
+        if (!insertSymbolRecursion(wd, sg, it, recursionPredicate, ignorePredicate, errorMessage))
             return false;
     return true;
 }
 
-template <class OutputIterator>
+template <class OutputIterator, class RecursionPredicate, class IgnorePredicate>
 bool CdbSymbolGroupContext::completeData(CdbSymbolGroupContext *sg,
                                          WatchData incompleteLocal,
                                          OutputIterator it,
+                                         RecursionPredicate recursionPredicate,
+                                         IgnorePredicate ignorePredicate,
                                          QString *errorMessage)
 {
     if (debugSgRecursion)
         qDebug().nospace() << "###>CdbSymbolGroupContext::completeData" << ' ' << incompleteLocal.iname << '\n';
-    const bool contextExpanded = sg->isExpanded(incompleteLocal.iname);
-    if (debugSgRecursion)
-        qDebug() << "  " << incompleteLocal.iname << "CE=" << contextExpanded;
-    // The view reinserts any node being expanded with flag 'ChildrenNeeded'.
-    // Recurse down one level in context unless this is already the case.
-    if (contextExpanded) {
-        incompleteLocal.setChildrenUnneeded();
-        *it = incompleteLocal;
-        ++it;
-    } else {
-        if (!insertSymbolRecursion(incompleteLocal, sg, it, 1, 0, errorMessage))
-            return false;
-    }
+    // If the symbols are already expanded in the context, they will be re-inserted,
+    // which is not handled for simplicity.
+    if (!insertSymbolRecursion(incompleteLocal, sg, it, recursionPredicate, ignorePredicate, errorMessage))
+        return false;
     return true;
 }
 
diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp
index b8f794b4a0904d65bde7a507aca8be49fa7a54cf..79e67dd868572d5e160fc6c58629019d1e648a1b 100644
--- a/src/plugins/debugger/watchhandler.cpp
+++ b/src/plugins/debugger/watchhandler.cpp
@@ -877,7 +877,7 @@ void WatchHandler::watchExpression(const QString &exp)
     WatchData data;
     data.exp = exp;
     data.name = exp;
-    if (exp == watcherEditPlaceHolder())
+    if (exp.isEmpty() || exp == watcherEditPlaceHolder())
         data.setAllUnneeded();
     data.iname = watcherName(exp);
     insertData(data);
@@ -1012,7 +1012,15 @@ void WatchHandler::loadWatchers()
 void WatchHandler::saveWatchers()
 {
     //qDebug() << "SAVE WATCHERS: " << m_watchers.keys();
-    setSessionValueRequested("Watchers", QVariant(m_watcherNames.keys()));
+    // Filter out valid watchers.
+    QStringList watcherNames;
+    const QHash<QString, int>::const_iterator cend = m_watcherNames.constEnd();
+    for (QHash<QString, int>::const_iterator it = m_watcherNames.constBegin(); it != cend; ++it) {
+        const QString &watcherName = it.key();
+        if (!watcherName.isEmpty() && watcherName != watcherEditPlaceHolder())
+            watcherNames.push_back(watcherName);
+    }
+    setSessionValueRequested("Watchers", QVariant(watcherNames));
 }
 
 void WatchHandler::saveSessionData()