アプリケーションのスタック トレースを出力しようとしています。StackWalk64
私のアプリケーションは でリリースされているため、使用できませんoptimization disabled
。私たちは誰かが書いたライブラリx86
を使用していましたが、似たようなものは見つかりませんでした。以下は、私がウェブ上で見つけたコードです。strace
codeprex
x64
x86
#include <Windows.h>
#include <DbgHelp.h>
#include <stdio.h>
#define INVALID_FP_RET_ADDR_VALUE 0x00000000
BOOL g_fSymInit;
HANDLE g_hProcess;
BOOL DisplaySymbolDetails(DWORD dwAddress)
{
DWORD64 displacement = 0;
ULONG64 buffer[(sizeof(SYMBOL_INFO) +
MAX_SYM_NAME*sizeof(TCHAR) +
sizeof(ULONG64) - 1) /
sizeof(ULONG64)];
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
pSymbol->MaxNameLen = MAX_SYM_NAME;
if (SymFromAddr(g_hProcess,dwAddress,&displacement,pSymbol))
{
// Try to get the Module details
IMAGEHLP_MODULE64 moduleinfo;
moduleinfo.SizeOfStruct = sizeof(IMAGEHLP_MODULE64);
if (SymGetModuleInfo64(g_hProcess,pSymbol->Address,&moduleinfo))
{
printf("%s!",moduleinfo.ModuleName);
}
else
{
printf("<ErrorModuleInfo_%d>!", GetLastError());
}
// now print the function name
if (pSymbol->MaxNameLen > 0)
{
printf("%s",pSymbol->Name);
}
else
{
printf("<Unknown_Function>");
}
}
else
{
printf(" <Unable to get symbol details_%d>", GetLastError());
}
return TRUE;
}
bool WalkTheStack()
{
DWORD _ebp = INVALID_FP_RET_ADDR_VALUE;
DWORD dwIPOfCurrentFunction = (DWORD)&WalkTheStack;
// Get the current Frame pointer
__asm
{
mov [_ebp], ebp
}
// We cannot walk the stack (yet!) without a frame pointer
if (_ebp == INVALID_FP_RET_ADDR_VALUE)
return false;
printf("CurFP\t\t\tRetAddr\n");
DWORD *pCurFP = (DWORD *)_ebp;
BOOL fFirstFP = TRUE;
while (pCurFP != INVALID_FP_RET_ADDR_VALUE)
{
// pointer arithmetic works in terms of type pointed to. Thus,
// "+1" below is equivalent of 4 bytes since we are doing DWORD
// math.
DWORD pRetAddrInCaller = (*((DWORD *)(pCurFP + 1)));
printf("%p\t\t%p ",pCurFP, (DWORD *)pRetAddrInCaller);
if (g_fSymInit)
{
if (fFirstFP)
{
fFirstFP = FALSE;
}
DisplaySymbolDetails(dwIPOfCurrentFunction);
// To get the name of the next function up the stack,
// we use the return address of the current frame
dwIPOfCurrentFunction = pRetAddrInCaller;
}
printf("\n");
if (pRetAddrInCaller == INVALID_FP_RET_ADDR_VALUE)
{
// StackWalk is over now...
break;
}
// move up the stack to our caller
DWORD pCallerFP = *((DWORD *)pCurFP);
pCurFP = (DWORD *)pCallerFP;
}
return true;
}
int main ( int argc, char **argv) {
g_fSymInit = FALSE;
g_hProcess = GetCurrentProcess();
if (!SymInitialize(g_hProcess, NULL,TRUE)) {
printf("Unable to initialize symbols!\n\n");
} else {
g_fSymInit = TRUE;
}
SymSetOptions(SYMOPT_UNDNAME|SYMOPT_INCLUDE_32BIT_MODULES|SYMOPT_ALLOW_ABSOLUTE_SYMBOLS);
WalkTheStack();
return 0;
}
機能させるにはどのような変更が必要ですかx64