SDL  2.0
SDL_assert.c File Reference
#include "./SDL_internal.h"
#include "SDL.h"
#include "SDL_atomic.h"
#include "SDL_messagebox.h"
#include "SDL_video.h"
#include "SDL_assert.h"
#include "SDL_assert_c.h"
#include "video/SDL_sysvideo.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+ Include dependency graph for SDL_assert.c:

Go to the source code of this file.

Macros

#define ENDLINE   "\n"
 

Functions

static SDL_assert_state SDL_PromptAssertion (const SDL_assert_data *data, void *userdata)
 
static void debug_print (const char *fmt,...)
 
static void SDL_AddAssertionToReport (SDL_assert_data *data)
 
static void SDL_GenerateAssertionReport (void)
 
static SDL_NORETURN void SDL_ExitProcess (int exitcode)
 
static SDL_NORETURN void SDL_AbortAssertion (void)
 
SDL_assert_state SDL_ReportAssertion (SDL_assert_data *data, const char *func, const char *file, int line)
 
void SDL_AssertionsQuit (void)
 
void SDL_SetAssertionHandler (SDL_AssertionHandler handler, void *userdata)
 Set an application-defined assertion handler. More...
 
const SDL_assert_dataSDL_GetAssertionReport (void)
 Get a list of all assertion failures. More...
 
void SDL_ResetAssertionReport (void)
 Reset the list of all assertion failures. More...
 
SDL_AssertionHandler SDL_GetDefaultAssertionHandler (void)
 Get the default assertion handler. More...
 
SDL_AssertionHandler SDL_GetAssertionHandler (void **userdata)
 Get the current assertion handler. More...
 

Variables

static SDL_assert_datatriggered_assertions = NULL
 
static SDL_mutexassertion_mutex = NULL
 
static SDL_AssertionHandler assertion_handler = SDL_PromptAssertion
 
static voidassertion_userdata = NULL
 

Macro Definition Documentation

◆ ENDLINE

#define ENDLINE   "\n"

Referenced by SDL_PromptAssertion().

Function Documentation

◆ debug_print()

static void debug_print ( const char *  fmt,
  ... 
)
static

Definition at line 74 of file SDL_assert.c.

References SDL_LOG_CATEGORY_ASSERT, SDL_LOG_PRIORITY_WARN, and SDL_LogMessageV.

Referenced by SDL_GenerateAssertionReport(), and SDL_PromptAssertion().

75 {
76  va_list ap;
77  va_start(ap, fmt);
79  va_end(ap);
80 }
#define SDL_LogMessageV

◆ SDL_AbortAssertion()

static SDL_NORETURN void SDL_AbortAssertion ( void  )
static

Definition at line 153 of file SDL_assert.c.

References SDL_assert_state, SDL_ExitProcess(), SDL_Quit, and SDLCALL.

Referenced by SDL_ReportAssertion().

154 {
155  SDL_Quit();
156  SDL_ExitProcess(42);
157 }
#define SDL_Quit
static SDL_NORETURN void SDL_ExitProcess(int exitcode)
Definition: SDL_assert.c:126

◆ SDL_AddAssertionToReport()

static void SDL_AddAssertionToReport ( SDL_assert_data data)
static

Definition at line 83 of file SDL_assert.c.

References triggered_assertions.

Referenced by SDL_ReportAssertion().

84 {
85  /* (data) is always a static struct defined with the assert macros, so
86  we don't have to worry about copying or allocating them. */
87  data->trigger_count++;
88  if (data->trigger_count == 1) { /* not yet added? */
89  data->next = triggered_assertions;
91  }
92 }
static SDL_assert_data * triggered_assertions
Definition: SDL_assert.c:59
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974

◆ SDL_AssertionsQuit()

void SDL_AssertionsQuit ( void  )

Definition at line 404 of file SDL_assert.c.

References NULL, SDL_DestroyMutex, and SDL_GenerateAssertionReport().

Referenced by SDL_Quit().

405 {
407 #ifndef SDL_THREADS_DISABLED
408  if (assertion_mutex != NULL) {
411  }
412 #endif
413 }
static void SDL_GenerateAssertionReport(void)
Definition: SDL_assert.c:95
#define NULL
Definition: begin_code.h:167
#define SDL_DestroyMutex
static SDL_mutex * assertion_mutex
Definition: SDL_assert.c:62

◆ SDL_ExitProcess()

static SDL_NORETURN void SDL_ExitProcess ( int  exitcode)
static

Definition at line 126 of file SDL_assert.c.

Referenced by SDL_AbortAssertion(), and SDL_ReportAssertion().

127 {
128 #ifdef __WIN32__
129  /* "if you do not know the state of all threads in your process, it is
130  better to call TerminateProcess than ExitProcess"
131  https://msdn.microsoft.com/en-us/library/windows/desktop/ms682658(v=vs.85).aspx */
132  TerminateProcess(GetCurrentProcess(), exitcode);
133  /* MingW doesn't have TerminateProcess marked as noreturn, so add an
134  ExitProcess here that will never be reached but make MingW happy. */
135  ExitProcess(exitcode);
136 #elif defined(__EMSCRIPTEN__)
137  emscripten_cancel_main_loop(); /* this should "kill" the app. */
138  emscripten_force_exit(exitcode); /* this should "kill" the app. */
139  exit(exitcode);
140 #elif defined(__HAIKU__) /* Haiku has _Exit, but it's not marked noreturn. */
141  _exit(exitcode);
142 #elif defined(HAVE__EXIT) /* Upper case _Exit() */
143  _Exit(exitcode);
144 #else
145  _exit(exitcode);
146 #endif
147 }

◆ SDL_GenerateAssertionReport()

static void SDL_GenerateAssertionReport ( void  )
static

Definition at line 95 of file SDL_assert.c.

References assertion_handler, debug_print(), NULL, SDL_assert_data, SDL_PromptAssertion(), SDL_ResetAssertionReport(), and triggered_assertions.

Referenced by SDL_AssertionsQuit().

96 {
98 
99  /* only do this if the app hasn't assigned an assertion handler. */
100  if ((item != NULL) && (assertion_handler != SDL_PromptAssertion)) {
101  debug_print("\n\nSDL assertion report.\n");
102  debug_print("All SDL assertions between last init/quit:\n\n");
103 
104  while (item != NULL) {
105  debug_print(
106  "'%s'\n"
107  " * %s (%s:%d)\n"
108  " * triggered %u time%s.\n"
109  " * always ignore: %s.\n",
110  item->condition, item->function, item->filename,
111  item->linenum, item->trigger_count,
112  (item->trigger_count == 1) ? "" : "s",
113  item->always_ignore ? "yes" : "no");
114  item = item->next;
115  }
116  debug_print("\n");
117 
119  }
120 }
static SDL_AssertionHandler assertion_handler
Definition: SDL_assert.c:65
static SDL_assert_data * triggered_assertions
Definition: SDL_assert.c:59
void SDL_ResetAssertionReport(void)
Reset the list of all assertion failures.
Definition: SDL_assert.c:431
static SDL_assert_state SDL_PromptAssertion(const SDL_assert_data *data, void *userdata)
Definition: SDL_assert.c:161
static void debug_print(const char *fmt,...)
Definition: SDL_assert.c:74
#define NULL
Definition: begin_code.h:167
#define SDL_assert_data
Definition: SDL_assert.h:280

◆ SDL_GetAssertionHandler()

SDL_AssertionHandler SDL_GetAssertionHandler ( void **  puserdata)

Get the current assertion handler.

This returns the function pointer that is called when an assertion is triggered. This is either the value last passed to SDL_SetAssertionHandler(), or if no application-specified function is set, is equivalent to calling SDL_GetDefaultAssertionHandler().

Parameters
puserdataPointer to a void*, which will store the "userdata" pointer that was passed to SDL_SetAssertionHandler(). This value will always be NULL for the default handler. If you don't care about this data, it is safe to pass a NULL pointer to this function to ignore it.
Returns
The SDL_AssertionHandler that is called when an assert triggers.

Definition at line 450 of file SDL_assert.c.

References assertion_handler, assertion_userdata, and NULL.

451 {
452  if (userdata != NULL) {
453  *userdata = assertion_userdata;
454  }
455  return assertion_handler;
456 }
static SDL_AssertionHandler assertion_handler
Definition: SDL_assert.c:65
static void * assertion_userdata
Definition: SDL_assert.c:66
#define NULL
Definition: begin_code.h:167

◆ SDL_GetAssertionReport()

const SDL_assert_data* SDL_GetAssertionReport ( void  )

Get a list of all assertion failures.

Get all assertions triggered since last call to SDL_ResetAssertionReport(), or the start of the program.

The proper way to examine this data looks something like this:

const SDL_AssertData *item = SDL_GetAssertionReport(); while (item) { printf("'%s', %s (%s:%d), triggered %u times, always ignore: %s.\\n", item->condition, item->function, item->filename, item->linenum, item->trigger_count, item->always_ignore ? "yes" : "no"); item = item->next; }

Returns
List of all assertions.
See also
SDL_ResetAssertionReport

Definition at line 426 of file SDL_assert.c.

References triggered_assertions.

427 {
428  return triggered_assertions;
429 }
static SDL_assert_data * triggered_assertions
Definition: SDL_assert.c:59

◆ SDL_GetDefaultAssertionHandler()

SDL_AssertionHandler SDL_GetDefaultAssertionHandler ( void  )

Get the default assertion handler.

This returns the function pointer that is called by default when an assertion is triggered. This is an internal function provided by SDL, that is used for assertions when SDL_SetAssertionHandler() hasn't been used to provide a different function.

Returns
The default SDL_AssertionHandler that is called when an assert triggers.

Definition at line 445 of file SDL_assert.c.

References SDL_PromptAssertion().

446 {
447  return SDL_PromptAssertion;
448 }
static SDL_assert_state SDL_PromptAssertion(const SDL_assert_data *data, void *userdata)
Definition: SDL_assert.c:161

◆ SDL_PromptAssertion()

static SDL_assert_state SDL_PromptAssertion ( const SDL_assert_data data,
void userdata 
)
static

Definition at line 161 of file SDL_assert.c.

References SDL_MessageBoxData::buttons, debug_print(), ENDLINE, SDL_MessageBoxData::flags, free, SDL_MessageBoxData::message, NULL, SDL_MessageBoxData::numbuttons, SDL_arraysize, SDL_assert_state, SDL_ASSERTION_ABORT, SDL_ASSERTION_ALWAYS_IGNORE, SDL_ASSERTION_BREAK, SDL_ASSERTION_IGNORE, SDL_ASSERTION_RETRY, SDL_FALSE, SDL_getenv, SDL_GetFocusWindow(), SDL_GetWindowFlags, SDL_MAX_LOG_MESSAGE, SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, SDL_MESSAGEBOX_WARNING, SDL_MinimizeWindow, SDL_RestoreWindow, SDL_ShowMessageBox, SDL_snprintf, SDL_stack_alloc, SDL_stack_free, SDL_strcmp, SDL_strncmp, SDL_TRUE, SDL_WINDOW_FULLSCREEN, SDL_zero, state, SDL_MessageBoxData::title, void, and SDL_MessageBoxData::window.

Referenced by SDL_GenerateAssertionReport(), SDL_GetDefaultAssertionHandler(), and SDL_SetAssertionHandler().

162 {
163 #ifdef __WIN32__
164  #define ENDLINE "\r\n"
165 #else
166  #define ENDLINE "\n"
167 #endif
168 
169  const char *envr;
172  SDL_MessageBoxData messagebox;
173  SDL_MessageBoxButtonData buttons[] = {
174  { 0, SDL_ASSERTION_RETRY, "Retry" },
175  { 0, SDL_ASSERTION_BREAK, "Break" },
176  { 0, SDL_ASSERTION_ABORT, "Abort" },
178  SDL_ASSERTION_IGNORE, "Ignore" },
180  SDL_ASSERTION_ALWAYS_IGNORE, "Always Ignore" }
181  };
182  char *message;
183  int selected;
184 
185  (void) userdata; /* unused in default handler. */
186 
187  /* !!! FIXME: why is this using SDL_stack_alloc and not just "char message[SDL_MAX_LOG_MESSAGE];" ? */
188  message = SDL_stack_alloc(char, SDL_MAX_LOG_MESSAGE);
189  if (!message) {
190  /* Uh oh, we're in real trouble now... */
191  return SDL_ASSERTION_ABORT;
192  }
194  "Assertion failure at %s (%s:%d), triggered %u %s:" ENDLINE
195  " '%s'",
196  data->function, data->filename, data->linenum,
197  data->trigger_count, (data->trigger_count == 1) ? "time" : "times",
198  data->condition);
199 
200  debug_print("\n\n%s\n\n", message);
201 
202  /* let env. variable override, so unit tests won't block in a GUI. */
203  envr = SDL_getenv("SDL_ASSERT");
204  if (envr != NULL) {
205  SDL_stack_free(message);
206 
207  if (SDL_strcmp(envr, "abort") == 0) {
208  return SDL_ASSERTION_ABORT;
209  } else if (SDL_strcmp(envr, "break") == 0) {
210  return SDL_ASSERTION_BREAK;
211  } else if (SDL_strcmp(envr, "retry") == 0) {
212  return SDL_ASSERTION_RETRY;
213  } else if (SDL_strcmp(envr, "ignore") == 0) {
214  return SDL_ASSERTION_IGNORE;
215  } else if (SDL_strcmp(envr, "always_ignore") == 0) {
217  } else {
218  return SDL_ASSERTION_ABORT; /* oh well. */
219  }
220  }
221 
222  /* Leave fullscreen mode, if possible (scary!) */
223  window = SDL_GetFocusWindow();
224  if (window) {
226  SDL_MinimizeWindow(window);
227  } else {
228  /* !!! FIXME: ungrab the input if we're not fullscreen? */
229  /* No need to mess with the window */
230  window = NULL;
231  }
232  }
233 
234  /* Show a messagebox if we can, otherwise fall back to stdio */
235  SDL_zero(messagebox);
236  messagebox.flags = SDL_MESSAGEBOX_WARNING;
237  messagebox.window = window;
238  messagebox.title = "Assertion Failed";
239  messagebox.message = message;
240  messagebox.numbuttons = SDL_arraysize(buttons);
241  messagebox.buttons = buttons;
242 
243  if (SDL_ShowMessageBox(&messagebox, &selected) == 0) {
244  if (selected == -1) {
245  state = SDL_ASSERTION_IGNORE;
246  } else {
247  state = (SDL_assert_state)selected;
248  }
249  }
250 
251  else
252  {
253 #if defined(__EMSCRIPTEN__)
254  /* This is nasty, but we can't block on a custom UI. */
255  for ( ; ; ) {
256  SDL_bool okay = SDL_TRUE;
257  char *buf = (char *) EM_ASM_INT({
258  var str =
259  UTF8ToString($0) + '\n\n' +
260  'Abort/Retry/Ignore/AlwaysIgnore? [ariA] :';
261  var reply = window.prompt(str, "i");
262  if (reply === null) {
263  reply = "i";
264  }
265  return allocate(intArrayFromString(reply), 'i8', ALLOC_NORMAL);
266  }, message);
267 
268  if (SDL_strcmp(buf, "a") == 0) {
269  state = SDL_ASSERTION_ABORT;
270  /* (currently) no break functionality on Emscripten
271  } else if (SDL_strcmp(buf, "b") == 0) {
272  state = SDL_ASSERTION_BREAK; */
273  } else if (SDL_strcmp(buf, "r") == 0) {
274  state = SDL_ASSERTION_RETRY;
275  } else if (SDL_strcmp(buf, "i") == 0) {
276  state = SDL_ASSERTION_IGNORE;
277  } else if (SDL_strcmp(buf, "A") == 0) {
279  } else {
280  okay = SDL_FALSE;
281  }
282  free(buf);
283 
284  if (okay) {
285  break;
286  }
287  }
288 #elif defined(HAVE_STDIO_H)
289  /* this is a little hacky. */
290  for ( ; ; ) {
291  char buf[32];
292  fprintf(stderr, "Abort/Break/Retry/Ignore/AlwaysIgnore? [abriA] : ");
293  fflush(stderr);
294  if (fgets(buf, sizeof (buf), stdin) == NULL) {
295  break;
296  }
297 
298  if (SDL_strncmp(buf, "a", 1) == 0) {
299  state = SDL_ASSERTION_ABORT;
300  break;
301  } else if (SDL_strncmp(buf, "b", 1) == 0) {
302  state = SDL_ASSERTION_BREAK;
303  break;
304  } else if (SDL_strncmp(buf, "r", 1) == 0) {
305  state = SDL_ASSERTION_RETRY;
306  break;
307  } else if (SDL_strncmp(buf, "i", 1) == 0) {
308  state = SDL_ASSERTION_IGNORE;
309  break;
310  } else if (SDL_strncmp(buf, "A", 1) == 0) {
312  break;
313  }
314  }
315 #endif /* HAVE_STDIO_H */
316  }
317 
318  /* Re-enter fullscreen mode */
319  if (window) {
320  SDL_RestoreWindow(window);
321  }
322 
323  SDL_stack_free(message);
324 
325  return state;
326 }
const char * message
#define SDL_MAX_LOG_MESSAGE
The maximum size of a log message.
Definition: SDL_log.h:54
const char * title
SDL_Window * window
GLuint GLsizei const GLchar * message
struct xkb_state * state
SDL_EventEntry * free
Definition: SDL_events.c:82
#define SDL_GetWindowFlags
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
#define SDL_MinimizeWindow
#define SDL_strncmp
static void debug_print(const char *fmt,...)
Definition: SDL_assert.c:74
Individual button data.
#define SDL_stack_alloc(type, count)
Definition: SDL_stdinc.h:354
SDL_Window * SDL_GetFocusWindow(void)
Definition: SDL_video.c:2696
#define SDL_zero(x)
Definition: SDL_stdinc.h:416
GLenum GLuint GLenum GLsizei const GLchar * buf
const SDL_MessageBoxButtonData * buttons
MessageBox structure containing title, text, window, etc.
#define SDL_RestoreWindow
#define SDL_getenv
#define SDL_ShowMessageBox
#define NULL
Definition: begin_code.h:167
SDL_bool
Definition: SDL_stdinc.h:161
#define SDL_assert_state
Definition: SDL_assert.h:279
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 void
The type used to identify a window.
Definition: SDL_sysvideo.h:73
#define SDL_snprintf
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:115
#define SDL_strcmp
#define SDL_stack_free(data)
Definition: SDL_stdinc.h:355
#define ENDLINE

◆ SDL_ReportAssertion()

SDL_assert_state SDL_ReportAssertion ( SDL_assert_data data,
const char *  func,
const char *  file,
int  line 
)

Definition at line 330 of file SDL_assert.c.

References assertion_handler, assertion_userdata, NULL, SDL_AbortAssertion(), SDL_AddAssertionToReport(), SDL_assert_state, SDL_ASSERTION_ABORT, SDL_ASSERTION_ALWAYS_IGNORE, SDL_ASSERTION_BREAK, SDL_ASSERTION_IGNORE, SDL_ASSERTION_RETRY, SDL_AtomicLock, SDL_AtomicUnlock, SDL_CreateMutex, SDL_ExitProcess(), SDL_LockMutex, SDL_UnlockMutex, and state.

332 {
334  static int assertion_running = 0;
335 
336 #ifndef SDL_THREADS_DISABLED
337  static SDL_SpinLock spinlock = 0;
338  SDL_AtomicLock(&spinlock);
339  if (assertion_mutex == NULL) { /* never called SDL_Init()? */
341  if (assertion_mutex == NULL) {
342  SDL_AtomicUnlock(&spinlock);
343  return SDL_ASSERTION_IGNORE; /* oh well, I guess. */
344  }
345  }
346  SDL_AtomicUnlock(&spinlock);
347 
348  if (SDL_LockMutex(assertion_mutex) < 0) {
349  return SDL_ASSERTION_IGNORE; /* oh well, I guess. */
350  }
351 #endif
352 
353  /* doing this because Visual C is upset over assigning in the macro. */
354  if (data->trigger_count == 0) {
355  data->function = func;
356  data->filename = file;
357  data->linenum = line;
358  }
359 
361 
362  assertion_running++;
363  if (assertion_running > 1) { /* assert during assert! Abort. */
364  if (assertion_running == 2) {
366  } else if (assertion_running == 3) { /* Abort asserted! */
367  SDL_ExitProcess(42);
368  } else {
369  while (1) { /* do nothing but spin; what else can you do?! */ }
370  }
371  }
372 
373  if (!data->always_ignore) {
375  }
376 
377  switch (state)
378  {
380  state = SDL_ASSERTION_IGNORE;
381  data->always_ignore = 1;
382  break;
383 
385  case SDL_ASSERTION_RETRY:
386  case SDL_ASSERTION_BREAK:
387  break; /* macro handles these. */
388 
389  case SDL_ASSERTION_ABORT:
391  /*break; ...shouldn't return, but oh well. */
392  }
393 
394  assertion_running--;
395 
396 #ifndef SDL_THREADS_DISABLED
398 #endif
399 
400  return state;
401 }
static SDL_AssertionHandler assertion_handler
Definition: SDL_assert.c:65
#define SDL_LockMutex
#define SDL_AtomicLock
#define SDL_CreateMutex
struct xkb_state * state
static void * assertion_userdata
Definition: SDL_assert.c:66
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
#define SDL_AtomicUnlock
static void SDL_AddAssertionToReport(SDL_assert_data *data)
Definition: SDL_assert.c:83
static SDL_NORETURN void SDL_AbortAssertion(void)
Definition: SDL_assert.c:153
#define NULL
Definition: begin_code.h:167
static SDL_NORETURN void SDL_ExitProcess(int exitcode)
Definition: SDL_assert.c:126
#define SDL_assert_state
Definition: SDL_assert.h:279
GLenum func
static SDL_mutex * assertion_mutex
Definition: SDL_assert.c:62
#define SDL_UnlockMutex
int SDL_SpinLock
Definition: SDL_atomic.h:89

◆ SDL_ResetAssertionReport()

void SDL_ResetAssertionReport ( void  )

Reset the list of all assertion failures.

Reset list of all assertions triggered.

See also
SDL_GetAssertionReport

Definition at line 431 of file SDL_assert.c.

References NULL, SDL_assert_data, SDL_FALSE, and triggered_assertions.

Referenced by SDL_GenerateAssertionReport().

432 {
433  SDL_assert_data *next = NULL;
434  SDL_assert_data *item;
435  for (item = triggered_assertions; item != NULL; item = next) {
436  next = (SDL_assert_data *) item->next;
437  item->always_ignore = SDL_FALSE;
438  item->trigger_count = 0;
439  item->next = NULL;
440  }
441 
443 }
static SDL_assert_data * triggered_assertions
Definition: SDL_assert.c:59
#define NULL
Definition: begin_code.h:167
#define SDL_assert_data
Definition: SDL_assert.h:280

◆ SDL_SetAssertionHandler()

void SDL_SetAssertionHandler ( SDL_AssertionHandler  handler,
void userdata 
)

Set an application-defined assertion handler.

This allows an app to show its own assertion UI and/or force the response to an assertion failure. If the app doesn't provide this, SDL will try to do the right thing, popping up a system-specific GUI dialog, and probably minimizing any fullscreen windows.

This callback may fire from any thread, but it runs wrapped in a mutex, so it will only fire from one thread at a time.

Setting the callback to NULL restores SDL's original internal handler.

This callback is NOT reset to SDL's internal handler upon SDL_Quit()!

Return SDL_AssertState value of how to handle the assertion failure.

Parameters
handlerCallback function, called when an assertion fails.
userdataA pointer passed to the callback as-is.

Definition at line 415 of file SDL_assert.c.

References assertion_handler, assertion_userdata, NULL, and SDL_PromptAssertion().

416 {
417  if (handler != NULL) {
418  assertion_handler = handler;
419  assertion_userdata = userdata;
420  } else {
423  }
424 }
static SDL_AssertionHandler assertion_handler
Definition: SDL_assert.c:65
static void * assertion_userdata
Definition: SDL_assert.c:66
static SDL_assert_state SDL_PromptAssertion(const SDL_assert_data *data, void *userdata)
Definition: SDL_assert.c:161
#define NULL
Definition: begin_code.h:167

Variable Documentation

◆ assertion_handler

◆ assertion_mutex

SDL_mutex* assertion_mutex = NULL
static

Definition at line 62 of file SDL_assert.c.

◆ assertion_userdata

void* assertion_userdata = NULL
static

◆ triggered_assertions