dynapi: Deal with failure cases better, other fixes. Fixes Bugzilla #4803.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
diff --git a/src/SDL.c b/src/SDL.c
index 6e80178..37423d4 100644
--- a/src/SDL.c
+++ b/src/SDL.c
@@ -45,6 +45,33 @@ extern int SDL_HelperWindowDestroy(void);
#endif
+/* This is not declared in any header, although it is shared between some
+ parts of SDL, because we don't want anything calling it without an
+ extremely good reason. */
+SDL_NORETURN void SDL_ExitProcess(const int exitcode)
+{
+#ifdef __WIN32__
+ /* "if you do not know the state of all threads in your process, it is
+ better to call TerminateProcess than ExitProcess"
+ https://msdn.microsoft.com/en-us/library/windows/desktop/ms682658(v=vs.85).aspx */
+ TerminateProcess(GetCurrentProcess(), exitcode);
+ /* MingW doesn't have TerminateProcess marked as noreturn, so add an
+ ExitProcess here that will never be reached but make MingW happy. */
+ ExitProcess(exitcode);
+#elif defined(__EMSCRIPTEN__)
+ emscripten_cancel_main_loop(); /* this should "kill" the app. */
+ emscripten_force_exit(exitcode); /* this should "kill" the app. */
+ exit(exitcode);
+#elif defined(__HAIKU__) /* Haiku has _Exit, but it's not marked noreturn. */
+ _exit(exitcode);
+#elif defined(HAVE__EXIT) /* Upper case _Exit() */
+ _Exit(exitcode);
+#else
+ _exit(exitcode);
+#endif
+}
+
+
/* The initialized subsystems */
#ifdef SDL_MAIN_NEEDED
static SDL_bool SDL_MainIsReady = SDL_FALSE;
diff --git a/src/SDL_assert.c b/src/SDL_assert.c
index 7ded637..ea97157 100644
--- a/src/SDL_assert.c
+++ b/src/SDL_assert.c
@@ -120,32 +120,14 @@ static void SDL_GenerateAssertionReport(void)
}
+/* This is not declared in any header, although it is shared between some
+ parts of SDL, because we don't want anything calling it without an
+ extremely good reason. */
#if defined(__WATCOMC__)
-static void SDL_ExitProcess (int);
+void SDL_ExitProcess(const int exitcode);
#pragma aux SDL_ExitProcess aborts;
#endif
-static SDL_NORETURN void SDL_ExitProcess(int exitcode)
-{
-#ifdef __WIN32__
- /* "if you do not know the state of all threads in your process, it is
- better to call TerminateProcess than ExitProcess"
- https://msdn.microsoft.com/en-us/library/windows/desktop/ms682658(v=vs.85).aspx */
- TerminateProcess(GetCurrentProcess(), exitcode);
- /* MingW doesn't have TerminateProcess marked as noreturn, so add an
- ExitProcess here that will never be reached but make MingW happy. */
- ExitProcess(exitcode);
-#elif defined(__EMSCRIPTEN__)
- emscripten_cancel_main_loop(); /* this should "kill" the app. */
- emscripten_force_exit(exitcode); /* this should "kill" the app. */
- exit(exitcode);
-#elif defined(__HAIKU__) /* Haiku has _Exit, but it's not marked noreturn. */
- _exit(exitcode);
-#elif defined(HAVE__EXIT) /* Upper case _Exit() */
- _Exit(exitcode);
-#else
- _exit(exitcode);
-#endif
-}
+SDL_NORETURN void SDL_ExitProcess(const int exitcode);
#if defined(__WATCOMC__)
diff --git a/src/dynapi/SDL_dynapi.c b/src/dynapi/SDL_dynapi.c
index b5497b2..23be8aa 100644
--- a/src/dynapi/SDL_dynapi.c
+++ b/src/dynapi/SDL_dynapi.c
@@ -264,29 +264,58 @@ static SDL_INLINE void *get_sdlapi_entry(const char *fname, const char *sym)
#endif
+static void dynapi_warn(const char *msg)
+{
+ const char *caption = "SDL Dynamic API Failure!";
+ /* SDL_ShowSimpleMessageBox() is a too heavy for here. */
+ #if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__)
+ MessageBoxA(NULL, msg, caption, MB_OK | MB_ICONERROR);
+ #else
+ fprintf(stderr, "\n\n%s\n%s\n\n", caption, msg);
+ fflush(stderr);
+ #endif
+}
+
+/* This is not declared in any header, although it is shared between some
+ parts of SDL, because we don't want anything calling it without an
+ extremely good reason. */
+#if defined(__WATCOMC__)
+void SDL_ExitProcess(const int exitcode);
+#pragma aux SDL_ExitProcess aborts;
+#endif
+SDL_NORETURN void SDL_ExitProcess(const int exitcode);
+
+
static void
SDL_InitDynamicAPILocked(void)
{
const char *libname = SDL_getenv_REAL("SDL_DYNAMIC_API");
SDL_DYNAPI_ENTRYFN entry = NULL; /* funcs from here by default. */
+ SDL_bool use_internal = SDL_TRUE;
if (libname) {
entry = (SDL_DYNAPI_ENTRYFN) get_sdlapi_entry(libname, "SDL_DYNAPI_entry");
if (!entry) {
- /* !!! FIXME: fail to startup here instead? */
- /* !!! FIXME: definitely warn user. */
- /* Just fill in the function pointers from this library. */
+ dynapi_warn("Couldn't load overriding SDL library. Please fix or remove the SDL_DYNAMIC_API environment variable. Using the default SDL.");
+ /* Just fill in the function pointers from this library, later. */
}
}
- if (!entry || (entry(SDL_DYNAPI_VERSION, &jump_table, sizeof (jump_table)) < 0)) {
- /* !!! FIXME: fail to startup here instead? */
- /* !!! FIXME: definitely warn user. */
- /* Just fill in the function pointers from this library. */
- if (!entry) {
- if (!initialize_jumptable(SDL_DYNAPI_VERSION, &jump_table, sizeof (jump_table))) {
- /* !!! FIXME: now we're screwed. Should definitely abort now. */
- }
+ if (entry) {
+ if (entry(SDL_DYNAPI_VERSION, &jump_table, sizeof (jump_table)) < 0) {
+ dynapi_warn("Couldn't override SDL library. Using a newer SDL build might help. Please fix or remove the SDL_DYNAMIC_API environment variable. Using the default SDL.");
+ /* Just fill in the function pointers from this library, later. */
+ } else {
+ use_internal = SDL_FALSE; /* We overrode SDL! Don't use the internal version! */
+ }
+ }
+
+ /* Just fill in the function pointers from this library. */
+ if (use_internal) {
+ if (initialize_jumptable(SDL_DYNAPI_VERSION, &jump_table, sizeof (jump_table)) < 0) {
+ /* Now we're screwed. Should definitely abort now. */
+ dynapi_warn("Failed to initialize internal SDL dynapi. As this would otherwise crash, we have to abort now.");
+ SDL_ExitProcess(86);
}
}