Win32 调用堆栈打印

void printCallStack(ushort maxLine)
{
	typedef USHORT(WINAPI *CaptureStackBackTraceType)(__in ULONG, __in ULONG, __out PVOID *, __out_opt PULONG);
	CaptureStackBackTraceType func = reinterpret_cast<CaptureStackBackTraceType>(::GetProcAddress(::LoadLibrary("kernel32.dll"), "RtlCaptureStackBackTrace"));
	if (!func)
		return; // WOE 29.SEP.2010
	// Quote from Microsoft Documentation:
	// ## Windows Server 2003 and Windows XP:
	// ## The sum of the FramesToSkip and FramesToCapture parameters must be less than 63.
	const int kMaxCallers = 62;
	void *callers_stack[kMaxCallers];
	HANDLE process = ::GetCurrentProcess();
	::SymInitialize(process, nullptr, TRUE);
	int frames = (func)(0, qMin(kMaxCallers, maxLine + 1), callers_stack, NULL);
	SYMBOL_INFO *symbol = static_cast<SYMBOL_INFO *>(calloc(sizeof(SYMBOL_INFO) + 256 * sizeof(char), 1));
	symbol->MaxNameLen = 255;
	symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
	::OutputDebugStringA("\n--------------- CallStack Begin ---------------\n");
	frames = qMin(frames, maxLine + 1);
	for (ushort i = 1; i < frames; i++)
	{
		::SymFromAddr(process, reinterpret_cast<DWORD64>(callers_stack[i]), nullptr, symbol);
		char message[256] = { 0 };
		sprintf_s(message, "%02d> 0x%08x: %s\n", i, reinterpret_cast<void *>(symbol->Address), symbol->Name);
		::OutputDebugStringA(message);
	}
	::OutputDebugStringA("--------------- CallStack End ---------------\n");
	free(symbol);
}

 

发表回复