diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp
index 653a6817b62afeb6e8c7f00cdbfd0aaff141efdc..1706b09b6e215d6dfa6a262bbd8aac99d5bd332d 100644
--- a/src/plugins/debugger/gdbengine.cpp
+++ b/src/plugins/debugger/gdbengine.cpp
@@ -1824,9 +1824,9 @@ void GdbEngine::sendInsertBreakpoint(int index)
         //if (where.isEmpty())
         //    where = data->fileName;
 #endif
-        // we need something like   "\"file name.cpp\":100"  to
-        // survive the gdb command line parser with file names intact
-        where = _("\"\\\"") + where + _("\\\":") + data->lineNumber + _c('"');
+        // The argument is simply a C-quoted version of the argument to the
+        // non-MI "break" command, including the "original" quoting it wants.
+        where = _("\"\\\"") + GdbMi::escapeCString(where) + _("\\\":") + data->lineNumber + _c('"');
     } else {
         where = data->funcName;
     }
@@ -1987,6 +1987,8 @@ void GdbEngine::handleBreakInsert(const GdbResultRecord &record, const QVariant
         handler->updateMarkers();
     } else if (record.resultClass == GdbResultError) {
         const BreakpointData *data = handler->at(index);
+        // Note that it is perfectly correct that the file name is put
+        // in quotes but not escaped. GDB simply is like that.
 #ifdef Q_OS_LINUX
         //QString where = "\"\\\"" + data->fileName + "\\\":"
         //    + data->lineNumber + "\"";
@@ -3848,13 +3850,13 @@ void GdbEngine::tryLoadDebuggingHelpers()
     execCommand(_("sharedlibrary .*")); // for LoadLibraryA
     //execCommand(_("handle SIGSEGV pass stop print"));
     //execCommand(_("set unwindonsignal off"));
-    execCommand(_("call LoadLibraryA(\"") + lib + _("\")"),
+    execCommand(_("call LoadLibraryA(\"") + GdbMi::escapeCString(lib) + _("\")"),
         CB(handleDebuggingHelperSetup));
     execCommand(_("sharedlibrary ") + dotEscape(lib));
 #elif defined(Q_OS_MAC)
     //execCommand(_("sharedlibrary libc")); // for malloc
     //execCommand(_("sharedlibrary libdl")); // for dlopen
-    execCommand(_("call (void)dlopen(\"") + lib + _("\", " STRINGIFY(RTLD_NOW) ")"),
+    execCommand(_("call (void)dlopen(\"") + GdbMi::escapeCString(lib) + _("\", " STRINGIFY(RTLD_NOW) ")"),
         CB(handleDebuggingHelperSetup));
     //execCommand(_("sharedlibrary ") + dotEscape(lib));
     m_debuggingHelperState = DebuggingHelperLoadTried;
@@ -3863,10 +3865,10 @@ void GdbEngine::tryLoadDebuggingHelpers()
     QString flag = QString::number(RTLD_NOW);
     execCommand(_("sharedlibrary libc")); // for malloc
     execCommand(_("sharedlibrary libdl")); // for dlopen
-    execCommand(_("call (void*)dlopen(\"") + lib + _("\", " STRINGIFY(RTLD_NOW) ")"),
+    execCommand(_("call (void*)dlopen(\"") + GdbMi::escapeCString(lib) + _("\", " STRINGIFY(RTLD_NOW) ")"),
         CB(handleDebuggingHelperSetup));
     // some older systems like CentOS 4.6 prefer this:
-    execCommand(_("call (void*)__dlopen(\"") + lib + _("\", " STRINGIFY(RTLD_NOW) ")"),
+    execCommand(_("call (void*)__dlopen(\"") + GdbMi::escapeCString(lib) + _("\", " STRINGIFY(RTLD_NOW) ")"),
         CB(handleDebuggingHelperSetup));
     execCommand(_("sharedlibrary ") + dotEscape(lib));
 #endif
diff --git a/src/plugins/debugger/gdbmi.cpp b/src/plugins/debugger/gdbmi.cpp
index bb858ad4db36e2b3938ae423e7c3124f0b0bbb69..e2fd7e7a25a67ec2e7ca9a0873daff134bd7363b 100644
--- a/src/plugins/debugger/gdbmi.cpp
+++ b/src/plugins/debugger/gdbmi.cpp
@@ -250,12 +250,18 @@ void GdbMi::dumpChildren(QByteArray * str, bool multiline, int indent) const
     }
 }
 
-QByteArray GdbMi::escapeCString(const QByteArray &ba)
+class MyString : public QString {
+public:
+    ushort at(int i) const { return constData()[i].unicode(); }
+};
+
+template<class ST, typename CT>
+inline ST escapeCStringTpl(const ST &ba)
 {
-    QByteArray ret;
+    ST ret;
     ret.reserve(ba.length() * 2);
     for (int i = 0; i < ba.length(); ++i) {
-        uchar c = ba.at(i);
+        CT c = ba.at(i);
         switch (c) {
             case '\\': ret += "\\\\"; break;
             case '\a': ret += "\\a"; break;
@@ -280,6 +286,16 @@ QByteArray GdbMi::escapeCString(const QByteArray &ba)
     return ret;
 }
 
+QString GdbMi::escapeCString(const QString &ba)
+{
+    return escapeCStringTpl<MyString, ushort>(static_cast<const MyString &>(ba));
+}
+
+QByteArray GdbMi::escapeCString(const QByteArray &ba)
+{
+    return escapeCStringTpl<QByteArray, uchar>(ba);
+}
+
 QByteArray GdbMi::toString(bool multiline, int indent) const
 {
     QByteArray result;
diff --git a/src/plugins/debugger/gdbmi.h b/src/plugins/debugger/gdbmi.h
index 30de06be386913612f1859c93431eedfcfe93dff..1e9731bb30362f2f46a786539a16c292922be16a 100644
--- a/src/plugins/debugger/gdbmi.h
+++ b/src/plugins/debugger/gdbmi.h
@@ -133,6 +133,7 @@ private:
 
     static QByteArray parseCString(const char *&from, const char *to);
     static QByteArray escapeCString(const QByteArray &ba);
+    static QString escapeCString(const QString &ba);
     void parseResultOrValue(const char *&from, const char *to);
     void parseValue(const char *&from, const char *to);
     void parseTuple(const char *&from, const char *to);