EAMainStartupShutdown.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright (c) Electronic Arts Inc. All rights reserved.
  3. ///////////////////////////////////////////////////////////////////////////////
  4. #include <EAMain/internal/EAMainStartupShutdown.h>
  5. #include <EAMain/EAMain.h>
  6. #include <EAMain/EAMainExit.h>
  7. #ifdef _MSC_VER
  8. #pragma warning(push, 0) // Microsoft headers generate warnings at our higher warning levels.
  9. #pragma warning(disable: 4702) // Unreachable code detected.
  10. #endif
  11. #if defined(EA_PLATFORM_MICROSOFT)
  12. #if defined(EA_PLATFORM_WINDOWS_PHONE) || defined(EA_PLATFORM_WINRT)
  13. #define EAMAIN_HAVE_UNHANDLED_EXCEPTION_FILTER 0
  14. #else
  15. #if !defined(WIN32_LEAN_AND_MEAN)
  16. #define WIN32_LEAN_AND_MEAN
  17. #endif
  18. #if defined(EA_PLATFORM_CAPILANO)
  19. #include <xdk.h>
  20. #endif
  21. EA_DISABLE_ALL_VC_WARNINGS();
  22. #include <Windows.h>
  23. #include <DbgHelp.h>
  24. EA_RESTORE_ALL_VC_WARNINGS();
  25. #include <EAStdC/EASprintf.h>
  26. #define EAMAIN_HAVE_UNHANDLED_EXCEPTION_FILTER 1
  27. #endif
  28. #endif
  29. #if !defined(EAMAIN_HAVE_UNHANDLED_EXCEPTION_FILTER)
  30. #define EAMAIN_HAVE_UNHANDLED_EXCEPTION_FILTER 0
  31. #endif
  32. namespace EA
  33. {
  34. namespace EAMain
  35. {
  36. namespace Internal
  37. {
  38. #if EAMAIN_HAVE_UNHANDLED_EXCEPTION_FILTER
  39. static LONG WINAPI EAMainUnhandledExceptionFilter(LPEXCEPTION_POINTERS exception)
  40. {
  41. EA::EAMain::Report("\n");
  42. EA::EAMain::Report("===============================================================================\n");
  43. EA::EAMain::Report("ATTENTION ATTENTION ATTENTION ATTENTION ATTENTION ATTENTION ATTENTION ATTENTION\n");
  44. EA::EAMain::Report("An unhandled exception has been detected. This likely means the application is \n");
  45. EA::EAMain::Report("crashing.\n\n");
  46. EA::EAMain::Report("(This message is courtesy of EAMain but does not mean that EAMain is\n");
  47. EA::EAMain::Report("the cause of the crash.)\n");
  48. EA::EAMain::Report("===============================================================================\n");
  49. #if EAMAIN_MINIDUMP_SUPPORTED
  50. char8_t szPath[MAX_PATH];
  51. char8_t szFileName[MAX_PATH];
  52. HANDLE hDumpFile;
  53. SYSTEMTIME stLocalTime;
  54. MINIDUMP_EXCEPTION_INFORMATION ExpParam;
  55. BOOL bMiniDumpSuccessful;
  56. #if defined(EA_PLATFORM_CAPILANO)
  57. const char8_t* pszDrive = "G:\\";
  58. #else
  59. const char8_t* pszDrive = "C:\\";
  60. #endif
  61. GetLocalTime( &stLocalTime );
  62. EA::StdC::Snprintf(szPath, EAArrayCount(szPath), "%sMiniDumps\\", pszDrive);
  63. CreateDirectoryA(szPath, NULL );
  64. EA::StdC::Snprintf(szFileName, EAArrayCount(szFileName), "%sMiniDump-%04d%02d%02d-%02d%02d%02d-%ld-%ld.dmp",
  65. szPath,
  66. stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay,
  67. stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond,
  68. GetCurrentProcessId(), GetCurrentThreadId());
  69. EA::EAMain::Report("Creating Dump File: %s - ", szFileName);
  70. hDumpFile = CreateFileA(szFileName, GENERIC_READ|GENERIC_WRITE,
  71. FILE_SHARE_WRITE|FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
  72. EA::EAMain::Report("%s (Error: %d) \n", hDumpFile != INVALID_HANDLE_VALUE ? "Success" : "Failure", hDumpFile != INVALID_HANDLE_VALUE ? 0 : HRESULT_FROM_WIN32(GetLastError()));
  73. ExpParam.ThreadId = GetCurrentThreadId();
  74. ExpParam.ExceptionPointers = exception;
  75. ExpParam.ClientPointers = TRUE;
  76. bMiniDumpSuccessful = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
  77. hDumpFile, MiniDumpWithDataSegs, &ExpParam, NULL, NULL);
  78. EA::EAMain::Report("Dump %s (Error: %d)\n", bMiniDumpSuccessful == TRUE ? "Successful" : "Failed - so deleted minidump file", bMiniDumpSuccessful == TRUE ? 0 : HRESULT_FROM_WIN32(GetLastError()));
  79. if (bMiniDumpSuccessful == FALSE)
  80. {
  81. DeleteFileA(szFileName);
  82. }
  83. #endif
  84. EAMainShutdown(1);
  85. return EXCEPTION_CONTINUE_SEARCH;
  86. }
  87. #endif
  88. void EAMainStartup(const char8_t* printServerAddress)
  89. {
  90. static bool sEAMainShutdown_StartupHandled = false;
  91. if(!sEAMainShutdown_StartupHandled)
  92. {
  93. sEAMainShutdown_StartupHandled = true;
  94. #if EAMAIN_HAVE_UNHANDLED_EXCEPTION_FILTER
  95. SetUnhandledExceptionFilter(EAMainUnhandledExceptionFilter);
  96. #endif
  97. // Running under NAnt output only appears when the buffer is filled if we allow the default buffering scheme for printf.
  98. setvbuf(stdout, NULL, _IONBF, BUFSIZ);
  99. setvbuf(stderr, NULL, _IONBF, BUFSIZ);
  100. // Startup the print manager
  101. //
  102. EA::EAMain::PrintManager::Instance().Startup(printServerAddress);
  103. }
  104. }
  105. int EAMainShutdown(int errorCount)
  106. {
  107. static bool sEAMainShutdown_ShutdownHandled = false;
  108. if(!sEAMainShutdown_ShutdownHandled)
  109. {
  110. sEAMainShutdown_ShutdownHandled = true;
  111. // Handle the application specific exit code.
  112. //
  113. #if defined(EA_PLATFORM_IPHONE)
  114. // Get test result. (iOS 5 bug prevents iPhone Runner from getting this from the exit code)
  115. if (errorCount == 0)
  116. Report("\nAll tests completed successfully.\n");
  117. else
  118. Report("\nTests failed. Total error count: %d\n", errorCount);
  119. fflush(stdout);
  120. #endif
  121. #if !defined(EA_PLATFORM_DESKTOP) && !defined(EA_PLATFORM_SERVER) // TODO: change define to something related to the StdC library used on the system.
  122. fflush(stdout);
  123. #endif
  124. // Required so the EAMainPrintServer can terminate with the correct error code.
  125. //
  126. EA::EAMain::Report("\nRETURNCODE=%d\n", errorCount);
  127. // Shutdown the EAMain print manager.
  128. //
  129. EA::EAMain::PrintManager::Instance().Shutdown();
  130. }
  131. return errorCount;
  132. }
  133. }
  134. }
  135. }
  136. #ifdef _MSC_VER
  137. #pragma warning(pop)
  138. #endif