Beispiel #1
0
void PrintFunctionAndSourceInfo(FILE* file, const STACKFRAME& callstack)
{
	TCHAR symInfo[BUFFERSIZE] = _T("?");
	TCHAR srcInfo[BUFFERSIZE] = _T("?");

	GetFunctionInfoFromAddresses((ULONG)callstack.AddrPC.Offset, (ULONG)callstack.AddrFrame.Offset, symInfo);
	GetSourceInfoFromAddress((ULONG)callstack.AddrPC.Offset, srcInfo);
	etfprint(file, "     " + TStrToUTF8(srcInfo) + " : " + TStrToUTF8(symInfo) + "\n");
}
void FunctionParameterInfo()
{
	STACKFRAME     callStack;
	BOOL           bResult = FALSE;
	CONTEXT        context;
	TCHAR          lpszFnInfo[BUFFERSIZE];
	HANDLE         hProcess = GetCurrentProcess();
	HANDLE         hThread = GetCurrentThread();

	::ZeroMemory( &context, sizeof(context) );
	context.ContextFlags = CONTEXT_FULL;

	if ( !GetThreadContext( hThread, &context ) )
	{
	   OutputDebugStringFormat( _T("Function info(thread=0x%X) failed.\n") );
		return;
	}
	
	::ZeroMemory( &callStack, sizeof(callStack) );
	callStack.AddrPC.Offset    = context.Eip;
	callStack.AddrStack.Offset = context.Esp;
	callStack.AddrFrame.Offset = context.Ebp;
	callStack.AddrPC.Mode      = AddrModeFlat;
	callStack.AddrStack.Mode   = AddrModeFlat;
	callStack.AddrFrame.Mode   = AddrModeFlat;

	for( ULONG index = 0; index < 2; index++ ) 
	{
		bResult = StackWalk(
			IMAGE_FILE_MACHINE_I386,
			hProcess,
			hThread,
			&callStack,
			NULL, 
			NULL,
			SymFunctionTableAccess,
			SymGetModuleBase,
			NULL);
	}

	if ( bResult && callStack.AddrFrame.Offset != 0) 
	{
	   GetFunctionInfoFromAddresses( callStack.AddrPC.Offset, callStack.AddrFrame.Offset, lpszFnInfo );
	   OutputDebugStringFormat( _T("Function info(thread=0x%X) : %s\n"), GetCurrentThreadId(), lpszFnInfo );
	}
	else
	   OutputDebugStringFormat( _T("Function info(thread=0x%X) failed.\n") );
}
void StackTrace( HANDLE hThread, LPCTSTR lpszMessage )
{
	STACKFRAME     callStack;
	BOOL           bResult;
	CONTEXT        context;
	TCHAR          symInfo[BUFFERSIZE] = _T("?");
	TCHAR          srcInfo[BUFFERSIZE] = _T("?");
	HANDLE         hProcess = GetCurrentProcess();

   // If it's not this thread, let's suspend it, and resume it at the end
	if ( hThread != GetCurrentThread() )
		if ( SuspendThread( hThread ) == -1 )
		{
		   // whaaat ?!
		   OutputDebugStringFormat( _T("Call stack info(thread=0x%X) failed.\n") );
			return;
		}

	::ZeroMemory( &context, sizeof(context) );
	context.ContextFlags = CONTEXT_FULL;

	if ( !GetThreadContext( hThread, &context ) )
	{
      OutputDebugStringFormat( _T("Call stack info(thread=0x%X) failed.\n") );
	   return;
	}
	
	::ZeroMemory( &callStack, sizeof(callStack) );
	callStack.AddrPC.Offset    = context.Eip;
	callStack.AddrStack.Offset = context.Esp;
	callStack.AddrFrame.Offset = context.Ebp;
	callStack.AddrPC.Mode      = AddrModeFlat;
	callStack.AddrStack.Mode   = AddrModeFlat;
	callStack.AddrFrame.Mode   = AddrModeFlat;

	for( ULONG index = 0; ; index++ ) 
	{
		bResult = StackWalk(
			IMAGE_FILE_MACHINE_I386,
			hProcess,
			hThread,
	      &callStack,
			NULL, 
			NULL,
			SymFunctionTableAccess,
			SymGetModuleBase,
			NULL);

		if ( index == 0 )
		   continue;

		if( !bResult || callStack.AddrFrame.Offset == 0 ) 
			break;
	
		GetFunctionInfoFromAddresses( callStack.AddrPC.Offset, callStack.AddrFrame.Offset, symInfo );
		GetSourceInfoFromAddress( callStack.AddrPC.Offset, srcInfo );

		OutputDebugStringFormat( _T("     %s : %s\n"), srcInfo, symInfo );
	}

	if ( hThread != GetCurrentThread() )
		ResumeThread( hThread );
}