• Advertisement
Sign in to follow this  

Call Stack

This topic is 3944 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Can anyone tell me how to write the call stack to a file if an assert triggers? (we need this so we can examine problems occurring on our play-testers' machines)

Share this post


Link to post
Share on other sites
Advertisement
Large chunk of code from my memory manager code:

void PMemory::DetermineCaller(Allocation* pAllocation)
{
// Get the current thread context
DWORD dwMachineType;
CONTEXT theContext;
memset(&theContext, 0, sizeof(theContext));
RtlCaptureContext(&theContext);

// Init the stack frame for this function
STACKFRAME64 theStackFrame;
memset(&theStackFrame, 0, sizeof(theStackFrame));
#ifdef _M_IX86
dwMachineType = IMAGE_FILE_MACHINE_I386;
theStackFrame.AddrPC.Offset = theContext.Eip;
theStackFrame.AddrPC.Mode = AddrModeFlat;
theStackFrame.AddrFrame.Offset = theContext.Ebp;
theStackFrame.AddrFrame.Mode = AddrModeFlat;
theStackFrame.AddrStack.Offset = theContext.Esp;
theStackFrame.AddrStack.Mode = AddrModeFlat;
#elif _M_X64
dwMachineType = IMAGE_FILE_MACHINE_AMD64;
theStackFrame.AddrPC.Offset = theContext.Rip;
theStackFrame.AddrPC.Mode = AddrModeFlat;
theStackFrame.AddrFrame.Offset = theContext.Rsp;
theStackFrame.AddrFrame.Mode = AddrModeFlat;
theStackFrame.AddrStack.Offset = theContext.Rsp;
theStackFrame.AddrStack.Mode = AddrModeFlat;
#elif _M_IA64
dwMachineType = IMAGE_FILE_MACHINE_IA64;
theStackFrame.AddrPC.Offset = theContext.StIIP;
theStackFrame.AddrPC.Mode = AddrModeFlat;
theStackFrame.AddrFrame.Offset = theContext.IntSp;
theStackFrame.AddrFrame.Mode = AddrModeFlat;
theStackFrame.AddrBStore.Offset = theContext.RsBSP;
theStackFrame.AddrBStore.Mode = AddrModeFlat;
theStackFrame.AddrStack.Offset = theContext.IntSp;
theStackFrame.AddrStack.Mode = AddrModeFlat;
#else
# error "Platform not supported!"
#endif

// Walk up the stack to the caller
for(int i=0; i<s_nFramesToWalk; ++i)
{
if(!StackWalk64(dwMachineType, GetCurrentProcess(), GetCurrentThread(), &theStackFrame,
&theContext, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL))
{
strcpy(pAllocation->szFile, "??");
pAllocation->nLine = 0;
return;
}
}

// Get file/line number
{
IMAGEHLP_LINE64 theLine;
DWORD dwDisplacement;
memset(&theLine, 0, sizeof(theLine));
theLine.SizeOfStruct = sizeof(theLine);
if(!SymGetLineFromAddr64(GetCurrentProcess(), theStackFrame.AddrPC.Offset, &dwDisplacement, &theLine))
{
strcpy(pAllocation->szFile, "??");
pAllocation->nLine = 0;
strcpy(pAllocation->szFunc, "??");
}
else
{
const char* pszFile = strrchr(theLine.FileName, '\\');
if(!pszFile) pszFile = theLine.FileName;
else ++pszFile;
strncpy(pAllocation->szFile, pszFile, Allocation::cnBufferSize);
pAllocation->nLine = theLine.LineNumber;
}
}

// Get function name
{
unsigned char byBuffer[sizeof(IMAGEHLP_SYMBOL64) + Allocation::cnBufferSize];
IMAGEHLP_SYMBOL64* pSymbol = (IMAGEHLP_SYMBOL64*)byBuffer;
DWORD64 dwDisplacement;
memset(pSymbol, 0, sizeof(IMAGEHLP_SYMBOL64) + Allocation::cnBufferSize);
pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
pSymbol->MaxNameLength = Allocation::cnBufferSize;
if(!SymGetSymFromAddr64(GetCurrentProcess(), theStackFrame.AddrPC.Offset, &dwDisplacement, pSymbol))
strcpy(pAllocation->szFunc, "??");
else
{
pSymbol->Name[Allocation::cnBufferSize-1] = '\0';
strcpy(pAllocation->szFunc, pSymbol->Name);
}
}
}


Obviously the symbol names won't exist in a release build, but you can still use the stack walking mechanism to walk the callstack and record return addresses, which you can then deal with on a dev machine. See StackWalk64 for more information.

Share this post


Link to post
Share on other sites
Thanks Steve,

Where is RtlCaptureContext on your machine? MSDN tells me it's in <winNT.h>

http://msdn2.microsoft.com/en-us/library/ms680591.aspx

but it's not anywhere to be found on my machine...

Are you using MSVC7?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement