diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp
index 788e57a63e3a295a1f11ca34d2b4faa8af963021..0989993f7a540acf653409497bb1740bd2fecb51 100644
--- a/src/plugins/debugger/gdbengine.cpp
+++ b/src/plugins/debugger/gdbengine.cpp
@@ -341,12 +341,6 @@ void GdbEngine::gdbProcError(QProcess::ProcessError error)
     q->exitDebugger();
 }
 
-static void skipSpaces(const char *&from, const char *to)
-{
-    while (from != to && QChar(*from).isSpace())
-        ++from;
-}
-
 static inline bool isNameChar(char c)
 {
     // could be 'stopped' or 'shlibs-added'
@@ -369,15 +363,6 @@ static void dump(const char *first, const char *middle, const QString & to)
 }
 #endif
 
-static void skipTerminator(const char *&from, const char *to)
-{
-    skipSpaces(from, to);
-    // skip '(gdb)'
-    if (from[0] == '(' && from[1] == 'g' && from[3] == 'b' && from[4] == ')')
-        from += 5;
-    skipSpaces(from, to);
-}
-
 void GdbEngine::readDebugeeOutput(const QByteArray &data)
 {
     emit applicationOutputAvailable(m_outputCodec->toUnicode(
@@ -389,205 +374,179 @@ void GdbEngine::debugMessage(const QString &msg)
     emit gdbOutputAvailable("debug:", msg);
 }
 
-// called asyncronously as response to Gdb stdout output in
-// gdbResponseAvailable()
-void GdbEngine::handleResponse()
+void GdbEngine::handleResponse(const QByteArray &buff)
 {
     static QTime lastTime;
 
     emit gdbOutputAvailable("            ", currentTime());
-    emit gdbOutputAvailable("stdout:", m_inbuffer);
+    emit gdbOutputAvailable("stdout:", buff);
 
 #if 0
     qDebug() // << "#### start response handling #### "
         << currentTime()
         << lastTime.msecsTo(QTime::currentTime()) << "ms,"
-        << "buf: " << m_inbuffer.left(1500) << "..."
-        //<< "buf: " << m_inbuffer
-        << "size:" << m_inbuffer.size();
+        << "buf: " << buff.left(1500) << "..."
+        //<< "buf: " << buff
+        << "size:" << buff.size();
 #else
-    //qDebug() << "buf: " << m_inbuffer;
+    //qDebug() << "buf: " << buff;
 #endif
 
     lastTime = QTime::currentTime();
 
-    while (1) {
-        if (m_inbuffer.isEmpty())
-            break;
+    if (buff.isEmpty() || buff == "(gdb) ")
+        return;
 
-        const char *from = m_inbuffer.constData();
-        // FIXME: check for line ending in '\n(gdb)\n'
-        const char *to = from + m_inbuffer.size();
-        const char *inner;
+    const char *from = buff.constData();
+    const char *to = from + buff.size();
+    const char *inner;
 
-        //const char *oldfrom = from;
+    int token = -1;
+    // token is a sequence of numbers
+    for (inner = from; inner != to; ++inner)
+        if (*inner < '0' || *inner > '9')
+            break;
+    if (from != inner) {
+        token = QByteArray(from, inner - from).toInt();
+        from = inner;
+        //qDebug() << "found token " << token;
+    }
+
+    // next char decides kind of record
+    const char c = *from++;
+    //qDebug() << "CODE:" << c;
+    switch (c) {
+        case '*':
+        case '+':
+        case '=': {
+            QByteArray asyncClass;
+            for (; from != to; ++from) {
+                const char c = *from;
+                if (!isNameChar(c))
+                    break;
+                asyncClass += *from;
+            }
+            //qDebug() << "ASYNCCLASS" << asyncClass;
 
-        //skipSpaces(from, to);
-        skipTerminator(from, to);
-        int token = -1;
+            GdbMi record;
+            while (from != to) {
+                if (*from != ',') {
+                    qDebug() << "MALFORMED ASYNC OUTPUT" << from;
+                    return;
+                }
+                ++from; // skip ','
+                GdbMi data;
+                data.parseResultOrValue(from, to);
+                if (data.isValid()) {
+                    //qDebug() << "parsed response: " << data.toString();
+                    record.m_children += data;
+                    record.m_type = GdbMi::Tuple;
+                }
+            }
+            if (asyncClass == "stopped") {
+                handleAsyncOutput(record);
+            } else if (asyncClass == "running") {
+                // Archer has 'thread-id="all"' here
+            #ifdef Q_OS_MAC
+            } else if (asyncClass == "shlibs-updated") {
+                // MAC announces updated libs
+            } else if (asyncClass == "shlibs-added") {
+                // MAC announces added libs
+                // {shlib-info={num="2", name="libmathCommon.A_debug.dylib",
+                // kind="-", dyld-addr="0x7f000", reason="dyld", requested-state="Y",
+                // state="Y", path="/usr/lib/system/libmathCommon.A_debug.dylib",
+                // description="/usr/lib/system/libmathCommon.A_debug.dylib",
+                // loaded_addr="0x7f000", slide="0x7f000", prefix=""}}
+            #endif
+            } else {
+                qDebug() << "IGNORED ASYNC OUTPUT "
+                    << asyncClass << record.toString();
+            }
+            break;
+        }
 
-        // token is a sequence of numbers
-        for (inner = from; inner != to; ++inner)
-            if (*inner < '0' || *inner > '9')
-                break;
-        if (from != inner) {
-            token = QString(QByteArray(from, inner - from)).toInt();
-            from = inner;
-            //qDebug() << "found token " << token;
+        case '~': {
+            m_pendingConsoleStreamOutput += GdbMi::parseCString(from, to);
+            break;
         }
 
-        if (from == to) {
-            //qDebug() << "Returning: " << toString();
+        case '@': {
+            m_pendingTargetStreamOutput += GdbMi::parseCString(from, to);
             break;
         }
 
-        // next char decides kind of record
-        const char c = *from++;
-        //qDebug() << "CODE:" << c;
-
-        switch (c) {
-            case '*':
-            case '+':
-            case '=': {
-                QByteArray asyncClass;
-                for (; from != to; ++from) {
-                    const char c = *from;
-                    if (!isNameChar(c))
-                        break;
-                    asyncClass += *from;
-                }
-                //qDebug() << "ASYNCCLASS" << asyncClass;
-
-                GdbMi record;
-                while (from != to && *from == ',') {
-                    ++from; // skip ','
-                    GdbMi data;
-                    data.parseResultOrValue(from, to);
-                    if (data.isValid()) {
-                        //qDebug() << "parsed response: " << data.toString();
-                        record.m_children += data;
-                        record.m_type = GdbMi::Tuple;
-                    }
-                }
-                //dump(oldfrom, from, record.toString());
-                skipTerminator(from, to);
-                m_inbuffer = QByteArray(from, to - from);
-                if (asyncClass == "stopped") {
-                    handleAsyncOutput(record);
-                } else if (asyncClass == "running") {
-                    // Archer has 'thread-id="all"' here
-                #ifdef Q_OS_MAC
-                } else if (asyncClass == "shlibs-updated") {
-                    // MAC announces updated libs
-                } else if (asyncClass == "shlibs-added") {
-                    // MAC announces added libs
-                    // {shlib-info={num="2", name="libmathCommon.A_debug.dylib",
-                    // kind="-", dyld-addr="0x7f000", reason="dyld", requested-state="Y",
-                    // state="Y", path="/usr/lib/system/libmathCommon.A_debug.dylib", 
-                    // description="/usr/lib/system/libmathCommon.A_debug.dylib",
-                    // loaded_addr="0x7f000", slide="0x7f000", prefix=""}}
-                #endif
-                } else {
-                    qDebug() << "IGNORED ASYNC OUTPUT "
-                        << asyncClass << record.toString();
-                }
-                break;
-            }
+        case '&': {
+            QByteArray data = GdbMi::parseCString(from, to);
+            m_pendingLogStreamOutput += data;
+            // On Windows, the contents seem to depend on the debugger
+            // version and/or OS version used.
+            if (data.startsWith("warning:"))
+                qq->showApplicationOutput(data);
+            break;
+        }
 
-            case '~': {
-                QByteArray data = GdbMi::parseCString(from, to);
-                m_pendingConsoleStreamOutput += data;
-                m_inbuffer = QByteArray(from, to - from);
-                break;
-            }
+        case '^': {
+            GdbResultRecord record;
 
-            case '@': {
-                QByteArray data = GdbMi::parseCString(from, to);
-                m_pendingTargetStreamOutput += data;
-                m_inbuffer = QByteArray(from, to - from);
-                break;
-            }
+            record.token = token;
 
-            case '&': {
-                QByteArray data = GdbMi::parseCString(from, to);
-                m_pendingLogStreamOutput += data;
-                m_inbuffer = QByteArray(from, to - from);
-                // On Windows, the contents seem to depend on the debugger
-                // version and/or OS version used.
-                if (data.startsWith("warning:"))
-                    qq->showApplicationOutput(data);
-                break;
-            }
+            for (inner = from; inner != to; ++inner)
+                if (*inner < 'a' || *inner > 'z')
+                    break;
+
+            QByteArray resultClass(from, inner - from);
+
+            if (resultClass == "done")
+                record.resultClass = GdbResultDone;
+            else if (resultClass == "running")
+                record.resultClass = GdbResultRunning;
+            else if (resultClass == "connected")
+                record.resultClass = GdbResultConnected;
+            else if (resultClass == "error")
+                record.resultClass = GdbResultError;
+            else if (resultClass == "exit")
+                record.resultClass = GdbResultExit;
+            else
+                record.resultClass = GdbResultUnknown;
 
-            case '^': {
-                GdbResultRecord record;
-
-                record.token = token;
-
-                for (inner = from; inner != to; ++inner)
-                    if (*inner < 'a' || *inner > 'z')
-                        break;
-
-                QByteArray resultClass(from, inner - from);
-
-                if (resultClass == "done")
-                    record.resultClass = GdbResultDone;
-                else if (resultClass == "running")
-                    record.resultClass = GdbResultRunning;
-                else if (resultClass == "connected")
-                    record.resultClass = GdbResultConnected;
-                else if (resultClass == "error")
-                    record.resultClass = GdbResultError;
-                else if (resultClass == "exit")
-                    record.resultClass = GdbResultExit;
-                else
-                    record.resultClass = GdbResultUnknown;
-
-                from = inner;
-                skipSpaces(from, to);
-                if (from != to && *from == ',') {
-                    ++from;
-                    record.data.parseTuple_helper(from, to);
-                    record.data.m_type = GdbMi::Tuple;
-                    record.data.m_name = "data";
+            from = inner;
+            if (from != to) {
+                if (*from != ',') {
+                    qDebug() << "MALFORMED RESULT OUTPUT" << from;
+                    return;
                 }
-                skipSpaces(from, to);
-                skipTerminator(from, to);
-
-                //qDebug() << "\nLOG STREAM:" + m_pendingLogStreamOutput;
-                //qDebug() << "\nTARGET STREAM:" + m_pendingTargetStreamOutput;
-                //qDebug() << "\nCONSOLE STREAM:" + m_pendingConsoleStreamOutput;
-                record.data.setStreamOutput("logstreamoutput",
-                    m_pendingLogStreamOutput);
-                record.data.setStreamOutput("targetstreamoutput",
-                    m_pendingTargetStreamOutput);
-                record.data.setStreamOutput("consolestreamoutput",
-                    m_pendingConsoleStreamOutput);
-                QByteArray custom = m_customOutputForToken[token];
-                if (!custom.isEmpty())
-                    record.data.setStreamOutput("customvaluecontents",
-                        '{' + custom + '}');
-                //m_customOutputForToken.remove(token);
-                m_pendingLogStreamOutput.clear();
-                m_pendingTargetStreamOutput.clear();
-                m_pendingConsoleStreamOutput.clear();
-
-                //dump(oldfrom, from, record.toString());
-                m_inbuffer = QByteArray(from, to - from);
-                handleResultRecord(record);
-                break;
-            }
-            default: {
-                qDebug() << "FIXME: UNKNOWN CODE: " << c << " IN " << m_inbuffer;
-                m_inbuffer = QByteArray(from, to - from);
-                break;
+                ++from;
+                record.data.parseTuple_helper(from, to);
+                record.data.m_type = GdbMi::Tuple;
+                record.data.m_name = "data";
             }
+
+            //qDebug() << "\nLOG STREAM:" + m_pendingLogStreamOutput;
+            //qDebug() << "\nTARGET STREAM:" + m_pendingTargetStreamOutput;
+            //qDebug() << "\nCONSOLE STREAM:" + m_pendingConsoleStreamOutput;
+            record.data.setStreamOutput("logstreamoutput",
+                m_pendingLogStreamOutput);
+            record.data.setStreamOutput("targetstreamoutput",
+                m_pendingTargetStreamOutput);
+            record.data.setStreamOutput("consolestreamoutput",
+                m_pendingConsoleStreamOutput);
+            QByteArray custom = m_customOutputForToken[token];
+            if (!custom.isEmpty())
+                record.data.setStreamOutput("customvaluecontents",
+                    '{' + custom + '}');
+            //m_customOutputForToken.remove(token);
+            m_pendingLogStreamOutput.clear();
+            m_pendingTargetStreamOutput.clear();
+            m_pendingConsoleStreamOutput.clear();
+
+            handleResultRecord(record);
+            break;
+        }
+        default: {
+            qDebug() << "UNKNOWN RESPONSE TYPE" << c;
+            break;
         }
     }
-
-    //qDebug() << "##### end response handling ####\n\n\n"
-    //    << currentTime() << lastTime.msecsTo(QTime::currentTime());
-    lastTime = QTime::currentTime();
 }
 
 void GdbEngine::readGdbStandardError()
@@ -597,30 +556,26 @@ void GdbEngine::readGdbStandardError()
 
 void GdbEngine::readGdbStandardOutput()
 {
-    // This is the function called whenever the Gdb process created
-    // output. As a rule of thumb, stdout contains _real_ Gdb output
-    // as responses to our command
-    // and "spontaneous" events like messages on loaded shared libraries.
-    // OTOH, stderr contains application output produced by qDebug etc.
-    // There is no organized way to pass application stdout output.
-
-    QByteArray out = m_gdbProc.readAllStandardOutput();
-
-    //qDebug() << "\n\n\nPLUGIN OUT: '" <<  out.data() << "'\n\n\n";
-
-    m_inbuffer.append(out);
-    //QTC_ASSERT(!m_inbuffer.isEmpty(), return);
+    m_inbuffer.append(m_gdbProc.readAllStandardOutput());
 
-    char c = m_inbuffer[m_inbuffer.size() - 1];
-    static const QByteArray termArray("(gdb) ");
-    if (out.indexOf(termArray) == -1 && c != 10 && c != 13) {
-        //qDebug() << "\n\nBuffer not yet filled, waiting for more data to arrive";
-        //qDebug() << m_inbuffer.data() << m_inbuffer.size();
-        //qDebug() << "\n\n";
-        return;
+    int newstart = 0;
+    while (newstart < m_inbuffer.size()) {
+        int start = newstart;
+        int end = m_inbuffer.indexOf('\n', start);
+        if (end < 0) {
+            m_inbuffer.remove(0, start);
+            return;
+        }
+        newstart = end + 1;
+        if (end == start)
+            continue;
+        if (m_inbuffer.at(end - 1) == '\r') {
+            --end;
+            if (end == start)
+                continue;
+        }
+        handleResponse(QByteArray::fromRawData(m_inbuffer.constData() + start, end - start));
     }
-
-    emit gdbResponseAvailable();
 }
 
 void GdbEngine::interruptInferior()
diff --git a/src/plugins/debugger/gdbengine.h b/src/plugins/debugger/gdbengine.h
index 9e6a0a9380b8b11e29a1f6757149acb5d6146dc5..7d205f513de105fcb5ef7ed1f9feb3becfb7b3e0 100644
--- a/src/plugins/debugger/gdbengine.h
+++ b/src/plugins/debugger/gdbengine.h
@@ -92,7 +92,6 @@ public:
     ~GdbEngine();
 
 signals:
-    void gdbResponseAvailable();
     void gdbInputAvailable(const QString &prefix, const QString &msg);
     void gdbOutputAvailable(const QString &prefix, const QString &msg);
     void applicationOutputAvailable(const QString &output);
@@ -173,8 +172,6 @@ private:
     void updateLocals();
 
 private slots:
-    void handleResponse();
-
     void gdbProcError(QProcess::ProcessError error);
     void readGdbStandardOutput();
     void readGdbStandardError();
@@ -182,6 +179,7 @@ private slots:
 
 private:
     int terminationIndex(const QByteArray &buffer, int &length);
+    void handleResponse(const QByteArray &buff);
     void handleStart(const GdbResultRecord &response);
     void handleAttach();
     void handleAqcuiredInferior();