Display thread names

extract thread names from QThread object name

Task-Number: QTCREATORBUG-382
Reviewed-by: hjk
parent f7b19f81
......@@ -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()
......@@ -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)
......
......@@ -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);
}
}
//////////////////////////////////////////////////////////////////////
//
......
......@@ -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;
......
......@@ -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();
}
......
......@@ -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;
......
......@@ -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>");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment