EAMainExit.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /////////////////////////////////////////////////////////////////////////////
  2. // EAMainExit.cpp
  3. //
  4. // Copyright (c) 2015 Electronic Arts Inc. All Rights Reserved.
  5. // Created by Justin Sharma
  6. /////////////////////////////////////////////////////////////////////////////
  7. #include <EAMain/EAMainExit.h>
  8. #include <EAMain/EAMain.h>
  9. #include <EAStdC/EAMemory.h>
  10. #include <EABase/eabase.h>
  11. EA_DISABLE_ALL_VC_WARNINGS()
  12. #include <cstdlib>
  13. #if defined(EA_PLATFORM_SONY) || defined(EA_PLATFORM_ANDROID)
  14. // All of these platforms require complex handling of exceptions and signals. No apparent solution yet.
  15. #elif defined(EA_PLATFORM_LINUX)
  16. #include <sys/signal.h>
  17. #elif defined(EA_PLATFORM_APPLE) || defined(EA_PLATFORM_WINDOWS) || defined(EA_PLATFORM_XBOXONE) || defined(EA_PLATFORM_CAPILANO) || defined(CS_UNDEFINED_STRING)
  18. #include <csignal>
  19. #endif
  20. EA_RESTORE_ALL_VC_WARNINGS()
  21. #include <EAMain/internal/EAMainStartupShutdown.h>
  22. namespace EA {
  23. namespace EAMain {
  24. const char* gExitCodeNames[ExitCode_Max] =
  25. {
  26. "Succeeded",
  27. "Asserted",
  28. "Abort Signal",
  29. "Segmentation Fault Signal",
  30. "Illegal Instruction Signal",
  31. "Hangup Signal",
  32. "Floating Point Exception Signal",
  33. "BusError Signal",
  34. "Unkown",
  35. };
  36. void Exit(int exitcode)
  37. {
  38. int index = (exitcode < 0 || exitcode >= ExitCode_Max) ? exitcode = ExitCode_Unknown : exitcode;
  39. Report("======================================================================\nEA::Main::Exit called with exitcode %d (%s)!\nThe caller wanted to immediately end execution!\n======================================================================\n", exitcode, gExitCodeNames[index]);
  40. #if !defined(EA_PLATFORM_ANDROID)
  41. Internal::EAMainShutdown(exitcode);
  42. std::exit(exitcode);
  43. #else
  44. PlatformShutdown(exitcode);
  45. #endif
  46. }
  47. #if defined(EA_PLATFORM_SONY) || defined(EA_PLATFORM_ANDROID) || defined(CS_UNDEFINED_STRING)
  48. void InitializeSignalHandler() {
  49. // Do nothing. No solution for signal/exception handling on this platform yet.
  50. }
  51. #elif defined(EA_PLATFORM_WINDOWS) || defined(EA_PLATFORM_XBOXONE) || defined(EA_PLATFORM_CAPILANO) || defined(CS_UNDEFINED_STRING)
  52. void InitializeSignalHandler()
  53. {
  54. // Do nothing. Unhandled exception filter will handle creating a minidump on
  55. // this platform which will contain more actionable information than a trapped
  56. // signal.
  57. }
  58. #elif defined(EA_PLATFORM_APPLE) || defined(EA_PLATFORM_IPHONE)
  59. int SignalToExitCode(int signal) {
  60. switch(signal)
  61. {
  62. case SIGABRT:
  63. return ExitCode_SignalAbort;
  64. case SIGSEGV:
  65. return ExitCode_SignalSegmentationViolation;
  66. case SIGILL:
  67. return ExitCode_SignalIllegalInstruction;
  68. case SIGFPE:
  69. return ExitCode_SignalFloatingPointException;
  70. case SIGHUP:
  71. return ExitCode_SignalHangup;
  72. case SIGBUS:
  73. return ExitCode_SignalBusError;
  74. default:
  75. return ExitCode_Unknown;
  76. };
  77. }
  78. void HandleSignal(int signal) {
  79. EA::EAMain::Exit(SignalToExitCode(signal));
  80. }
  81. void InitializeSignalHandler() {
  82. std::signal(SIGABRT, HandleSignal);
  83. std::signal(SIGSEGV, HandleSignal);
  84. std::signal(SIGILL, HandleSignal);
  85. std::signal(SIGFPE, HandleSignal);
  86. std::signal(SIGHUP, HandleSignal);
  87. std::signal(SIGBUS, HandleSignal);
  88. }
  89. #elif defined(EA_PLATFORM_LINUX)
  90. int SignalToExitCode(int signal) {
  91. switch(signal)
  92. {
  93. case SIGABRT:
  94. return ExitCode_SignalAbort;
  95. case SIGSEGV:
  96. return ExitCode_SignalSegmentationViolation;
  97. case SIGILL:
  98. return ExitCode_SignalIllegalInstruction;
  99. case SIGHUP:
  100. return ExitCode_SignalHangup;
  101. case SIGFPE:
  102. return ExitCode_SignalFloatingPointException;
  103. case SIGBUS:
  104. return ExitCode_SignalBusError;
  105. default:
  106. return ExitCode_Unknown;
  107. };
  108. }
  109. struct sigaction ABRTAction;
  110. struct sigaction SEGVAction;
  111. struct sigaction SIGILLAction;
  112. struct sigaction SIGHUPAction;
  113. struct sigaction SIGFPEAction;
  114. struct sigaction SIGBUSAction;
  115. void HandleSignal(int signal, siginfo_t *sigInfo, void *context) {
  116. EA::EAMain::Exit(SignalToExitCode(signal));
  117. }
  118. void InitializeSignalHandler() {
  119. ABRTAction.sa_sigaction = HandleSignal;
  120. ABRTAction.sa_flags = SA_SIGINFO;
  121. SEGVAction.sa_sigaction = HandleSignal;
  122. SEGVAction.sa_flags = SA_SIGINFO;
  123. SIGILLAction.sa_sigaction = HandleSignal;
  124. SIGILLAction.sa_flags = SA_SIGINFO;
  125. SIGHUPAction.sa_sigaction = HandleSignal;
  126. SIGHUPAction.sa_flags = SA_SIGINFO;
  127. SIGFPEAction.sa_sigaction = HandleSignal;
  128. SIGFPEAction.sa_flags = SA_SIGINFO;
  129. SIGBUSAction.sa_sigaction = HandleSignal;
  130. SIGBUSAction.sa_flags = SA_SIGINFO;
  131. sigaction(SIGABRT, &ABRTAction, NULL);
  132. sigaction(SIGSEGV, &SEGVAction, NULL);
  133. sigaction(SIGILL, &SIGILLAction, NULL);
  134. sigaction(SIGHUP, &SIGHUPAction, NULL);
  135. sigaction(SIGFPE, &SIGFPEAction, NULL);
  136. sigaction(SIGBUS, &SIGBUSAction, NULL);
  137. }
  138. #endif
  139. }
  140. }