GUI: Added new function GetCallStackByThread
This commit is contained in:
parent
f6c0faf201
commit
9311752b74
|
|
@ -107,6 +107,12 @@ static void _getcallstack(DBGCALLSTACK* callstack)
|
|||
stackgetcallstack(GetContextDataEx(hActiveThread, UE_CSP), (CALLSTACK*)callstack);
|
||||
}
|
||||
|
||||
static void _getcallstackbythread(HANDLE thread, DBGCALLSTACK* callstack)
|
||||
{
|
||||
if(thread)
|
||||
stackgetcallstackbythread(thread, (CALLSTACK*)callstack);
|
||||
}
|
||||
|
||||
static void _getsehchain(DBGSEHCHAIN* sehchain)
|
||||
{
|
||||
std::vector<duint> SEHList;
|
||||
|
|
@ -532,4 +538,5 @@ void dbgfunctionsinit()
|
|||
_dbgfunctions.RefreshModuleList = _refreshmodulelist;
|
||||
_dbgfunctions.GetAddrFromLineEx = _getaddrfromlineex;
|
||||
_dbgfunctions.ModSymbolStatus = _modsymbolstatus;
|
||||
_dbgfunctions.GetCallStackByThread = _getcallstackbythread;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -207,6 +207,7 @@ typedef int(*SYMAUTOCOMPLETE)(const char* Search, char** Buffer, int MaxSymbols)
|
|||
typedef void(*REFRESHMODULELIST)();
|
||||
typedef duint(*GETADDRFROMLINEEX)(duint mod, const char* szSourceFile, int line);
|
||||
typedef MODULESYMBOLSTATUS(*MODSYMBOLSTATUS)(duint mod);
|
||||
typedef void(*GETCALLSTACKBYTHREAD)(HANDLE thread, DBGCALLSTACK* callstack);
|
||||
|
||||
//The list of all the DbgFunctions() return value.
|
||||
//WARNING: This list is append only. Do not insert things in the middle or plugins would break.
|
||||
|
|
@ -285,6 +286,7 @@ typedef struct DBGFUNCTIONS_
|
|||
REFRESHMODULELIST RefreshModuleList;
|
||||
GETADDRFROMLINEEX GetAddrFromLineEx;
|
||||
MODSYMBOLSTATUS ModSymbolStatus;
|
||||
GETCALLSTACKBYTHREAD GetCallStackByThread;
|
||||
} DBGFUNCTIONS;
|
||||
|
||||
#ifdef BUILD_DBG
|
||||
|
|
|
|||
|
|
@ -360,6 +360,103 @@ void stackgetcallstack(duint csp, std::vector<CALLSTACKENTRY> & callstackVector,
|
|||
CallstackCache[csp] = callstackVector;
|
||||
}
|
||||
|
||||
void stackgetcallstackbythread(HANDLE thread, CALLSTACK* callstack)
|
||||
{
|
||||
std::vector<CALLSTACKENTRY> callstackVector;
|
||||
duint csp = GetContextDataEx(thread, UE_CSP);
|
||||
// Gather context data
|
||||
CONTEXT context;
|
||||
memset(&context, 0, sizeof(CONTEXT));
|
||||
|
||||
context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
|
||||
|
||||
if(SuspendThread(thread) == -1)
|
||||
return;
|
||||
|
||||
if(!GetThreadContext(thread, &context))
|
||||
return;
|
||||
|
||||
if(ResumeThread(thread) == -1)
|
||||
return;
|
||||
|
||||
if(ShowSuspectedCallStack)
|
||||
{
|
||||
stackgetsuspectedcallstack(csp, callstackVector);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set up all frame data
|
||||
STACKFRAME64 frame;
|
||||
ZeroMemory(&frame, sizeof(STACKFRAME64));
|
||||
|
||||
#ifdef _M_IX86
|
||||
DWORD machineType = IMAGE_FILE_MACHINE_I386;
|
||||
frame.AddrPC.Offset = context.Eip;
|
||||
frame.AddrPC.Mode = AddrModeFlat;
|
||||
frame.AddrFrame.Offset = context.Ebp;
|
||||
frame.AddrFrame.Mode = AddrModeFlat;
|
||||
frame.AddrStack.Offset = csp;
|
||||
frame.AddrStack.Mode = AddrModeFlat;
|
||||
#elif _M_X64
|
||||
DWORD machineType = IMAGE_FILE_MACHINE_AMD64;
|
||||
frame.AddrPC.Offset = context.Rip;
|
||||
frame.AddrPC.Mode = AddrModeFlat;
|
||||
frame.AddrFrame.Offset = context.Rsp;
|
||||
frame.AddrFrame.Mode = AddrModeFlat;
|
||||
frame.AddrStack.Offset = csp;
|
||||
frame.AddrStack.Mode = AddrModeFlat;
|
||||
#endif
|
||||
|
||||
const int MaxWalks = 50;
|
||||
// Container for each callstack entry (50 pre-allocated entries)
|
||||
callstackVector.clear();
|
||||
callstackVector.reserve(MaxWalks);
|
||||
|
||||
for(auto i = 0; i < MaxWalks; i++)
|
||||
{
|
||||
if(!SafeStackWalk64(
|
||||
machineType,
|
||||
fdProcessInfo->hProcess,
|
||||
thread,
|
||||
&frame,
|
||||
&context,
|
||||
StackReadProcessMemoryProc64,
|
||||
StackSymFunctionTableAccess64,
|
||||
StackGetModuleBaseProc64,
|
||||
StackTranslateAddressProc64))
|
||||
{
|
||||
// Maybe it failed, maybe we have finished walking the stack
|
||||
break;
|
||||
}
|
||||
|
||||
if(frame.AddrPC.Offset != 0)
|
||||
{
|
||||
// Valid frame
|
||||
CALLSTACKENTRY entry;
|
||||
memset(&entry, 0, sizeof(CALLSTACKENTRY));
|
||||
|
||||
StackEntryFromFrame(&entry, (duint)frame.AddrFrame.Offset + sizeof(duint), (duint)frame.AddrPC.Offset, (duint)frame.AddrReturn.Offset);
|
||||
callstackVector.push_back(entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Base reached
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
callstack->total = (int)callstackVector.size();
|
||||
|
||||
if(callstack->total > 0)
|
||||
{
|
||||
callstack->entries = (CALLSTACKENTRY*)BridgeAlloc(callstack->total * sizeof(CALLSTACKENTRY));
|
||||
|
||||
// Copy data directly from the vector
|
||||
memcpy(callstack->entries, callstackVector.data(), callstack->total * sizeof(CALLSTACKENTRY));
|
||||
}
|
||||
}
|
||||
|
||||
void stackgetcallstack(duint csp, CALLSTACK* callstack)
|
||||
{
|
||||
std::vector<CALLSTACKENTRY> callstackVector;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ bool stackcommentget(duint addr, STACK_COMMENT* comment);
|
|||
void stackupdatecallstack(duint csp);
|
||||
void stackgetcallstack(duint csp, CALLSTACK* callstack);
|
||||
void stackgetcallstack(duint csp, std::vector<CALLSTACKENTRY> & callstack, bool cache);
|
||||
void stackgetcallstackbythread(HANDLE thread, CALLSTACK* callstack);
|
||||
void stackupdatesettings();
|
||||
|
||||
#endif //_STACKINFO_H
|
||||
Loading…
Reference in New Issue