From b45f64113af0cb4c4766b7a0a9f3394d90dbfab3 Mon Sep 17 00:00:00 2001 From: Dasperal Date: Sat, 12 Oct 2024 20:32:20 +0300 Subject: [PATCH] Fix crush after error Caused by double iteration on one va_list --- src/i_system.c | 84 ++++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 44 deletions(-) diff --git a/src/i_system.c b/src/i_system.c index 9c802e7b..bbacebf7 100644 --- a/src/i_system.c +++ b/src/i_system.c @@ -194,7 +194,7 @@ boolean I_ConsoleStdout(void) // I_Quit // -static inline void do_quit(boolean is_error) +static inline void do_quit(const boolean is_error) { if(already_quitting) { @@ -203,13 +203,11 @@ static inline void do_quit(boolean is_error) "Внимание: обнаружен рекурсивный вызов I_Quit*.\n"); exit(-1); } - else - { - already_quitting = true; - } + + already_quitting = true; // Run through all exit functions - atexit_listentry_t* entry = exit_funcs; + const atexit_listentry_t* entry = exit_funcs; while(entry != NULL) { if(!is_error || entry->run_on_error) @@ -252,74 +250,72 @@ void I_Quit(void) do_quit(false); } -void _add_error(char* error, va_list argptr) +static inline message_t* _enqueue_message(const char* error, va_list arg_ptr) { - // Message first. - vprintf(error, argptr); + // Log message first + va_list arg_ptr_2; + va_copy(arg_ptr_2, arg_ptr); + vprintf(error, arg_ptr_2); + va_end(arg_ptr_2); printf("\n\n"); fflush(stdout); // Write a copy of the msg into buffer. message_t* msg = malloc(sizeof(message_t)); memset(msg->msgbuf, 0, sizeof(msg->msgbuf)); - M_vsnprintf(msg->msgbuf, sizeof(msg->msgbuf), error, argptr); + M_vsnprintf(msg->msgbuf, sizeof(msg->msgbuf), error, arg_ptr); - msg->type = SDL_MESSAGEBOX_ERROR; + // Link to message queue msg->next = message_queue; message_queue = msg; + + return msg; } -void I_QuitWithError(char* error, ...) +static inline void _add_message(const char* message, const va_list arg_ptr) { - va_list argptr; - va_start(argptr, error); - _add_error(error, argptr); - va_end(argptr); - - do_quit(true); + _enqueue_message(message, arg_ptr)->type = SDL_MESSAGEBOX_INFORMATION; } -void I_AddError(char* error, ...) +static inline void _add_error(const char* error, const va_list arg_ptr) { - va_list argptr; - va_start(argptr, error); - _add_error(error, argptr); - va_end(argptr); + _enqueue_message(error, arg_ptr)->type = SDL_MESSAGEBOX_ERROR; } -void _add_message(char* message, va_list argptr) +void I_QuitWithError(char* error, ...) { - // Message first. - vprintf(message, argptr); - printf("\n\n"); - fflush(stdout); + va_list arg_ptr; + va_start(arg_ptr, error); + _add_error(error, arg_ptr); + va_end(arg_ptr); - // Write a copy of the message into buffer. - message_t* msg = malloc(sizeof(message_t)); - memset(msg->msgbuf, 0, sizeof(msg->msgbuf)); - M_vsnprintf(msg->msgbuf, sizeof(msg->msgbuf), message, argptr); + do_quit(true); +} - msg->type = SDL_MESSAGEBOX_INFORMATION; - msg->next = message_queue; - message_queue = msg; +void I_AddError(char* error, ...) +{ + va_list arg_ptr; + va_start(arg_ptr, error); + _add_error(error, arg_ptr); + va_end(arg_ptr); } -void I_QuitWithMessage(char* error, ...) +void I_QuitWithMessage(char* message, ...) { - va_list argptr; - va_start(argptr, error); - _add_message(error, argptr); - va_end(argptr); + va_list arg_ptr; + va_start(arg_ptr, message); + _add_message(message, arg_ptr); + va_end(arg_ptr); do_quit(false); } void I_AddMessage(char* message, ...) { - va_list argptr; - va_start(argptr, message); - _add_message(message, argptr); - va_end(argptr); + va_list arg_ptr; + va_start(arg_ptr, message); + _add_message(message, arg_ptr); + va_end(arg_ptr); } //