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);