diff --git a/src/plugins/coreplugin/dialogs/settingsdialog.cpp b/src/plugins/coreplugin/dialogs/settingsdialog.cpp
index e354928a7a4bcf4c0e47cac52a8838864525f265..3f2790a35489ec9a400d6e9afa40cfb380c92122 100644
--- a/src/plugins/coreplugin/dialogs/settingsdialog.cpp
+++ b/src/plugins/coreplugin/dialogs/settingsdialog.cpp
@@ -63,6 +63,8 @@ const int categoryIconSize = 24;
 namespace Core {
 namespace Internal {
 
+QPointer<SettingsDialog> SettingsDialog::m_instance = 0;
+
 // ----------- Category model
 
 class Category {
@@ -253,18 +255,20 @@ static inline QList<Core::IOptionsPage*> sortedOptionsPages()
     return rc;
 }
 
-SettingsDialog::SettingsDialog(QWidget *parent, const QString &categoryId,
-                               const QString &pageId) :
+SettingsDialog::SettingsDialog(QWidget *parent) :
     QDialog(parent),
     m_pages(sortedOptionsPages()),
     m_proxyModel(new CategoryFilterModel(this)),
     m_model(new CategoryModel(this)),
-    m_applied(false),
     m_stackedLayout(new QStackedLayout),
     m_filterLineEdit(new Utils::FilterLineEdit),
     m_categoryList(new CategoryListView),
-    m_headerLabel(new QLabel)
+    m_headerLabel(new QLabel),
+    m_running(false),
+    m_applied(false)
 {
+    m_applied = false;
+
     createGui();
     setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
 #ifdef Q_OS_MAC
@@ -275,31 +279,16 @@ SettingsDialog::SettingsDialog(QWidget *parent, const QString &categoryId,
 
     m_model->setPages(m_pages);
 
-    QString initialCategory = categoryId;
-    QString initialPage = pageId;
-    if (initialCategory.isEmpty() && initialPage.isEmpty()) {
-        QSettings *settings = ICore::instance()->settings();
-        initialCategory = settings->value(QLatin1String(categoryKeyC), QVariant(QString())).toString();
-        initialPage = settings->value(QLatin1String(pageKeyC), QVariant(QString())).toString();
-    }
-
-    int initialCategoryIndex = -1;
-    int initialPageIndex = -1;
-
     // Create the tab widgets with the pages in each category
     const QList<Category*> &categories = m_model->categories();
     for (int i = 0; i < categories.size(); ++i) {
         Category *category = categories.at(i);
-        if (category->id == initialCategory)
-            initialCategoryIndex = i;
 
         QTabWidget *tabWidget = new QTabWidget;
         for (int j = 0; j < category->pages.size(); ++j) {
             IOptionsPage *page = category->pages.at(j);
             QWidget *widget = page->createPage(0);
             tabWidget->addTab(widget, page->displayName());
-            if (initialCategoryIndex == i && page->id() == initialPage)
-                initialPageIndex = j;
         }
 
         connect(tabWidget, SIGNAL(currentChanged(int)),
@@ -319,18 +308,46 @@ SettingsDialog::SettingsDialog(QWidget *parent, const QString &categoryId,
     connect(m_categoryList->selectionModel(), SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
             this, SLOT(currentChanged(QModelIndex)));
 
+    // The order of the slot connection matters here, the filter slot
+    // opens the matching page after the model has filtered.
+    connect(m_filterLineEdit, SIGNAL(filterChanged(QString)),
+                m_proxyModel, SLOT(setFilterFixedString(QString)));
+    connect(m_filterLineEdit, SIGNAL(filterChanged(QString)), this, SLOT(filter(QString)));
+    m_categoryList->setFocus();
+    setAttribute(Qt::WA_DeleteOnClose);
+}
+
+void SettingsDialog::showPage(const QString &categoryId, const QString &pageId)
+{
+    // handle the case of "show last page"
+    QString initialCategory = categoryId;
+    QString initialPage = pageId;
+    if (initialCategory.isEmpty() && initialPage.isEmpty()) {
+        QSettings *settings = ICore::instance()->settings();
+        initialCategory = settings->value(QLatin1String(categoryKeyC), QVariant(QString())).toString();
+        initialPage = settings->value(QLatin1String(pageKeyC), QVariant(QString())).toString();
+    }
+
+    int initialCategoryIndex = -1;
+    int initialPageIndex = -1;
+    const QList<Category*> &categories = m_model->categories();
+    for (int i = 0; i < categories.size(); ++i) {
+        Category *category = categories.at(i);
+        if (category->id == initialCategory) {
+            initialCategoryIndex = i;
+            for (int j = 0; j < category->pages.size(); ++j) {
+                IOptionsPage *page = category->pages.at(j);
+                if (page->id() == initialPage)
+                    initialPageIndex = j;
+            }
+        }
+    }
     if (initialCategoryIndex != -1) {
         const QModelIndex modelIndex = m_proxyModel->mapFromSource(m_model->index(initialCategoryIndex));
         m_categoryList->setCurrentIndex(modelIndex);
         if (initialPageIndex != -1)
             categories.at(initialCategoryIndex)->tabWidget->setCurrentIndex(initialPageIndex);
     }
-
-    // The order of the slot connection matters here, the filter slot
-    // opens the matching page after the model has filtered.
-    connect(m_filterLineEdit, SIGNAL(filterChanged(QString)),
-                m_proxyModel, SLOT(setFilterFixedString(QString)));
-    connect(m_filterLineEdit, SIGNAL(filterChanged(QString)), this, SLOT(filter(QString)));
 }
 
 void SettingsDialog::createGui()
@@ -464,19 +481,20 @@ void SettingsDialog::apply()
     m_applied = true;
 }
 
-bool SettingsDialog::execDialog()
-{
-    m_categoryList->setFocus();
-    m_applied = false;
-    exec();
-    return m_applied;
-}
-
 void SettingsDialog::done(int val)
 {
     QSettings *settings = ICore::instance()->settings();
     settings->setValue(QLatin1String(categoryKeyC), m_currentCategory);
     settings->setValue(QLatin1String(pageKeyC), m_currentPage);
+
+    // exit all additional event loops, see comment in execDialog()
+    QListIterator<QEventLoop *> it(m_eventLoops);
+    it.toBack();
+    while (it.hasPrevious()) {
+        QEventLoop *loop = it.previous();
+        loop->exit();
+    }
+
     QDialog::done(val);
 }
 
@@ -488,5 +506,38 @@ QSize SettingsDialog::sizeHint() const
     return minimumSize();
 }
 
+SettingsDialog *SettingsDialog::getSettingsDialog(QWidget *parent,
+                           const QString &initialCategory,
+                           const QString &initialPage)
+{
+    if (!m_instance) {
+        m_instance = new SettingsDialog(parent);
+    }
+    m_instance->showPage(initialCategory, initialPage);
+    return m_instance;
+}
+
+bool SettingsDialog::execDialog()
+{
+    if (!m_running) {
+        m_running = true;
+        exec();
+    } else {
+        // exec dialog is called while the instance is already running
+        // this can happen when a event triggers a code path that wants to
+        // show the settings dialog again
+        // e.g. when starting the debugger (with non-built debugging helpers),
+        // and manually opening the settings dialog, after the debugger hit
+        // a break point it will complain about missing helper, and offer the
+        // option to open the settings dialog.
+        // Keep the UI running by creating another event loop.
+        QEventLoop *loop = new QEventLoop(this);
+        m_eventLoops.append(loop);
+        loop->exec();
+    }
+    return m_applied;
+}
+
+
 } // namespace Internal
 } // namespace Core
diff --git a/src/plugins/coreplugin/dialogs/settingsdialog.h b/src/plugins/coreplugin/dialogs/settingsdialog.h
index 632be74da0172c2adb210eb470648416f6816014..4172f036f871c8dc0e6d4eee858b3398c879d88c 100644
--- a/src/plugins/coreplugin/dialogs/settingsdialog.h
+++ b/src/plugins/coreplugin/dialogs/settingsdialog.h
@@ -34,6 +34,8 @@
 
 #include <QtCore/QList>
 #include <QtCore/QSet>
+#include <QtCore/QPointer>
+#include <QtCore/QEventLoop>
 #include <QtGui/QDialog>
 
 QT_BEGIN_NAMESPACE
@@ -59,13 +61,15 @@ class SettingsDialog : public QDialog
     Q_OBJECT
 
 public:
-    SettingsDialog(QWidget *parent,
-                   const QString &initialCategory = QString(),
-                   const QString &initialPage = QString());
-    ~SettingsDialog();
 
-    // Run the dialog and return true if 'Ok' was chosen or 'Apply' was invoked
-    // at least once
+    // Returns a settings dialog. This makes sure that always only
+    // a single settings dialog instance is running.
+    // The dialog will be deleted automatically on close.
+    static SettingsDialog *getSettingsDialog(QWidget *parent,
+                               const QString &initialCategory = QString(),
+                               const QString &initialPage = QString());
+    // Run the dialog and wait for it to finish.
+    // Returns if the changes have been applied.
     bool execDialog();
 
     virtual QSize sizeHint() const;
@@ -82,8 +86,12 @@ private slots:
     void filter(const QString &text);
 
 private:
+    SettingsDialog(QWidget *parent);
+    ~SettingsDialog();
+
     void createGui();
     void showCategory(int index);
+    void showPage(const QString &categoryId, const QString &pageId);
     void updateEnabledTabs(Category *category, const QString &searchText);
 
     const QList<Core::IOptionsPage*> m_pages;
@@ -91,13 +99,16 @@ private:
     QSet<Core::IOptionsPage*> m_visitedPages;
     QSortFilterProxyModel *m_proxyModel;
     CategoryModel *m_model;
-    bool m_applied;
     QString m_currentCategory;
     QString m_currentPage;
     QStackedLayout *m_stackedLayout;
     Utils::FilterLineEdit *m_filterLineEdit;
     QListView *m_categoryList;
     QLabel *m_headerLabel;
+    bool m_running;
+    bool m_applied;
+    QList<QEventLoop *> m_eventLoops;
+    static QPointer<SettingsDialog> m_instance;
 };
 
 } // namespace Internal
diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp
index e20d9cde4e1ddc2e85b72d382e4841db57b39ace..e2edbfce8b50a16cf48fff233533d19b0b6fee4c 100644
--- a/src/plugins/coreplugin/mainwindow.cpp
+++ b/src/plugins/coreplugin/mainwindow.cpp
@@ -928,8 +928,8 @@ bool MainWindow::showOptionsDialog(const QString &category,
     emit m_coreImpl->optionsDialogRequested();
     if (!parent)
         parent = this;
-    SettingsDialog dlg(parent, category, page);
-    return dlg.execDialog();
+    SettingsDialog *dialog = SettingsDialog::getSettingsDialog(parent, category, page);
+    return dialog->execDialog();
 }
 
 void MainWindow::saveAll()