diff --git a/src/plugins/debugger/cdb/cdbdebugengine.cpp b/src/plugins/debugger/cdb/cdbdebugengine.cpp
index 16548f9146e916b8040b78e47ec350c5e732f954..2c4db8eabc00f049d6ac60857787f7a6d6b2b613 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine.cpp
+++ b/src/plugins/debugger/cdb/cdbdebugengine.cpp
@@ -39,6 +39,7 @@
 #include "cdboptionspage.h"
 #include "cdboptions.h"
 #include "cdbexceptionutils.h"
+#include "cdbsymbolpathlisteditor.h"
 #include "debuggeragents.h"
 #include "debuggeruiswitcher.h"
 #include "debuggermainwindow.h"
@@ -59,6 +60,7 @@
 #include <utils/fancymainwindow.h>
 #include <texteditor/itexteditor.h>
 #include <utils/savedaction.h>
+#include <utils/checkablemessagebox.h>
 
 #include <QtCore/QDebug>
 #include <QtCore/QTimer>
@@ -347,11 +349,48 @@ void CdbDebugEnginePrivate::checkVersion()
     }
 }
 
+void CdbDebugEngine::startupChecks()
+{
+    // Check symbol server unless the user has an external/internal setup
+    if (!qgetenv("_NT_SYMBOL_PATH").isEmpty()
+        || CdbOptions::indexOfSymbolServerPath(m_d->m_options->symbolPaths) != -1)
+        return;
+    // Prompt to use Symbol server unless the user checked "No nagging".
+    Core::ICore *core = Core::ICore::instance();
+    const QString nagSymbolServerKey = CdbOptions::settingsGroup() + QLatin1String("/NoPromptSymbolServer");
+    bool noFurtherNagging = core->settings()->value(nagSymbolServerKey, false).toBool();
+    if (noFurtherNagging)
+        return;
+
+    const QString symServUrl = QLatin1String("http://support.microsoft.com/kb/311503");
+    const QString msg = tr("<html><head/><body><p>The debugger is not configured to use the public "
+                           "<a href=\"%1\">Microsoft Symbol Server</a>. This is recommended "
+                           "for retrieval of the symbols of the operating system libraries.</p>"
+                           "<p><i>Note:</i> A fast internet connection is required for this to work smoothly. Also, a delay "
+                           "might occur when connecting for the first time.</p>"
+                           "<p>Would you like to set it up?</p></br>"
+                           "</body></html>").arg(symServUrl);
+    const QDialogButtonBox::StandardButton answer =
+            Utils::CheckableMessageBox::question(core->mainWindow(), tr("Symbol Server"), msg,
+                                                 tr("Do not ask again"), &noFurtherNagging);
+    core->settings()->setValue(nagSymbolServerKey, noFurtherNagging);
+    if (answer == QDialogButtonBox::No)
+        return;
+    // Prompt for path and add it. Synchronize QSetting and debugger.
+    const QString cacheDir = CdbSymbolPathListEditor::promptCacheDirectory(core->mainWindow());
+    if (cacheDir.isEmpty())
+        return;
+    m_d->m_options->symbolPaths.push_back(CdbOptions::symbolServerPath(cacheDir));
+    m_d->m_options->toSettings(core->settings());
+    syncDebuggerPaths();
+}
+
 void CdbDebugEngine::startDebugger(const QSharedPointer<DebuggerStartParameters> &sp)
 {
     if (debugCDBExecution)
         qDebug() << "startDebugger" << *sp;
     CdbCore::BreakPoint::clearNormalizeFileNameCache();
+    startupChecks();
     setState(AdapterStarting, Q_FUNC_INFO, __LINE__);
     m_d->checkVersion();
     if (m_d->m_hDebuggeeProcess) {
diff --git a/src/plugins/debugger/cdb/cdbdebugengine.h b/src/plugins/debugger/cdb/cdbdebugengine.h
index 452f8df87ff000ed52260aa87319598f98fd9548..16d928a16c083116cd00c07d2ad376973e351bdf 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine.h
+++ b/src/plugins/debugger/cdb/cdbdebugengine.h
@@ -112,6 +112,7 @@ private slots:
     void warning(const QString &w);
 
 private:
+    void startupChecks();
     void setState(DebuggerState state, const char *func, int line);
     inline bool startAttachDebugger(qint64 pid, DebuggerStartMode sm, QString *errorMessage);
     void processTerminated(unsigned long exitCode);
diff --git a/src/plugins/debugger/cdb/cdboptions.cpp b/src/plugins/debugger/cdb/cdboptions.cpp
index fda335be03c7ab6f3e3f53cc1194d922f7d4e23f..0c3e00b383bb685253081ce4700ca38eb11b26d8 100644
--- a/src/plugins/debugger/cdb/cdboptions.cpp
+++ b/src/plugins/debugger/cdb/cdboptions.cpp
@@ -50,6 +50,11 @@ CdbOptions::CdbOptions() :
 {
 }
 
+QString CdbOptions::settingsGroup()
+{
+    return QLatin1String(settingsGroupC);
+}
+
 void CdbOptions::clear()
 {
     enabled = false;
@@ -99,5 +104,37 @@ unsigned CdbOptions::compare(const CdbOptions &rhs) const
     return rc;
 }
 
+static const char symbolServerPrefixC[] = "symsrv*symsrv.dll*";
+static const char symbolServerPostfixC[] = "*http://msdl.microsoft.com/download/symbols";
+
+QString CdbOptions::symbolServerPath(const QString &cacheDir)
+{
+    QString s = QLatin1String(symbolServerPrefixC);
+    s +=  QDir::toNativeSeparators(cacheDir);
+    s += QLatin1String(symbolServerPostfixC);
+    return s;
+}
+
+bool CdbOptions::isSymbolServerPath(const QString &path, QString *cacheDir /*  = 0 */)
+{
+    // Split apart symbol server post/prefixes
+    if (!path.startsWith(QLatin1String(symbolServerPrefixC)) || !path.endsWith(QLatin1String(symbolServerPostfixC)))
+        return false;
+    if (cacheDir) {
+        const unsigned prefixLength = qstrlen(symbolServerPrefixC);
+        *cacheDir = path.mid(prefixLength, path.size() - prefixLength - qstrlen(symbolServerPostfixC));
+    }
+    return true;
+}
+
+int CdbOptions::indexOfSymbolServerPath(const QStringList &paths, QString *cacheDir /*  = 0 */)
+{
+    const int count = paths.size();
+    for (int i = 0; i < count; i++)
+        if (CdbOptions::isSymbolServerPath(paths.at(i), cacheDir))
+            return i;
+    return -1;
+}
+
 } // namespace Internal
 } // namespace Debugger
