Commit 2a9233a0 authored by Friedemann Kleint's avatar Friedemann Kleint
Browse files

CDB: Provide thread frame information

parent 67155e3d
......@@ -1701,36 +1701,12 @@ ULONG CdbDebugEnginePrivate::updateThreadList()
if (debugCDB)
qDebug() << Q_FUNC_INFO << m_hDebuggeeProcess;
ThreadsHandler* th = manager()->threadsHandler();
QList<ThreadData> threads;
bool success = false;
ULONG currentThreadId;
QString errorMessage;
ULONG currentThreadId = 0;
do {
ULONG threadCount;
HRESULT hr= m_cif.debugSystemObjects->GetNumberThreads(&threadCount);
if (FAILED(hr)) {
errorMessage= msgComFailed("GetNumberThreads", hr);
break;
}
// Get ids and index of current
if (threadCount) {
m_cif.debugSystemObjects->GetCurrentThreadId(&currentThreadId);
QVector<ULONG> threadIds(threadCount);
hr = m_cif.debugSystemObjects->GetThreadIdsByIndex(0, threadCount, &(*threadIds.begin()), 0);
if (FAILED(hr)) {
errorMessage= msgComFailed("GetThreadIdsByIndex", hr);
break;
}
for (ULONG i = 0; i < threadCount; i++)
threads.push_back(ThreadData(threadIds.at(i)));
}
th->setThreads(threads);
success = true;
} while (false);
if (!success)
m_engine->warning(msgFunctionFailed(Q_FUNC_INFO, errorMessage));
if (!CdbStackTraceContext::getThreads(m_cif, true, &threads, &currentThreadId, &errorMessage))
m_engine->warning(errorMessage);
manager()->threadsHandler()->setThreads(threads);
return currentThreadId;
}
......
......@@ -219,5 +219,105 @@ void CdbStackTraceContext::format(QTextStream &str) const
}
}
// Thread state helper
static inline QString msgGetThreadStateFailed(unsigned long threadId, const QString &why)
{
return QString::fromLatin1("Unable to determine the state of thread %1: %2").arg(threadId).arg(why);
}
static inline bool getStoppedThreadState(const CdbComInterfaces &cif,
ThreadData *t,
QString *errorMessage)
{
ULONG currentThread;
HRESULT hr = cif.debugSystemObjects->GetCurrentThreadId(&currentThread);
if (FAILED(hr)) {
*errorMessage = msgGetThreadStateFailed(t->id, msgComFailed("GetCurrentThreadId", hr));
return false;
}
if (currentThread != t->id) {
hr = cif.debugSystemObjects->SetCurrentThreadId(t->id);
if (FAILED(hr)) {
*errorMessage = msgGetThreadStateFailed(t->id, msgComFailed("SetCurrentThreadId", hr));
return false;
}
}
ULONG frameCount;
DEBUG_STACK_FRAME topFrame[1];
hr = cif.debugControl->GetStackTrace(0, 0, 0, topFrame, 1, &frameCount);
if (FAILED(hr)) {
*errorMessage = msgGetThreadStateFailed(t->id, msgComFailed("GetStackTrace", hr));
return false;
}
t->address = topFrame[0].InstructionOffset;
WCHAR wszBuf[MAX_PATH];
cif.debugSymbols->GetNameByOffsetWide(topFrame[0].InstructionOffset, wszBuf, MAX_PATH, 0, 0);
t->function = QString::fromUtf16(reinterpret_cast<const ushort *>(wszBuf));
ULONG ulLine;
hr = cif.debugSymbols->GetLineByOffsetWide(topFrame[0].InstructionOffset, &ulLine, wszBuf, MAX_PATH, 0, 0);
if (SUCCEEDED(hr)) {
t->line = ulLine;
// Just display base name
t->file = QString::fromUtf16(reinterpret_cast<const ushort *>(wszBuf));
if (!t->file.isEmpty()) {
const int slashPos = t->file.lastIndexOf(QLatin1Char('\\'));
if (slashPos != -1)
t->file.remove(0, slashPos + 1);
}
}
return true;
}
static inline QString msgGetThreadsFailed(const QString &why)
{
return QString::fromLatin1("Unable to determine the thread information: %1").arg(why);
}
bool CdbStackTraceContext::getThreads(const CdbComInterfaces &cif,
bool isStopped,
QList<ThreadData> *threads,
ULONG *currentThreadId,
QString *errorMessage)
{
threads->clear();
ULONG threadCount;
*currentThreadId = 0;
HRESULT hr= cif.debugSystemObjects->GetNumberThreads(&threadCount);
if (FAILED(hr)) {
*errorMessage= msgGetThreadsFailed(msgComFailed("GetNumberThreads", hr));
return false;
}
// Get ids and index of current
if (!threadCount)
return true;
hr = cif.debugSystemObjects->GetCurrentThreadId(currentThreadId);
if (FAILED(hr)) {
*errorMessage= msgGetThreadsFailed(msgComFailed("GetCurrentThreadId", hr));
return false;
}
QVector<ULONG> threadIds(threadCount);
hr = cif.debugSystemObjects->GetThreadIdsByIndex(0, threadCount, &(*threadIds.begin()), 0);
if (FAILED(hr)) {
*errorMessage= msgGetThreadsFailed(msgComFailed("GetThreadIdsByIndex", hr));
return false;
}
for (ULONG i = 0; i < threadCount; i++) {
ThreadData threadData(threadIds.at(i));
if (isStopped) {
if (!getStoppedThreadState(cif, &threadData, errorMessage)) {
qWarning("%s\n", qPrintable(*errorMessage));
errorMessage->clear();
}
}
threads->push_back(threadData);
}
return true;
}
} // namespace Internal
} // namespace Debugger
......@@ -49,6 +49,7 @@ struct CdbComInterfaces;
class CdbSymbolGroupContext;
class CdbStackFrameContext;
class CdbDumperHelper;
struct ThreadData;
/* Context representing a break point stack consisting of several frames.
* Maintains an on-demand constructed list of CdbStackFrameContext
......@@ -81,6 +82,14 @@ public:
void format(QTextStream &str) const;
QString toString() const;
// Retrieve information about threads. When stopped, add
// current stack frame.
static bool getThreads(const CdbComInterfaces &cif,
bool isStopped,
QList<ThreadData> *threads,
ULONG *currentThreadId,
QString *errorMessage);
private:
bool init(unsigned long frameCount, QString *errorMessage);
CIDebugSymbolGroup *createSymbolGroup(int index, QString *errorMessage);
......
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