diff --git a/share/qtcreator/gdbmacros/dumper.py b/share/qtcreator/gdbmacros/dumper.py
index e2bda10df3160c232e62ca119769ecee0491c390..97f736b7b9c9218444c484234fa2ccae64b45dac 100644
--- a/share/qtcreator/gdbmacros/dumper.py
+++ b/share/qtcreator/gdbmacros/dumper.py
@@ -61,8 +61,9 @@ Hex4EncodedLittleEndian, \
 Hex8EncodedLittleEndian, \
 Hex2EncodedUtf8, \
 Hex8EncodedBigEndian, \
-Hex4EncodedBigEndian \
-    = range(12)
+Hex4EncodedBigEndian, \
+Hex4EncodedLittleEndianWithoutQuotes \
+    = range(13)
 
 # Display modes
 StopDisplay, \
@@ -1684,4 +1685,45 @@ class Dumper:
                     with Children(self, 1):
                         self.listAnonymous(child, name, field.type)
 
+#######################################################################
+#
+# ThreadNames Command
+#
+#######################################################################
+
+
+class ThreadNamesCommand(gdb.Command):
+    """Guess Thread names"""
+
+    def __init__(self):
+        super(ThreadNamesCommand, self).__init__("threadnames", gdb.COMMAND_OBSCURE)
+        self.ns = qtNamespace()
+
+    def invoke(self, arg, from_tty):
+        out = '['
+        for thread in gdb.inferiors()[0].threads():
+            maximalStackDepth = int(arg)
+            thread.switch()
+            e = gdb.selected_frame ()
+            while True:
+                maximalStackDepth -= 1
+                if maximalStackDepth < 0:
+                    break
+                e = e.older()
+                if e == None or e.name() == None:
+                    break
+                if e.name() == self.ns + "QThreadPrivate::start":
+                    thrptr = e.read_var("thr").dereference()
+                    d_ptr = thrptr["d_ptr"]["d"].cast(lookupType(self.ns + "QObjectPrivate").pointer()).dereference()
+                    #warn("D_PTR: %s " % d_ptr)
+                    objectName = d_ptr["objectName"]
+                    i = 0
+                    out += '{valueencoded="' + str(Hex4EncodedLittleEndianWithoutQuotes)+'",id="'
+                    out += str(thread.num) + '",value="'
+                    out += encodeString(objectName)
+                    out += '"},'
+        print out[:-1] + ']'
+
+ThreadNamesCommand()
+
 
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index 2947f2cc2bd28763f46e6f5abeafc020536fea05..0a835346bc3f19ca3a3adfad71abf0c1b529ba24 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -2042,6 +2042,7 @@ void DebuggerPluginPrivate::connectEngine(DebuggerEngine *engine, bool notify)
     m_stackWindow->setModel(engine->stackModel());
     m_threadsWindow->setModel(engine->threadsModel());
     m_threadBox->setModel(engine->threadsModel());
+    m_threadBox->setModelColumn(ThreadData::NameColumn);
     m_watchersWindow->setModel(engine->watchersModel());
     m_capabilities = engine->debuggerCapabilities();
     if (notify)
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index aa9095b2ff091c30d324294ffdf53a02b3219ac1..45a5761472b097dcc74897d99b0d5af1674875ec 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -2963,6 +2963,7 @@ void GdbEngine::handleThreadInfo(const GdbResponse &response)
             response.data.findChild("current-thread-id").data().toInt();
         threadsHandler()->setCurrentThreadId(currentThreadId);
         plugin()->updateState(this); // Adjust Threads combobox.
+        postCommand("threadnames " + theDebuggerAction(MaximalStackDepth)->value().toByteArray(), CB(handleThreadNames), id);
     } else {
         // Fall back for older versions: Try to get at least a list
         // of running threads.
@@ -2986,6 +2987,31 @@ void GdbEngine::handleThreadListIds(const GdbResponse &response)
     threadsHandler()->setCurrentThreadId(id);
 }
 
+void GdbEngine::handleThreadNames(const GdbResponse &response)
+{
+    if (response.resultClass == GdbResultDone) {
+        GdbMi contents = response.data.findChild("consolestreamoutput");
+        GdbMi names;
+        names.fromString(contents.data());
+
+        Threads threads = threadsHandler()->threads();
+
+        foreach (const GdbMi &name, names.children()) {
+            int id = name.findChild("id").data().toInt();
+            for (int index = 0, n = threads.size(); index != n; ++index) {
+                ThreadData & thread = threads[index];
+                if (thread.id == id) {
+                    thread.name = decodeData(name.findChild("value").data(), name.findChild("valueencoded").data().toInt());
+                    break;
+                }
+            }
+        }
+        threadsHandler()->setThreads(threads);
+        plugin()->updateState(this);
+    }
+
+}
+
 
 //////////////////////////////////////////////////////////////////////
 //
diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h
index 7ddff2918ab0be209d54b2f9f8dfa597a41c0e80..1fa5825f50fe821148059d7a5dab79acae14aae0 100644
--- a/src/plugins/debugger/gdb/gdbengine.h
+++ b/src/plugins/debugger/gdb/gdbengine.h
@@ -435,6 +435,7 @@ private: ////////// View & Data Stuff //////////
     void handleStackSelectFrame(const GdbResponse &response);
     void handleThreadListIds(const GdbResponse &response);
     void handleThreadInfo(const GdbResponse &response);
+    void handleThreadNames(const GdbResponse &response);
     Q_SLOT void reloadStack(bool forceGotoLocation);
     Q_SLOT virtual void reloadFullStack();
     int currentFrame() const;
diff --git a/src/plugins/debugger/threadshandler.cpp b/src/plugins/debugger/threadshandler.cpp
index 9092e099a4ae9d1a8f16328eac667806398a886e..f8a07920b9b307da97d771b6497eea9e2cc7c04e 100644
--- a/src/plugins/debugger/threadshandler.cpp
+++ b/src/plugins/debugger/threadshandler.cpp
@@ -149,6 +149,10 @@ QVariant ThreadsHandler::data(const QModelIndex &index, int role) const
             return thread.core;
         case ThreadData::StateColumn:
             return thread.state;
+        case ThreadData::NameColumn:
+            if (thread.name.isEmpty())
+                return thread.id;
+            return thread.name;
         }
     case Qt::ToolTipRole:
         return threadToolTip(thread);
@@ -183,6 +187,8 @@ QVariant ThreadsHandler::headerData
         return tr("Core");
     case ThreadData::StateColumn:
         return tr("State");
+    case ThreadData::NameColumn:
+        return tr("Name");
     }
     return QVariant();
 }
diff --git a/src/plugins/debugger/threadshandler.h b/src/plugins/debugger/threadshandler.h
index 6815dafc1aeda0d575d162e16a5da002969276cf..5dfb6046c218a0b08f3336148d78f5e74de51d29 100644
--- a/src/plugins/debugger/threadshandler.h
+++ b/src/plugins/debugger/threadshandler.h
@@ -59,6 +59,7 @@ struct ThreadData
         FileColumn,
         LineColumn,
         StateColumn,
+        NameColumn,
         CoreColumn,
         ColumnCount = CoreColumn
     };
@@ -77,6 +78,7 @@ struct ThreadData
     QString fileName;
     QString state;
     int lineNumber;
+    QString name;
 };
 
 typedef QVector<ThreadData> Threads;
diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp
index 435deb9e13187284ae24e22635f504ceb1c590e9..f4a1a6059d47e2ee7a8821a081bdd30081f1d2bc 100644
--- a/src/plugins/debugger/watchutils.cpp
+++ b/src/plugins/debugger/watchutils.cpp
@@ -716,6 +716,12 @@ QString decodeData(const QByteArray &ba, int encoding)
             return doubleQuote + QString::fromUtf16(reinterpret_cast<const ushort *>
                 (decodedBa.data()), decodedBa.size() / 2) + doubleQuote;
         }
+        case 12: { //  %04x encoded 16 bit data, Little Endian, without quotes (see 7)
+            const QByteArray decodedBa = QByteArray::fromHex(ba);
+            //qDebug() << quoteUnprintableLatin1(decodedBa) << "\n\n";
+            return QString::fromUtf16(reinterpret_cast<const ushort *>
+                (decodedBa.data()), decodedBa.size() / 2);
+        }
     }
     qDebug() << "ENCODING ERROR: " << encoding;
     return QCoreApplication::translate("Debugger", "<Encoding error>");