익셉션 안에서 콜스텍 출력


#include <tchar.h>
#include <string>
#include <windows.h>
#include <dbghelp.h>
#pragma comment(lib,"dbghelp")

long WINAPI ViewFunctionStack(_EXCEPTION_POINTERS *pExceptionInfo)
{
 int iSymbolNameSize = 1024;
 // Walk the stack.

 // Variables for stack walking.
 HANDLE hProcess = GetCurrentProcess();
 HANDLE hThread = GetCurrentThread();
 DWORD64 dw64Offset = 0;
 DWORD dwOffset = 0;
 DWORD dwSymOptions = SymGetOptions();
 SYMBOL_INFO* pSymbolInfo = (SYMBOL_INFO*) malloc( sizeof(SYMBOL_INFO) + iSymbolNameSize );
 IMAGEHLP_LINE64 imageHelpLine;
 STACKFRAME64 stackFrame64;

 // Initialize stack frame.
 memset( &stackFrame64, 0, sizeof(stackFrame64) );
 stackFrame64.AddrPC.Offset  = pExceptionInfo->ContextRecord->Eip;
 stackFrame64.AddrPC.Mode   = AddrModeFlat;
 stackFrame64.AddrFrame.Offset  = pExceptionInfo->ContextRecord->Ebp;
 stackFrame64.AddrFrame.Mode  = AddrModeFlat;
 stackFrame64.AddrStack.Offset  = pExceptionInfo->ContextRecord->Esp;
 stackFrame64.AddrStack.Mode  = AddrModeFlat;
 stackFrame64.AddrBStore.Mode  = AddrModeFlat;
 stackFrame64.AddrReturn.Mode  = AddrModeFlat;

 // Set symbol options.
 dwSymOptions      |= SYMOPT_LOAD_LINES;
 dwSymOptions      |= SYMOPT_UNDNAME;
 dwSymOptions      |= SYMOPT_EXACT_SYMBOLS;
 SymSetOptions( dwSymOptions );

 // Initialize symbol.
 memset( pSymbolInfo, 0, sizeof(SYMBOL_INFO) + iSymbolNameSize );
 pSymbolInfo->SizeOfStruct   = sizeof(SYMBOL_INFO);
 pSymbolInfo->MaxNameLen    = iSymbolNameSize;

 // Initialize line number info.
 memset( &imageHelpLine, 0, sizeof(imageHelpLine) );
 imageHelpLine.SizeOfStruct    = sizeof(imageHelpLine);

 // Load symbols.
 SymInitialize( GetCurrentProcess(), ".", 1 );

 std::string strStackList;

 while( 1 )
 {
  if( !StackWalk64( IMAGE_FILE_MACHINE_I386, hProcess, hThread, &stackFrame64, pExceptionInfo->ContextRecord, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL ) )
   break;

  // Warning - ANSI_TO_TCHAR uses alloca which might not be safe during an exception handler - INVESTIGATE!
  if( SymFromAddr( hProcess, stackFrame64.AddrPC.Offset, &dw64Offset, pSymbolInfo ) && SymGetLineFromAddr64( hProcess, stackFrame64.AddrPC.Offset, &dwOffset, &imageHelpLine ) )
  {
   char chLineNumber[128];
   _itoa_s(imageHelpLine.LineNumber, chLineNumber, 10);

   strStackList += pSymbolInfo->Name;
   strStackList += "() [";
   strStackList += imageHelpLine.FileName;
   strStackList += ":";
   strStackList += chLineNumber;
   strStackList += "]";
   strStackList += " <- ";
  }
 }

 SymCleanup( hProcess );
 free( pSymbolInfo );

 MessageBoxA(NULL, strStackList.c_str(), NULL, NULL);

 return EXCEPTION_EXECUTE_HANDLER;
}

void func()
{
 *((int *)0) = 0;
}

int _tmain(int argc, _TCHAR* argv[])
{

 SetUnhandledExceptionFilter( ViewFunctionStack );

 func();

 system("pause");
 return 0;
}