本文整理汇总了C++中DbgHelp::StackWalk64方法的典型用法代码示例。如果您正苦于以下问题:C++ DbgHelp::StackWalk64方法的具体用法?C++ DbgHelp::StackWalk64怎么用?C++ DbgHelp::StackWalk64使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类DbgHelp
的用法示例。
在下文中一共展示了DbgHelp::StackWalk64方法的2个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: getStackTrace
// getStackTrace - Traces the stack as far back as possible, or until 'maxdepth'
// frames have been traced. Populates the CallStack with one entry for each
// stack frame traced.
//
// Note: This function uses a documented Windows API to walk the stack. This
// API is supposed to be the most reliable way to walk the stack. It claims
// to be able to walk stack frames that do not follow the conventional stack
// frame layout. However, this robustness comes at a cost: it is *extremely*
// slow compared to walking frames by following frame (base) pointers.
//
// - maxdepth (IN): Maximum number of frames to trace back.
//
// - framepointer (IN): Frame (base) pointer at which to begin the stack trace.
// If NULL, then the stack trace will begin at this function.
//
// Return Value:
//
// None.
//
VOID SafeCallStack::getStackTrace (UINT32 maxdepth, const context_t& context)
{
UINT32 count = 0;
UINT_PTR function = context.func;
if (function != NULL)
{
count++;
push_back(function);
}
DWORD architecture = X86X64ARCHITECTURE;
// Get the required values for initialization of the STACKFRAME64 structure
// to be passed to StackWalk64(). Required fields are AddrPC and AddrFrame.
CONTEXT currentContext;
memset(¤tContext, 0, sizeof(currentContext));
currentContext.SPREG = context.SPREG;
currentContext.BPREG = context.BPREG;
currentContext.IPREG = context.IPREG;
// Initialize the STACKFRAME64 structure.
STACKFRAME64 frame;
memset(&frame, 0x0, sizeof(frame));
frame.AddrPC.Offset = currentContext.IPREG;
frame.AddrPC.Mode = AddrModeFlat;
frame.AddrStack.Offset = currentContext.SPREG;
frame.AddrStack.Mode = AddrModeFlat;
frame.AddrFrame.Offset = currentContext.BPREG;
frame.AddrFrame.Mode = AddrModeFlat;
frame.Virtual = TRUE;
CriticalSectionLocker<> cs(g_heapMapLock);
CriticalSectionLocker<DbgHelp> locker(g_DbgHelp);
// Walk the stack.
while (count < maxdepth) {
count++;
DbgTrace(L"dbghelp32.dll %i: StackWalk64\n", GetCurrentThreadId());
if (!g_DbgHelp.StackWalk64(architecture, g_currentProcess, g_currentThread, &frame, ¤tContext, NULL,
SymFunctionTableAccess64, SymGetModuleBase64, NULL, locker)) {
// Couldn't trace back through any more frames.
break;
}
if (frame.AddrFrame.Offset == 0) {
// End of stack.
break;
}
// Push this frame's program counter onto the CallStack.
push_back((UINT_PTR)frame.AddrPC.Offset);
}
}
示例2: sampleTarget
//.........这里部分代码省略.........
#else
CONTEXT32 threadcontext32;
context = &threadcontext32;
threadcontext32.ContextFlags = CONTEXT32_FLAGS;
machine = IMAGE_FILE_MACHINE_I386;
// Can fail occasionally, for example if you have a debugger attached to the process.
HRESULT result = SuspendThread(target_thread);
if(result == 0xffffffff)
return false;
int prev_priority = GetThreadPriority(target_thread);
SetThreadPriority(target_thread, THREAD_PRIORITY_TIME_CRITICAL);
result = GetThreadContext(target_thread, &threadcontext32);
SetThreadPriority(target_thread, prev_priority);
if(!result){
// DE: 20090325: If GetThreadContext fails we must be sure to resume thread again
ResumeThread(target_thread);
return false;
}
applyHacks(target_process, threadcontext32);
ip = threadcontext32.Eip;
sp = threadcontext32.Esp;
bp = threadcontext32.Ebp;
#endif
DbgHelp *prevDbgHelp = NULL;
bool first = true;
while(true)
{
// See which module this IP is in.
Module *mod = syminfo->getModuleForAddr(ip);
DbgHelp *dbgHelp = mod ? mod->dbghelp : &dbgHelpMs;
// Use whichever dbghelp stack walker is best for this module type.
// If we're switching between types, restart the stack walk from
// the current place.
if (dbgHelp != prevDbgHelp)
{
prevDbgHelp = dbgHelp;
memset(&frame, 0, sizeof(frame));
frame.AddrStack.Offset = sp;
frame.AddrPC.Offset = ip;
frame.AddrFrame.Offset = bp;
frame.AddrStack.Mode = frame.AddrPC.Mode = frame.AddrFrame.Mode = AddrModeFlat;
frame.AddrReturn.Offset = ip;
first = true;
}
// Add this IP to the stack trace.
// We skip the first one, as the first call to StackWalk64
// simply fills in more registers for the current frame,
// rather than walking down to the next one.
if (!first)
stack.addr[stack.depth++] = ip;
first = false;
BOOL result = dbgHelp->StackWalk64(
machine,
target_process,
target_thread,
&frame,
context,
NULL,
dbgHelp->SymFunctionTableAccess64,
dbgHelp->SymGetModuleBase64,
NULL
);
if (!result || stack.depth >= MAX_CALLSTACK_LEVELS)
break;
ip = (PROFILER_ADDR)frame.AddrPC.Offset;
sp = (PROFILER_ADDR)frame.AddrStack.Offset;
bp = (PROFILER_ADDR)frame.AddrFrame.Offset;
// Stop once we hit the end of the stack.
if (frame.AddrReturn.Offset == 0)
{
stack.addr[stack.depth++] = ip;
break;
}
}
if (!ResumeThread(target_thread))
throw ProfilerExcep(L"ResumeThread failed.");
//NOTE: this has to go after ResumeThread. Otherwise mem allocation needed by std::map
//may hit a lock held by the suspended thread.
if (stack.depth > 0)
{
flatcounts[stack.addr[0]]+=timeSpent;
callstacks[stack]+=timeSpent;
}
return true;
}