assert: Remove use of alloca()

For short messages, use a stack buffer that is
significantly smaller than SDL_MAX_LOG_MESSAGE.

For larger messages, fall back to allocation.
main
Eddy Jansson 2022-04-29 14:05:15 +02:00 committed by Sam Lantinga
parent 97774cdf72
commit 73448fe245
1 changed files with 32 additions and 15 deletions

View File

@ -45,6 +45,8 @@
#include <emscripten.h> #include <emscripten.h>
#endif #endif
/* The size of the stack buffer to use for rendering assert messages. */
#define SDL_MAX_ASSERT_MESSAGE_STACK 256
static SDL_assert_state SDLCALL static SDL_assert_state SDLCALL
SDL_PromptAssertion(const SDL_assert_data *data, void *userdata); SDL_PromptAssertion(const SDL_assert_data *data, void *userdata);
@ -160,30 +162,43 @@ SDL_PromptAssertion(const SDL_assert_data *data, void *userdata)
{ SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT,
SDL_ASSERTION_ALWAYS_IGNORE, "Always Ignore" } SDL_ASSERTION_ALWAYS_IGNORE, "Always Ignore" }
}; };
char *message;
int selected; int selected;
char stack_buf[SDL_MAX_ASSERT_MESSAGE_STACK];
char *message = stack_buf;
size_t buf_len = sizeof(stack_buf);
size_t len;
(void) userdata; /* unused in default handler. */ (void) userdata; /* unused in default handler. */
/* !!! FIXME: why is this using SDL_stack_alloc and not just "char message[SDL_MAX_LOG_MESSAGE];" ? */ do {
message = SDL_stack_alloc(char, SDL_MAX_LOG_MESSAGE); /* Assume the output will fit... */
if (!message) { len = SDL_snprintf(message, buf_len,
/* Uh oh, we're in real trouble now... */ "Assertion failure at %s (%s:%d), triggered %u %s:" ENDLINE " '%s'",
return SDL_ASSERTION_ABORT; data->function, data->filename, data->linenum,
} data->trigger_count, (data->trigger_count == 1) ? "time" : "times",
SDL_snprintf(message, SDL_MAX_LOG_MESSAGE, data->condition);
"Assertion failure at %s (%s:%d), triggered %u %s:" ENDLINE
" '%s'", /* .. and if it didn't, allocate a bigger buffer and try again */
data->function, data->filename, data->linenum, if (len >= buf_len && message == stack_buf) {
data->trigger_count, (data->trigger_count == 1) ? "time" : "times", buf_len = SDL_MAX_LOG_MESSAGE;
data->condition); message = (char *)SDL_malloc(buf_len);
if (!message) {
/* Uh oh, we're in real trouble now... */
return SDL_ASSERTION_ABORT;
}
len = 0;
}
} while (len == 0);
debug_print("\n\n%s\n\n", message); debug_print("\n\n%s\n\n", message);
/* let env. variable override, so unit tests won't block in a GUI. */ /* let env. variable override, so unit tests won't block in a GUI. */
envr = SDL_getenv("SDL_ASSERT"); envr = SDL_getenv("SDL_ASSERT");
if (envr != NULL) { if (envr != NULL) {
SDL_stack_free(message); if (message != stack_buf) {
SDL_free(message);
}
if (SDL_strcmp(envr, "abort") == 0) { if (SDL_strcmp(envr, "abort") == 0) {
return SDL_ASSERTION_ABORT; return SDL_ASSERTION_ABORT;
@ -301,7 +316,9 @@ SDL_PromptAssertion(const SDL_assert_data *data, void *userdata)
SDL_RestoreWindow(window); SDL_RestoreWindow(window);
} }
SDL_stack_free(message); if (message != stack_buf) {
SDL_free(message);
}
return state; return state;
} }