当前位置: 首页>>代码示例>>C++>>正文


C++ DbgHelp::StackWalk64方法代码示例

本文整理汇总了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(&currentContext, 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, &currentContext, 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);
    }
}
开发者ID:rconde01,项目名称:vld,代码行数:71,代码来源:callstack.cpp

示例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;
}
开发者ID:madmaxoft,项目名称:verysleepy,代码行数:101,代码来源:profiler.cpp


注:本文中的DbgHelp::StackWalk64方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。