diff --git a/src/plugins/ios/iosdebugsupport.cpp b/src/plugins/ios/iosdebugsupport.cpp
index 174ea9bd9cc5077c71a7bdd1b4bfd2257710f8dd..d698c9e438a196c2772cba661d7678ab4cc6327f 100644
--- a/src/plugins/ios/iosdebugsupport.cpp
+++ b/src/plugins/ios/iosdebugsupport.cpp
@@ -222,9 +222,9 @@ void IosDebugSupport::handleRemoteErrorOutput(const QString &output)
 {
     if (m_runControl) {
         if (m_runControl->engine())
-            m_runControl->engine()->showMessage(output + QLatin1Char('\n'), AppError);
+            m_runControl->engine()->showMessage(output, AppError);
         else
-            m_runControl->showMessage(output + QLatin1Char('\n'), AppError);
+            m_runControl->showMessage(output, AppError);
     }
 }
 
diff --git a/src/plugins/ios/iostoolhandler.cpp b/src/plugins/ios/iostoolhandler.cpp
index e00e13754dd0937d2cdcc51039272cbcff2c5863..7a4ffe9f50d0ce428fa9fd35176e906e4a9b363b 100644
--- a/src/plugins/ios/iostoolhandler.cpp
+++ b/src/plugins/ios/iostoolhandler.cpp
@@ -62,6 +62,7 @@ struct ParserState {
         Value,
         QueryResult,
         AppOutput,
+        ControlChar,
         AppStarted,
         InferiorPid,
         GdbServerPort,
@@ -87,9 +88,10 @@ struct ParserState {
         case Status:
         case InferiorPid:
         case GdbServerPort:
+        case AppOutput:
             return true;
         case QueryResult:
-        case AppOutput:
+        case ControlChar:
         case AppStarted:
         case AppTransfer:
         case Item:
@@ -398,6 +400,13 @@ void IosToolHandlerPrivate::processXml()
                 stack.append(ParserState(ParserState::QueryResult));
             } else if (elName == QLatin1String("app_output")) {
                 stack.append(ParserState(ParserState::AppOutput));
+            } else if (elName == QLatin1String("control_char")) {
+                QXmlStreamAttributes attributes = outputParser.attributes();
+                QChar c[1] = { QChar::fromLatin1(static_cast<char>(attributes.value(QLatin1String("code")).toString().toInt())) };
+                if (stack.size() > 0 && stack.last().collectChars())
+                    stack.last().chars.append(c[0]);
+                stack.append(ParserState(ParserState::ControlChar));
+                break;
             } else if (elName == QLatin1String("item")) {
                 stack.append(ParserState(ParserState::Item));
             } else if (elName == QLatin1String("status")) {
@@ -466,6 +475,9 @@ void IosToolHandlerPrivate::processXml()
                 stop(0);
                 return;
             case ParserState::AppOutput:
+                appOutput(p.chars);
+                break;
+            case ParserState::ControlChar:
                 break;
             case ParserState::AppStarted:
                 break;
@@ -494,9 +506,7 @@ void IosToolHandlerPrivate::processXml()
             // isCDATA() returns true.
             if (stack.isEmpty())
                 break;
-            if (stack.last().kind == ParserState::AppOutput)
-                emit appOutput(outputParser.text().toString());
-            else if (stack.last().collectChars())
+            if (stack.last().collectChars())
                 stack.last().chars.append(outputParser.text());
             break;
         case QXmlStreamReader::Comment:
diff --git a/src/tools/iostool/main.cpp b/src/tools/iostool/main.cpp
index bfec66e07ac348cc3cf50768b0b8b8c061f38a09..0d2c4cdf929945718b6ef42885fe1c859cc35057 100644
--- a/src/tools/iostool/main.cpp
+++ b/src/tools/iostool/main.cpp
@@ -65,6 +65,7 @@ public:
     void writeMsg(const char *msg);
     void writeMsg(const QString &msg);
     void stopXml(int errorCode);
+    void writeTextInElement(const QString &output);
 private slots:
     void isTransferringApp(const QString &bundlePath, const QString &deviceId, int progress,
                            const QString &info);
@@ -338,13 +339,15 @@ void IosTool::didStartApp(const QString &bundlePath, const QString &deviceId,
 
 void IosTool::writeMsg(const char *msg)
 {
-    out.writeTextElement(QLatin1String("msg"), QLatin1String(msg));
-    outFile.flush();
+    writeMsg(QString::fromLatin1(msg));
 }
 
 void IosTool::writeMsg(const QString &msg)
 {
-    out.writeTextElement(QLatin1String("msg"), msg);
+    out.writeStartElement(QLatin1String("msg"));
+    writeTextInElement(msg);
+    out.writeCharacters(QLatin1String("\n"));
+    out.writeEndElement();
     outFile.flush();
 }
 
@@ -366,18 +369,35 @@ void IosTool::deviceInfo(const QString &deviceId, const Ios::IosDeviceManager::D
     doExit();
 }
 
+void IosTool::writeTextInElement(const QString &output)
+{
+    QRegExp controlCharRe(QLatin1String("[\x01-\x08]|\x0B|\x0C|[\x0E-\x1F]|\\0000"));
+    int pos = 0;
+    int oldPos = 0;
+
+    while ((pos = controlCharRe.indexIn(output, pos)) != -1) {
+        out.writeCharacters(output.mid(oldPos, pos - oldPos));
+        out.writeEmptyElement(QLatin1String("control_char"));
+        out.writeAttribute(QLatin1String("code"), QString::number(output.at(pos).toLatin1()));
+        pos += 1;
+        oldPos = pos;
+    }
+    out.writeCharacters(output.mid(oldPos, output.length() - oldPos));
+}
+
 void IosTool::appOutput(const QString &output)
 {
-    if (inAppOutput)
-        out.writeCharacters(output);
-    else
-        out.writeTextElement(QLatin1String("app_output"), output);
+    if (!inAppOutput)
+        out.writeStartElement(QLatin1String("app_output"));
+    writeTextInElement(output);
+    if (!inAppOutput)
+        out.writeEndElement();
     outFile.flush();
 }
 
 void IosTool::errorMsg(const QString &msg)
 {
-    writeMsg(msg + QLatin1Char('\n'));
+    writeMsg(msg);
 }
 
 void IosTool::handleNewConnection()