Merge pull request #3278 from foralost/3051_Switch__to_thread_handles
#3051: Follow a thread from handles window
This commit is contained in:
commit
b683fc6a59
|
@ -10,55 +10,21 @@
|
|||
|
||||
bool cbShowThreadId(int argc, char* argv[])
|
||||
{
|
||||
duint threadID = 0;
|
||||
|
||||
if(argc > 2)
|
||||
if(argc > 1)
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Too many arguments specified. Only 1 argument can be passed, or none.\n"));
|
||||
duint threadId = 0;
|
||||
if(!valfromstring(argv[1], &threadId, false))
|
||||
return false;
|
||||
}
|
||||
else if(argc == 2)
|
||||
|
||||
SELECTIONDATA newSelection = { threadId, threadId };
|
||||
if(!GuiSelectionSet(GUI_THREADS, &newSelection))
|
||||
{
|
||||
threadID = strtoll(argv[1], NULL, 10);
|
||||
if(threadID == 0)
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not search for thread ID 0 or argument was not a number in decimal base.\n"));
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Invalid thread %s\n"), formatpidtid((DWORD)threadId).c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if(argc == 1)
|
||||
{
|
||||
GuiShowThreads();
|
||||
return true;
|
||||
}
|
||||
|
||||
THREADLIST threads_head{};
|
||||
DbgGetThreadList(&threads_head);
|
||||
GuiUpdateThreadView(); // To be sure that we have the freshest stuff
|
||||
|
||||
bool threadFound = false;
|
||||
uint32_t row;
|
||||
for(row = 0; row < threads_head.count; row++)
|
||||
{
|
||||
THREADALLINFO currThread = threads_head.list[row];
|
||||
if(currThread.BasicInfo.ThreadId == threadID)
|
||||
{
|
||||
threadFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BridgeFree(threads_head.list);
|
||||
if(!threadFound)
|
||||
{
|
||||
dprintf(QT_TRANSLATE_NOOP("DBG", "Could not find provided thread ID: %llu\n"), threadID);
|
||||
return false;
|
||||
}
|
||||
|
||||
SELECTIONDATA foundThreadGUIRow{row, row};
|
||||
|
||||
GuiShowThreads();
|
||||
GuiSelectionSet(GUI_THREADS, &foundThreadGUIRow);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ public:
|
|||
void deleteAllColumns() override;
|
||||
|
||||
virtual QString getCellContent(duint row, duint column) = 0;
|
||||
virtual duint getCellUserdata(duint row, duint column) = 0;
|
||||
virtual bool isValidIndex(duint row, duint column) = 0;
|
||||
virtual void sortRows(duint column, bool ascending) = 0;
|
||||
|
||||
|
|
|
@ -182,7 +182,7 @@ void ReferenceView::addColumnAtRef(int width, QString title)
|
|||
StdSearchListView::addColumnAt(width, title, true);
|
||||
}
|
||||
|
||||
void ReferenceView::setRowCount(dsint count)
|
||||
void ReferenceView::setRowCount(duint count)
|
||||
{
|
||||
if(!stdList()->getRowCount() && count) //from zero to N rows
|
||||
searchSelectionChanged(0);
|
||||
|
|
|
@ -21,7 +21,7 @@ public:
|
|||
public slots:
|
||||
void addColumnAtRef(int width, QString title);
|
||||
|
||||
void setRowCount(dsint count) override;
|
||||
void setRowCount(duint count) override;
|
||||
|
||||
void setSingleSelection(int index, bool scroll);
|
||||
void addCommand(QString title, QString command);
|
||||
|
|
|
@ -57,16 +57,22 @@ void StdSearchListView::loadColumnFromConfig(const QString & viewName)
|
|||
stdSearchList()->loadColumnFromConfig(viewName);
|
||||
}
|
||||
|
||||
void StdSearchListView::setRowCount(dsint count)
|
||||
void StdSearchListView::setRowCount(duint count)
|
||||
{
|
||||
//clearFilter();
|
||||
stdList()->setRowCount(count);
|
||||
}
|
||||
|
||||
void StdSearchListView::setCellContent(int r, int c, QString s)
|
||||
void StdSearchListView::setCellContent(duint row, duint column, QString s)
|
||||
{
|
||||
//clearFilter();
|
||||
stdList()->setCellContent(r, c, s);
|
||||
stdList()->setCellContent(row, column, s);
|
||||
}
|
||||
|
||||
void StdSearchListView::setCellUserdata(duint row, duint column, duint userdata)
|
||||
{
|
||||
//clearFilter();
|
||||
stdList()->setCellUserdata(row, column, userdata);
|
||||
}
|
||||
|
||||
void StdSearchListView::reloadData()
|
||||
|
|
|
@ -18,12 +18,13 @@ public:
|
|||
void enableMultiSelection(bool enabled);
|
||||
void setAddressColumn(int col, bool cipBase = false);
|
||||
void loadColumnFromConfig(const QString & viewName);
|
||||
virtual void setRowCount(duint count);
|
||||
void setCellContent(duint row, duint column, QString s);
|
||||
void setCellUserdata(duint row, duint column, duint userdata);
|
||||
void setSearchStartCol(duint column);
|
||||
|
||||
public slots:
|
||||
virtual void setRowCount(dsint count);
|
||||
void setCellContent(int r, int c, QString s);
|
||||
void reloadData();
|
||||
void setSearchStartCol(duint col);
|
||||
|
||||
private:
|
||||
StdTableSearchList* mSearchListData;
|
||||
|
|
|
@ -25,7 +25,7 @@ public:
|
|||
void setCellContent(duint r, duint c, QString s, duint userdata);
|
||||
QString getCellContent(duint r, duint c) override;
|
||||
void setCellUserdata(duint r, duint c, duint userdata);
|
||||
duint getCellUserdata(duint r, duint c);
|
||||
duint getCellUserdata(duint r, duint c) override;
|
||||
bool isValidIndex(duint r, duint c) override;
|
||||
void sortRows(duint column, bool ascending) override;
|
||||
|
||||
|
|
|
@ -688,6 +688,9 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
|
|||
case GUI_SYMMOD:
|
||||
emit selectionSymmodGet(selection);
|
||||
break;
|
||||
case GUI_THREADS:
|
||||
emit selectionThreadsGet(selection);
|
||||
break;
|
||||
default:
|
||||
return (void*)false;
|
||||
}
|
||||
|
|
|
@ -130,6 +130,7 @@ signals:
|
|||
void selectionMemmapGet(SELECTIONDATA* selection);
|
||||
void selectionMemmapSet(const SELECTIONDATA* selection);
|
||||
void selectionSymmodGet(SELECTIONDATA* selection);
|
||||
void selectionThreadsGet(SELECTIONDATA* selection);
|
||||
void selectionThreadsSet(const SELECTIONDATA* selection);
|
||||
void getStrWindow(const QString title, QString* text);
|
||||
void autoCompleteAddCmd(const QString cmd);
|
||||
|
|
|
@ -71,13 +71,13 @@ void CallStackView::setupContextMenu()
|
|||
});
|
||||
|
||||
mMenuBuilder->addSeparator();
|
||||
QAction* followInThreads = makeAction(tr("Follow in Threads"), SLOT(followInThreadsSlot()));
|
||||
QAction* followInThreads = makeAction(DIcon("arrow-threads"), tr("Follow in Threads"), SLOT(followInThreadsSlot()));
|
||||
mMenuBuilder->addAction(followInThreads, [this](QMenu*)
|
||||
{
|
||||
return isThreadHeaderSelected();
|
||||
});
|
||||
|
||||
QAction* renameThread = makeAction(tr("Rename Thread"), SLOT(renameThreadSlot()));
|
||||
QAction* renameThread = makeAction(DIcon("thread-setname"), tr("Rename Thread"), SLOT(renameThreadSlot()));
|
||||
mMenuBuilder->addAction(renameThread, [this](QMenu*)
|
||||
{
|
||||
return isThreadHeaderSelected();
|
||||
|
@ -162,7 +162,6 @@ void CallStackView::updateCallStackSlot()
|
|||
DbgFunctions()->GetCallStackByThread(threadList.list[currentIndexToDraw].BasicInfo.Handle, &callstack);
|
||||
setRowCount(currentRow + callstack.total + 1);
|
||||
auto threadId = threadList.list[currentIndexToDraw].BasicInfo.ThreadId;
|
||||
setCellContent(currentRow, ColThread, ToDecString(threadId));
|
||||
|
||||
QString threadName = threadList.list[currentIndexToDraw].BasicInfo.threadName;
|
||||
QString colThreadString = ToDecString(threadList.list[currentIndexToDraw].BasicInfo.ThreadId);
|
||||
|
@ -265,6 +264,7 @@ void CallStackView::renameThreadSlot()
|
|||
|
||||
DbgCmdExec(QString("setthreadname %1, \"%2\"").arg(ToHexString(threadId)).arg(DbgCmdEscape(threadName)));
|
||||
}
|
||||
|
||||
void CallStackView::followInThreadsSlot()
|
||||
{
|
||||
QStringList threadIDName = getCellContent(getInitialSelection(), ColThread).split(" - ");
|
||||
|
|
|
@ -47,7 +47,7 @@ HandlesView::HandlesView(QWidget* parent) : QWidget(parent)
|
|||
mWindowsTable->addColumnAt(8 + 16 * charWidth, tr("StyleEx"), true, "", StdTable::SortBy::AsHex);
|
||||
mWindowsTable->addColumnAt(8 + 8 * charWidth, tr("Parent"), true);
|
||||
mWindowsTable->addColumnAt(8 + 20 * charWidth, tr("Size"), true);
|
||||
mWindowsTable->addColumnAt(8 + 6 * charWidth, tr("Enable"), true);
|
||||
mWindowsTable->addColumnAt(8 + 8 * charWidth, tr("Enable"), true);
|
||||
mWindowsTable->loadColumnFromConfig("Window");
|
||||
mWindowsTable->setIconColumn(2);
|
||||
|
||||
|
@ -118,6 +118,8 @@ HandlesView::HandlesView(QWidget* parent) : QWidget(parent)
|
|||
mActionFollowProc = new QAction(DIcon(ArchValue("processor32", "processor64")), tr("Follow Proc in Disassembler"), this);
|
||||
connect(mActionFollowProc, SIGNAL(triggered()), this, SLOT(followInDisasmSlot()));
|
||||
mActionFollowProc->setShortcut(Qt::Key_Return);
|
||||
mActionFollowThread = new QAction(DIcon("arrow-threads"), tr("Follow in Threads"), this);
|
||||
connect(mActionFollowThread, SIGNAL(triggered()), this, SLOT(followInThreads()));
|
||||
mWindowsTable->addAction(mActionFollowProc);
|
||||
mActionToggleProcBP = new QAction(DIcon("breakpoint_toggle"), tr("Toggle Breakpoint in Proc"), this);
|
||||
connect(mActionToggleProcBP, SIGNAL(triggered()), this, SLOT(toggleBPSlot()));
|
||||
|
@ -221,6 +223,7 @@ void HandlesView::windowsTableContextMenuSlot(QMenu* menu)
|
|||
}
|
||||
|
||||
menu->addAction(mActionFollowProc);
|
||||
menu->addAction(mActionFollowThread);
|
||||
menu->addAction(mActionToggleProcBP);
|
||||
menu->addAction(mActionMessageProcBP);
|
||||
}
|
||||
|
@ -325,6 +328,12 @@ void HandlesView::followInDisasmSlot()
|
|||
DbgCmdExec(QString("disasm %1").arg(mWindowsTable->mCurList->getCellContent(mWindowsTable->mCurList->getInitialSelection(), 0)));
|
||||
}
|
||||
|
||||
void HandlesView::followInThreads()
|
||||
{
|
||||
auto threadId = mWindowsTable->mCurList->getCellUserdata(mWindowsTable->mCurList->getInitialSelection(), 4);
|
||||
DbgCmdExec(QString("showthreadid %1").arg(ToHexString(threadId)));
|
||||
}
|
||||
|
||||
void HandlesView::toggleBPSlot()
|
||||
{
|
||||
auto & mCurList = *mWindowsTable->mCurList;
|
||||
|
@ -435,13 +444,13 @@ void HandlesView::enumWindows()
|
|||
mWindowsTable->setCellContent(i, 1, ToHexString(windows[i].handle));
|
||||
mWindowsTable->setCellContent(i, 2, QString(windows[i].windowTitle));
|
||||
mWindowsTable->setCellContent(i, 3, QString(windows[i].windowClass));
|
||||
char threadname[MAX_THREAD_NAME_SIZE];
|
||||
if(DbgFunctions()->ThreadGetName(windows[i].threadId, threadname) && *threadname != '\0')
|
||||
mWindowsTable->setCellContent(i, 4, QString::fromUtf8(threadname));
|
||||
else if(Config()->getBool("Gui", "PidTidInHex"))
|
||||
mWindowsTable->setCellContent(i, 4, ToHexString(windows[i].threadId));
|
||||
auto tidStr = QString().sprintf(Config()->getBool("Gui", "PidTidInHex") ? "%X" : "%u", windows[i].threadId);
|
||||
char threadName[MAX_THREAD_NAME_SIZE];
|
||||
if(DbgFunctions()->ThreadGetName(windows[i].threadId, threadName) && *threadName != '\0')
|
||||
mWindowsTable->setCellContent(i, 4, QString::fromUtf8(threadName) + QString(" (%1)").arg(tidStr));
|
||||
else
|
||||
mWindowsTable->setCellContent(i, 4, QString::number(windows[i].threadId));
|
||||
mWindowsTable->setCellContent(i, 4, tidStr);
|
||||
mWindowsTable->setCellUserdata(i, 4, windows[i].threadId);
|
||||
//Style
|
||||
mWindowsTable->setCellContent(i, 5, ToHexString(windows[i].style));
|
||||
//StyleEx
|
||||
|
|
|
@ -35,6 +35,7 @@ public slots:
|
|||
void enableWindowSlot();
|
||||
void disableWindowSlot();
|
||||
void followInDisasmSlot();
|
||||
void followInThreads();
|
||||
void toggleBPSlot();
|
||||
void messagesBPSlot();
|
||||
|
||||
|
@ -56,6 +57,7 @@ private:
|
|||
QAction* mActionEnableWindow;
|
||||
QAction* mActionDisableWindow;
|
||||
QAction* mActionFollowProc;
|
||||
QAction* mActionFollowThread;
|
||||
QAction* mActionToggleProcBP;
|
||||
QAction* mActionMessageProcBP;
|
||||
|
||||
|
|
|
@ -41,12 +41,12 @@ SourceView::~SourceView()
|
|||
clear();
|
||||
}
|
||||
|
||||
QString SourceView::getCellContent(duint r, duint c)
|
||||
QString SourceView::getCellContent(duint row, duint column)
|
||||
{
|
||||
if(!isValidIndex(r, c))
|
||||
if(!isValidIndex(row, column))
|
||||
return QString();
|
||||
LineData & line = mLines.at(r - mPrepareTableOffset);
|
||||
switch(c)
|
||||
LineData & line = mLines.at(row - mPrepareTableOffset);
|
||||
switch(column)
|
||||
{
|
||||
case ColAddr:
|
||||
return line.addr ? ToPtrString(line.addr) : QString();
|
||||
|
@ -59,13 +59,29 @@ QString SourceView::getCellContent(duint r, duint c)
|
|||
return "INVALID";
|
||||
}
|
||||
|
||||
bool SourceView::isValidIndex(duint r, duint c)
|
||||
duint SourceView::getCellUserdata(duint row, duint column)
|
||||
{
|
||||
if(!isValidIndex(row, column))
|
||||
return 0;
|
||||
LineData & line = mLines.at(row - mPrepareTableOffset);
|
||||
switch(column)
|
||||
{
|
||||
case ColAddr:
|
||||
return line.addr;
|
||||
case ColLine:
|
||||
return line.index + 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool SourceView::isValidIndex(duint row, duint column)
|
||||
{
|
||||
if(!mFileLines)
|
||||
return false;
|
||||
if(c < ColAddr || c > ColCode)
|
||||
if(column < ColAddr || column > ColCode)
|
||||
return false;
|
||||
return r >= 0 && size_t(r) < mFileLines->size();
|
||||
return row >= 0 && size_t(row) < mFileLines->size();
|
||||
}
|
||||
|
||||
void SourceView::sortRows(duint column, bool ascending)
|
||||
|
|
|
@ -13,8 +13,9 @@ public:
|
|||
SourceView(QString path, duint addr, QWidget* parent = nullptr);
|
||||
~SourceView();
|
||||
|
||||
QString getCellContent(duint r, duint c) override;
|
||||
bool isValidIndex(duint r, duint c) override;
|
||||
QString getCellContent(duint row, duint column) override;
|
||||
duint getCellUserdata(duint row, duint column) override;
|
||||
bool isValidIndex(duint row, duint column) override;
|
||||
void sortRows(duint column, bool ascending) override;
|
||||
void prepareData() override;
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ void ThreadView::contextMenuSlot(const QPoint & pos)
|
|||
|
||||
void ThreadView::gotoThreadEntrySlot()
|
||||
{
|
||||
QString addrText = getCellContent(getInitialSelection(), 2);
|
||||
QString addrText = getCellContent(getInitialSelection(), ColEntry);
|
||||
DbgCmdExecDirect(QString("disasm " + addrText));
|
||||
}
|
||||
|
||||
|
@ -167,6 +167,7 @@ ThreadView::ThreadView(StdTable* parent) : StdTable(parent)
|
|||
|
||||
//setCopyMenuOnly(true);
|
||||
connect(Bridge::getBridge(), SIGNAL(selectionThreadsSet(const SELECTIONDATA*)), this, SLOT(selectionThreadsSet(const SELECTIONDATA*)));
|
||||
connect(Bridge::getBridge(), SIGNAL(selectionThreadsGet(SELECTIONDATA*)), this, SLOT(selectionThreadsGet(SELECTIONDATA*)));
|
||||
connect(Bridge::getBridge(), SIGNAL(updateThreads()), this, SLOT(updateThreadListSlot()));
|
||||
connect(this, SIGNAL(doubleClickedSignal()), this, SLOT(doubleClickedSlot()));
|
||||
connect(this, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(contextMenuSlot(QPoint)));
|
||||
|
@ -178,19 +179,27 @@ ThreadView::ThreadView(StdTable* parent) : StdTable(parent)
|
|||
|
||||
void ThreadView::selectionThreadsSet(const SELECTIONDATA* selection)
|
||||
{
|
||||
if(selection->start >= getRowCount() ||
|
||||
selection->end >= getRowCount() ||
|
||||
selection->start > selection->end)
|
||||
auto selectedThreadId = selection->start;
|
||||
auto rowCount = getRowCount();
|
||||
for(duint row = 0; row < rowCount; row++)
|
||||
{
|
||||
Bridge::getBridge()->setResult(BridgeResult::SelectionSet, 0);
|
||||
auto threadId = getCellUserdata(row, ColThreadId);
|
||||
if(threadId == selectedThreadId)
|
||||
{
|
||||
setSingleSelection(row);
|
||||
Bridge::getBridge()->setResult(BridgeResult::SelectionSet, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mSelection.firstSelectedIndex = selection->start;
|
||||
mSelection.fromIndex = selection->start;
|
||||
mSelection.toIndex = selection->end;
|
||||
Bridge::getBridge()->setResult(BridgeResult::SelectionSet, 1);
|
||||
emit selectionChanged(mSelection.firstSelectedIndex);
|
||||
Bridge::getBridge()->setResult(BridgeResult::SelectionSet, 0);
|
||||
}
|
||||
|
||||
void ThreadView::selectionThreadsGet(SELECTIONDATA* selection)
|
||||
{
|
||||
auto threadId = getCellUserdata(getInitialSelection(), ColThreadId);
|
||||
selection->start = selection->end = threadId;
|
||||
Bridge::getBridge()->setResult(BridgeResult::SelectionGet, 1);
|
||||
}
|
||||
|
||||
void ThreadView::updateThreadListSlot()
|
||||
|
@ -203,15 +212,15 @@ void ThreadView::updateThreadListSlot()
|
|||
for(int i = 0; i < threadList.count; i++)
|
||||
{
|
||||
if(!threadList.list[i].BasicInfo.ThreadNumber)
|
||||
setCellContent(i, 0, tr("Main"));
|
||||
setCellContent(i, ColNumber, tr("Main"));
|
||||
else
|
||||
setCellContent(i, 0, ToDecString(threadList.list[i].BasicInfo.ThreadNumber));
|
||||
setCellContent(i, 1, QString().sprintf(tidFormat, threadList.list[i].BasicInfo.ThreadId));
|
||||
setCellUserdata(i, 1, threadList.list[i].BasicInfo.ThreadId);
|
||||
setCellContent(i, 2, ToPtrString(threadList.list[i].BasicInfo.ThreadStartAddress));
|
||||
setCellContent(i, 3, ToPtrString(threadList.list[i].BasicInfo.ThreadLocalBase));
|
||||
setCellContent(i, 4, ToPtrString(threadList.list[i].ThreadCip));
|
||||
setCellContent(i, 5, ToDecString(threadList.list[i].SuspendCount));
|
||||
setCellContent(i, ColNumber, ToDecString(threadList.list[i].BasicInfo.ThreadNumber));
|
||||
setCellContent(i, ColThreadId, QString().sprintf(tidFormat, threadList.list[i].BasicInfo.ThreadId));
|
||||
setCellUserdata(i, ColThreadId, threadList.list[i].BasicInfo.ThreadId);
|
||||
setCellContent(i, ColEntry, ToPtrString(threadList.list[i].BasicInfo.ThreadStartAddress));
|
||||
setCellContent(i, ColTeb, ToPtrString(threadList.list[i].BasicInfo.ThreadLocalBase));
|
||||
setCellContent(i, ColCip, ToPtrString(threadList.list[i].ThreadCip));
|
||||
setCellContent(i, ColSuspendCount, ToDecString(threadList.list[i].SuspendCount));
|
||||
QString priorityString;
|
||||
switch(threadList.list[i].Priority)
|
||||
{
|
||||
|
@ -240,7 +249,7 @@ void ThreadView::updateThreadListSlot()
|
|||
priorityString = tr("Unknown");
|
||||
break;
|
||||
}
|
||||
setCellContent(i, 6, priorityString);
|
||||
setCellContent(i, ColPriority, priorityString);
|
||||
QString waitReasonString;
|
||||
switch(threadList.list[i].WaitReason)
|
||||
{
|
||||
|
@ -359,13 +368,13 @@ void ThreadView::updateThreadListSlot()
|
|||
waitReasonString = "Unknown";
|
||||
break;
|
||||
}
|
||||
setCellContent(i, 7, waitReasonString);
|
||||
setCellContent(i, 8, QString("%1").arg(threadList.list[i].LastError, sizeof(unsigned int) * 2, 16, QChar('0')).toUpper());
|
||||
setCellContent(i, 9, FILETIMEToTime(threadList.list[i].UserTime));
|
||||
setCellContent(i, 10, FILETIMEToTime(threadList.list[i].KernelTime));
|
||||
setCellContent(i, 11, FILETIMEToDate(threadList.list[i].CreationTime));
|
||||
setCellContent(i, 12, ToLongLongHexString(threadList.list[i].Cycles));
|
||||
setCellContent(i, 13, threadList.list[i].BasicInfo.threadName);
|
||||
setCellContent(i, ColWaitReason, waitReasonString);
|
||||
setCellContent(i, ColLastError, QString("%1").arg(threadList.list[i].LastError, sizeof(unsigned int) * 2, 16, QChar('0')).toUpper());
|
||||
setCellContent(i, ColUserTime, FILETIMEToTime(threadList.list[i].UserTime));
|
||||
setCellContent(i, ColKernelTime, FILETIMEToTime(threadList.list[i].KernelTime));
|
||||
setCellContent(i, ColCreationTime, FILETIMEToDate(threadList.list[i].CreationTime));
|
||||
setCellContent(i, ColCpuCycles, ToLongLongHexString(threadList.list[i].Cycles));
|
||||
setCellContent(i, ColThreadName, threadList.list[i].BasicInfo.threadName);
|
||||
}
|
||||
mCurrentThreadId = -1;
|
||||
if(threadList.count)
|
||||
|
@ -381,7 +390,7 @@ void ThreadView::updateThreadListSlot()
|
|||
QString ThreadView::paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h)
|
||||
{
|
||||
QString ret = StdTable::paintContent(painter, row, col, x, y, w, h);
|
||||
duint threadId = getCellUserdata(row, 1);
|
||||
duint threadId = getCellUserdata(row, ColThreadId);
|
||||
if(threadId == mCurrentThreadId && !col)
|
||||
{
|
||||
painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("ThreadCurrentBackgroundColor")));
|
||||
|
@ -394,17 +403,17 @@ QString ThreadView::paintContent(QPainter* painter, duint row, duint col, int x,
|
|||
|
||||
void ThreadView::doubleClickedSlot()
|
||||
{
|
||||
duint threadId = getCellUserdata(getInitialSelection(), 1);
|
||||
duint threadId = getCellUserdata(getInitialSelection(), ColThreadId);
|
||||
DbgCmdExecDirect("switchthread " + ToHexString(threadId));
|
||||
|
||||
QString addrText = getCellContent(getInitialSelection(), 4);
|
||||
QString addrText = getCellContent(getInitialSelection(), ColCip);
|
||||
DbgCmdExec("disasm " + addrText);
|
||||
}
|
||||
|
||||
void ThreadView::setNameSlot()
|
||||
{
|
||||
duint threadId = getCellUserdata(getInitialSelection(), 1);
|
||||
QString threadName = getCellContent(getInitialSelection(), 13);
|
||||
duint threadId = getCellUserdata(getInitialSelection(), ColThreadId);
|
||||
QString threadName = getCellContent(getInitialSelection(), ColThreadName);
|
||||
if(!SimpleInputBox(this, tr("Thread name - %1").arg(threadId), threadName, threadName, QString()))
|
||||
return;
|
||||
|
||||
|
|
|
@ -10,11 +10,13 @@ public:
|
|||
explicit ThreadView(StdTable* parent = nullptr);
|
||||
QString paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h) override;
|
||||
void setupContextMenu();
|
||||
|
||||
signals:
|
||||
void displayThreadsView();
|
||||
|
||||
public slots:
|
||||
void selectionThreadsSet(const SELECTIONDATA* selection);
|
||||
void selectionThreadsGet(SELECTIONDATA* selection);
|
||||
void updateThreadListSlot();
|
||||
void doubleClickedSlot();
|
||||
void execCommandSlot();
|
||||
|
@ -26,4 +28,22 @@ private:
|
|||
QAction* makeCommandAction(QAction* action, const QString & command);
|
||||
duint mCurrentThreadId;
|
||||
MenuBuilder* mMenuBuilder;
|
||||
|
||||
enum
|
||||
{
|
||||
ColNumber = 0,
|
||||
ColThreadId,
|
||||
ColEntry,
|
||||
ColTeb,
|
||||
ColCip,
|
||||
ColSuspendCount,
|
||||
ColPriority,
|
||||
ColWaitReason,
|
||||
ColLastError,
|
||||
ColUserTime,
|
||||
ColKernelTime,
|
||||
ColCreationTime,
|
||||
ColCpuCycles,
|
||||
ColThreadName,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -56,20 +56,40 @@ ZehSymbolTable::ZehSymbolTable(QWidget* parent)
|
|||
Initialize();
|
||||
}
|
||||
|
||||
QString ZehSymbolTable::getCellContent(duint r, duint c)
|
||||
QString ZehSymbolTable::getCellContent(duint row, duint column)
|
||||
{
|
||||
QMutexLocker lock(&mMutex);
|
||||
if(!isValidIndex(r, c))
|
||||
if(!isValidIndex(row, column))
|
||||
return QString();
|
||||
SymbolInfoWrapper info;
|
||||
DbgGetSymbolInfo(&mData.at(r), info.put());
|
||||
return symbolInfoString(info.get(), c);
|
||||
DbgGetSymbolInfo(&mData.at(row), info.put());
|
||||
return symbolInfoString(info.get(), column);
|
||||
}
|
||||
|
||||
bool ZehSymbolTable::isValidIndex(duint r, duint c)
|
||||
duint ZehSymbolTable::getCellUserdata(duint row, duint column)
|
||||
{
|
||||
QMutexLocker lock(&mMutex);
|
||||
return r >= 0 && r < (int)mData.size() && c >= 0 && c <= ColUndecorated;
|
||||
if(!isValidIndex(row, column))
|
||||
return 0;
|
||||
SymbolInfoWrapper info;
|
||||
DbgGetSymbolInfo(&mData.at(row), info.put());
|
||||
switch(column)
|
||||
{
|
||||
case ColAddr:
|
||||
return info->addr;
|
||||
case ColOrdinal:
|
||||
return info->ordinal;
|
||||
case ColType:
|
||||
return info->type;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool ZehSymbolTable::isValidIndex(duint row, duint column)
|
||||
{
|
||||
QMutexLocker lock(&mMutex);
|
||||
return row >= 0 && row < (int)mData.size() && column >= 0 && column <= ColUndecorated;
|
||||
}
|
||||
|
||||
void ZehSymbolTable::sortRows(duint column, bool ascending)
|
||||
|
|
|
@ -9,8 +9,9 @@ class ZehSymbolTable : public AbstractStdTable
|
|||
public:
|
||||
ZehSymbolTable(QWidget* parent = nullptr);
|
||||
|
||||
QString getCellContent(duint r, duint c) override;
|
||||
bool isValidIndex(duint r, duint c) override;
|
||||
QString getCellContent(duint row, duint column) override;
|
||||
duint getCellUserdata(duint row, duint column) override;
|
||||
bool isValidIndex(duint row, duint column) override;
|
||||
void sortRows(duint column, bool ascending) override;
|
||||
|
||||
friend class SymbolView;
|
||||
|
|
Loading…
Reference in New Issue