diff --git a/src/plugins/debugger/cdb/cdboptions.h b/src/plugins/debugger/cdb/cdboptions.h
index cb7bd07ef2ce782aa6373116f1528c2602465aeb..97f08d108a218136a96a4e61993cabfbdfc72069 100644
--- a/src/plugins/debugger/cdb/cdboptions.h
+++ b/src/plugins/debugger/cdb/cdboptions.h
@@ -54,6 +54,14 @@ public:
                        SymbolOptionsChanged = 0x4 };
     unsigned compare(const CdbOptions &s) const;
 
+    // Format a symbol server specification with a cache directory
+    static QString symbolServerPath(const QString &cacheDir);
+    // Check whether the path is a symbol server specification and return the cache directory
+    static bool isSymbolServerPath(const QString &symbolPath, QString *cacheDir = 0);
+    static int indexOfSymbolServerPath(const QStringList &symbolPaths, QString *cacheDir = 0);
+
+    static QString settingsGroup();
+
     bool enabled;
     QString path;
     QStringList symbolPaths;
diff --git a/src/plugins/debugger/cdb/cdbsymbolpathlisteditor.cpp b/src/plugins/debugger/cdb/cdbsymbolpathlisteditor.cpp
index 4bd5e2c953a25eb2dc5bdec6be9ed3c198de41cd..a3fc68922aaf3a3e723d10cdbeb827d1f3155006 100644
--- a/src/plugins/debugger/cdb/cdbsymbolpathlisteditor.cpp
+++ b/src/plugins/debugger/cdb/cdbsymbolpathlisteditor.cpp
@@ -28,13 +28,83 @@
 **************************************************************************/
 
 #include "cdbsymbolpathlisteditor.h"
+#include "cdboptions.h"
 
+#include <utils/pathchooser.h>
+
+#include <QtCore/QDir>
+#include <QtCore/QDebug>
 #include <QtGui/QFileDialog>
 #include <QtGui/QAction>
+#include <QtGui/QDialogButtonBox>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QFormLayout>
+#include <QtGui/QMessageBox>
 
 namespace Debugger {
 namespace Internal {
 
+CacheDirectoryDialog::CacheDirectoryDialog(QWidget *parent) :
+    QDialog(parent), m_chooser(new Utils::PathChooser),
+    m_buttonBox(new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel))
+{
+    setWindowTitle(tr("Select Local Cache Folder"));
+    setModal(true);
+    setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
+    QFormLayout *formLayout = new QFormLayout;
+    m_chooser->setExpectedKind(Utils::PathChooser::Directory);
+    m_chooser->setMinimumWidth(400);
+    formLayout->addRow(tr("Path:"), m_chooser);
+
+    QVBoxLayout *mainLayout = new QVBoxLayout;
+    mainLayout->addLayout(formLayout);
+    mainLayout->addWidget(m_buttonBox);
+
+    setLayout(mainLayout);
+
+    connect(m_buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
+    connect(m_buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+}
+
+void CacheDirectoryDialog::setPath(const QString &p)
+{
+    m_chooser->setPath(p);
+}
+
+QString CacheDirectoryDialog::path() const
+{
+    return m_chooser->path();
+}
+
+void CacheDirectoryDialog::accept()
+{
+    // Ensure path exists
+    QString cache = path();
+    if (cache.isEmpty())
+        return;
+    QFileInfo fi(cache);
+    // Folder exists - all happy.
+    if (fi.isDir()) {
+        QDialog::accept();
+        return;
+    }
+    // Does a file of the same name exist?
+    if (fi.exists()) {
+        QMessageBox::warning(this, tr("Already Exists"),
+                             tr("A file named '%1' already exists.").arg(cache));
+        return;
+    }
+    // Create
+    QDir root(QDir::root());
+    if (!root.mkpath(cache)) {
+        QMessageBox::warning(this, tr("Cannot Create"),
+                             tr("The folder '%1' could not be created.").arg(cache));
+        return;
+    }
+    QDialog::accept();
+}
+
 CdbSymbolPathListEditor::CdbSymbolPathListEditor(QWidget *parent) :
     Utils::PathListEditor(parent)
 {
@@ -44,15 +114,20 @@ CdbSymbolPathListEditor::CdbSymbolPathListEditor(QWidget *parent) :
                       "Requires specifying a local cache directory."));
 }
 
+QString CdbSymbolPathListEditor::promptCacheDirectory(QWidget *parent)
+{
+    CacheDirectoryDialog dialog(parent);
+    dialog.setPath(QDir::tempPath() + QDir::separator() + QLatin1String("symbolcache"));
+    if (dialog.exec() != QDialog::Accepted)
+        return QString();
+    return dialog.path();
+}
+
 void CdbSymbolPathListEditor::addSymbolServer()
 {
-    const QString title = tr("Pick a local cache directory");
-    const QString cacheDir = QFileDialog::getExistingDirectory(this, title);
-    if (!cacheDir.isEmpty()) {
-        const QString path = QString::fromLatin1("symsrv*symsrv.dll*%1*http://msdl.microsoft.com/download/symbols").
-                             arg(QDir::toNativeSeparators(cacheDir));
-        insertPathAtCursor(path);
-    }
+    const QString cacheDir = promptCacheDirectory(this);
+    if (!cacheDir.isEmpty())
+        insertPathAtCursor(CdbOptions::symbolServerPath(cacheDir));
 }
 
 } // namespace Internal
diff --git a/src/plugins/debugger/cdb/cdbsymbolpathlisteditor.h b/src/plugins/debugger/cdb/cdbsymbolpathlisteditor.h
index 9959c001d0b49fa5a8d19ed0ee0c4f42234cbaa7..9152762fcb031a40fa4de720f4331f581f540c36 100644
--- a/src/plugins/debugger/cdb/cdbsymbolpathlisteditor.h
+++ b/src/plugins/debugger/cdb/cdbsymbolpathlisteditor.h
@@ -32,15 +32,49 @@
 
 #include <utils/pathlisteditor.h>
 
+#include <QtGui/QDialog>
+
+namespace Utils {
+    class PathChooser;
+}
+
+QT_BEGIN_NAMESPACE
+class QDialogButtonBox;
+QT_END_NAMESPACE
+
 namespace Debugger {
 namespace Internal {
 
+// Internal helper dialog prompting for a cache directory
+// using a PathChooser.
+// Note that QFileDialog does not offer a way of suggesting
+// a non-existent folder, which is in turn automatically
+// created. This is done here (suggest $TEMP\symbolcache
+// regardless of its existence).
+
+class CacheDirectoryDialog    : public QDialog {
+    Q_OBJECT
+public:
+   explicit CacheDirectoryDialog(QWidget *parent = 0);
+
+   void setPath(const QString &p);
+   QString path() const;
+
+   virtual void accept();
+
+private:
+   Utils::PathChooser *m_chooser;
+   QDialogButtonBox *m_buttonBox;
+};
+
 class CdbSymbolPathListEditor : public Utils::PathListEditor
 {
     Q_OBJECT
 public:
     explicit CdbSymbolPathListEditor(QWidget *parent = 0);
 
+    static QString promptCacheDirectory(QWidget *parent);
+
 private slots:
     void addSymbolServer();
 };