allow user to change thread name #980
This commit is contained in:
parent
e794d47015
commit
e47482dec8
|
@ -2015,6 +2015,36 @@ CMDRESULT cbDebugSetPriority(int argc, char* argv[])
|
||||||
return STATUS_CONTINUE;
|
return STATUS_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CMDRESULT cbDebugSetthreadname(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
if(argc < 2)
|
||||||
|
{
|
||||||
|
dputs("Not enough arguments!");
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
duint threadid;
|
||||||
|
if(!valfromstring(argv[1], &threadid, false))
|
||||||
|
return STATUS_ERROR;
|
||||||
|
THREADINFO info;
|
||||||
|
if(!ThreadGetInfo(DWORD(threadid), info))
|
||||||
|
{
|
||||||
|
dprintf("Invalid thread %X\n", threadid);
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
auto newname = argc > 2 ? argv[2] : "";
|
||||||
|
if(!ThreadSetName(DWORD(threadid), newname))
|
||||||
|
{
|
||||||
|
dprintf("Failed to change the name for thread %X\n", threadid);
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
if(!info.threadName)
|
||||||
|
dprintf("Thread name set to \"%s\"!\n", newname);
|
||||||
|
else
|
||||||
|
dprintf("Thread name changed from \"%s\" to \"%s\"!\n", info.threadName, newname);
|
||||||
|
GuiUpdateAllViews();
|
||||||
|
return STATUS_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
CMDRESULT cbDebugDownloadSymbol(int argc, char* argv[])
|
CMDRESULT cbDebugDownloadSymbol(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
dputs("This may take very long, depending on your network connection and data in the debug directory...");
|
dputs("This may take very long, depending on your network connection and data in the debug directory...");
|
||||||
|
|
|
@ -96,6 +96,7 @@ CMDRESULT cbDebugKillthread(int argc, char* argv[]);
|
||||||
CMDRESULT cbDebugSuspendAllThreads(int argc, char* argv[]);
|
CMDRESULT cbDebugSuspendAllThreads(int argc, char* argv[]);
|
||||||
CMDRESULT cbDebugResumeAllThreads(int argc, char* argv[]);
|
CMDRESULT cbDebugResumeAllThreads(int argc, char* argv[]);
|
||||||
CMDRESULT cbDebugSetPriority(int argc, char* argv[]);
|
CMDRESULT cbDebugSetPriority(int argc, char* argv[]);
|
||||||
|
CMDRESULT cbDebugSetthreadname(int argc, char* argv[]);
|
||||||
CMDRESULT cbDebugGetCmdline(int argc, char* argv[]);
|
CMDRESULT cbDebugGetCmdline(int argc, char* argv[]);
|
||||||
CMDRESULT cbDebugSetCmdline(int argc, char* argv[]);
|
CMDRESULT cbDebugSetCmdline(int argc, char* argv[]);
|
||||||
CMDRESULT cbDebugLoadLib(int argc, char* argv[]);
|
CMDRESULT cbDebugLoadLib(int argc, char* argv[]);
|
||||||
|
|
|
@ -139,6 +139,18 @@ void ThreadGetList(std::vector<THREADINFO> & list)
|
||||||
list.push_back(thread.second);
|
list.push_back(thread.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ThreadGetInfo(DWORD ThreadId, THREADINFO & info)
|
||||||
|
{
|
||||||
|
SHARED_ACQUIRE(LockThreads);
|
||||||
|
|
||||||
|
auto found = threadList.find(ThreadId);
|
||||||
|
if(found == threadList.end())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
info = found->second;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ThreadIsValid(DWORD ThreadId)
|
bool ThreadIsValid(DWORD ThreadId)
|
||||||
{
|
{
|
||||||
SHARED_ACQUIRE(LockThreads);
|
SHARED_ACQUIRE(LockThreads);
|
||||||
|
@ -221,7 +233,7 @@ bool ThreadSetName(DWORD ThreadId, const char* Name)
|
||||||
if(!Name)
|
if(!Name)
|
||||||
Name = "";
|
Name = "";
|
||||||
|
|
||||||
strcpy_s(threadList[ThreadId].threadName, Name);
|
strncpy_s(threadList[ThreadId].threadName, Name, _TRUNCATE);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ void ThreadClear();
|
||||||
int ThreadGetCount();
|
int ThreadGetCount();
|
||||||
void ThreadGetList(THREADLIST* list);
|
void ThreadGetList(THREADLIST* list);
|
||||||
void ThreadGetList(std::vector<THREADINFO> & list);
|
void ThreadGetList(std::vector<THREADINFO> & list);
|
||||||
|
bool ThreadGetInfo(DWORD ThreadId, THREADINFO & info);
|
||||||
bool ThreadIsValid(DWORD ThreadId);
|
bool ThreadIsValid(DWORD ThreadId);
|
||||||
bool ThreadSetName(DWORD ThreadId, const char* name);
|
bool ThreadSetName(DWORD ThreadId, const char* name);
|
||||||
bool ThreadGetTib(duint TEBAddress, NT_TIB* Tib);
|
bool ThreadGetTib(duint TEBAddress, NT_TIB* Tib);
|
||||||
|
|
|
@ -112,6 +112,7 @@ static void registercommands()
|
||||||
dbgcmdnew("suspendallthreads\1threadsuspendall", cbDebugSuspendAllThreads, true); //suspend all threads
|
dbgcmdnew("suspendallthreads\1threadsuspendall", cbDebugSuspendAllThreads, true); //suspend all threads
|
||||||
dbgcmdnew("resumeallthreads\1threadresumeall", cbDebugResumeAllThreads, true); //resume all threads
|
dbgcmdnew("resumeallthreads\1threadresumeall", cbDebugResumeAllThreads, true); //resume all threads
|
||||||
dbgcmdnew("setthreadpriority\1setprioritythread\1threadsetpriority", cbDebugSetPriority, true); //set thread priority
|
dbgcmdnew("setthreadpriority\1setprioritythread\1threadsetpriority", cbDebugSetPriority, true); //set thread priority
|
||||||
|
dbgcmdnew("threadsetname\1setthreadname", cbDebugSetthreadname, true); //set thread name
|
||||||
dbgcmdnew("symdownload\1downloadsym", cbDebugDownloadSymbol, true); //download symbols
|
dbgcmdnew("symdownload\1downloadsym", cbDebugDownloadSymbol, true); //download symbols
|
||||||
dbgcmdnew("getcmdline\1getcommandline", cbDebugGetCmdline, true); //Get CmdLine
|
dbgcmdnew("getcmdline\1getcommandline", cbDebugGetCmdline, true); //Get CmdLine
|
||||||
dbgcmdnew("setcmdline\1setcommandline", cbDebugSetCmdline, true); //Set CmdLine
|
dbgcmdnew("setcmdline\1setcommandline", cbDebugSetCmdline, true); //Set CmdLine
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
#include "Bridge.h"
|
#include "Bridge.h"
|
||||||
#include "StringUtil.h"
|
#include "StringUtil.h"
|
||||||
|
#include "LineEditDialog.h"
|
||||||
|
|
||||||
void ThreadView::contextMenuSlot(const QPoint & pos)
|
void ThreadView::contextMenuSlot(const QPoint & pos)
|
||||||
{
|
{
|
||||||
|
@ -14,6 +15,7 @@ void ThreadView::contextMenuSlot(const QPoint & pos)
|
||||||
wMenu.addAction(mResumeThread);
|
wMenu.addAction(mResumeThread);
|
||||||
wMenu.addAction(mKillThread);
|
wMenu.addAction(mKillThread);
|
||||||
wMenu.addSeparator();
|
wMenu.addSeparator();
|
||||||
|
wMenu.addAction(mSetName);
|
||||||
wMenu.addMenu(mSetPriority);
|
wMenu.addMenu(mSetPriority);
|
||||||
bool ok;
|
bool ok;
|
||||||
ULONGLONG entry = getCellContent(getInitialSelection(), 2).toULongLong(&ok, 16);
|
ULONGLONG entry = getCellContent(getInitialSelection(), 2).toULongLong(&ok, 16);
|
||||||
|
@ -184,6 +186,9 @@ void ThreadView::setupContextMenu()
|
||||||
mGoToThreadEntry = new QAction(tr("Go to Thread Entry"), this);
|
mGoToThreadEntry = new QAction(tr("Go to Thread Entry"), this);
|
||||||
connect(mGoToThreadEntry, SIGNAL(triggered()), this, SLOT(GoToThreadEntry()));
|
connect(mGoToThreadEntry, SIGNAL(triggered()), this, SLOT(GoToThreadEntry()));
|
||||||
|
|
||||||
|
// Set name
|
||||||
|
mSetName = new QAction(tr("Set name"), this);
|
||||||
|
connect(mSetName, SIGNAL(triggered()), this, SLOT(SetNameSlot()));
|
||||||
}
|
}
|
||||||
|
|
||||||
ThreadView::ThreadView(StdTable* parent) : StdTable(parent)
|
ThreadView::ThreadView(StdTable* parent) : StdTable(parent)
|
||||||
|
@ -201,10 +206,10 @@ ThreadView::ThreadView(StdTable* parent) : StdTable(parent)
|
||||||
addColumnAt(8 + charwidth * 14, tr("Suspend Count"), false, "", SortBy::AsInt);
|
addColumnAt(8 + charwidth * 14, tr("Suspend Count"), false, "", SortBy::AsInt);
|
||||||
addColumnAt(8 + charwidth * 12, tr("Priority"), false);
|
addColumnAt(8 + charwidth * 12, tr("Priority"), false);
|
||||||
addColumnAt(8 + charwidth * 12, tr("Wait Reason"), false);
|
addColumnAt(8 + charwidth * 12, tr("Wait Reason"), false);
|
||||||
addColumnAt(8 + charwidth * 11, tr("Last Error"), false);
|
addColumnAt(8 + charwidth * 10, tr("Last Error"), false);
|
||||||
addColumnAt(8 + charwidth * 12, tr("User Time"), false);
|
addColumnAt(8 + charwidth * 16, tr("User Time"), false);
|
||||||
addColumnAt(8 + charwidth * 12, tr("Kernel Time"), false);
|
addColumnAt(8 + charwidth * 16, tr("Kernel Time"), false);
|
||||||
addColumnAt(8 + charwidth * 15, tr("Creation Time"), false);
|
addColumnAt(8 + charwidth * 16, tr("Creation Time"), false);
|
||||||
addColumnAt(8 + charwidth * 10, tr("CPU Cycles"), false, "", SortBy::AsInt);
|
addColumnAt(8 + charwidth * 10, tr("CPU Cycles"), false, "", SortBy::AsInt);
|
||||||
addColumnAt(8, tr("Name"), false);
|
addColumnAt(8, tr("Name"), false);
|
||||||
loadColumnFromConfig("Thread");
|
loadColumnFromConfig("Thread");
|
||||||
|
@ -421,3 +426,14 @@ void ThreadView::doubleClickedSlot()
|
||||||
DbgCmdExecDirect(QString("switchthread " + threadId).toUtf8().constData());
|
DbgCmdExecDirect(QString("switchthread " + threadId).toUtf8().constData());
|
||||||
emit showCpu();
|
emit showCpu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ThreadView::SetNameSlot()
|
||||||
|
{
|
||||||
|
QString threadId = getCellContent(getInitialSelection(), 1);
|
||||||
|
LineEditDialog mLineEdit(this);
|
||||||
|
mLineEdit.setText(getCellContent(getInitialSelection(), 13));
|
||||||
|
if(mLineEdit.exec() != QDialog::Accepted)
|
||||||
|
return;
|
||||||
|
QString escapedName = mLineEdit.editText.replace("\"", "\\\"");
|
||||||
|
DbgCmdExec(QString("setthreadname %1, \"%2\"").arg(threadId).arg(escapedName).toUtf8().constData());
|
||||||
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ public slots:
|
||||||
void SetPriorityLowestSlot();
|
void SetPriorityLowestSlot();
|
||||||
void SetPriorityNormalSlot();
|
void SetPriorityNormalSlot();
|
||||||
void SetPriorityTimeCriticalSlot();
|
void SetPriorityTimeCriticalSlot();
|
||||||
|
void SetNameSlot();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void showCpu();
|
void showCpu();
|
||||||
|
@ -46,6 +47,7 @@ private:
|
||||||
QAction* mSetPriorityLowest;
|
QAction* mSetPriorityLowest;
|
||||||
QAction* mSetPriorityNormal;
|
QAction* mSetPriorityNormal;
|
||||||
QAction* mSetPriorityTimeCritical;
|
QAction* mSetPriorityTimeCritical;
|
||||||
|
QAction* mSetName;
|
||||||
QMenu* mSetPriority;
|
QMenu* mSetPriority;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue