EAMainExit.cpp 5.6 KB

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