From: Ivan Maidanski Date: Sun, 24 Jun 2012 08:49:10 +0000 (+0400) Subject: Call GC_on_abort (with NULL argument) on exit(1) X-Git-Tag: gc7_4_0~267 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=215d710e39b5f9df733525b97ff8c39cb659c7b0;p=gc Call GC_on_abort (with NULL argument) on exit(1) * include/private/gc_priv.h (EXIT): Call GC_on_abort(NULL) before exit(1) (unless PCR) enabling the collector to enter a tight loop (for debugging purpose) on abnormal EXIT if "GC_LOOP_ON_ABORT" environment variable is set. * misc.c (GC_on_abort): Allow "msg" argument to be NULL (skip printing the message in such a case); update comment. --- diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index f7641dea..5ba0f718 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -493,7 +493,7 @@ typedef char * ptr_t; /* A generic pointer to which we can add */ # ifdef PCR # define EXIT() PCR_Base_Exit(1,PCR_waitForever) # else -# define EXIT() (void)exit(1) +# define EXIT() (GC_on_abort(NULL), exit(1 /* EXIT_FAILURE */)) # endif /* Print warning message, e.g. almost out of memory. */ diff --git a/misc.c b/misc.c index ad3ac092..deecc0ef 100644 --- a/misc.c +++ b/misc.c @@ -1460,32 +1460,37 @@ GC_API GC_warn_proc GC_CALL GC_get_warn_proc(void) } #if !defined(PCR) && !defined(SMALL_CONFIG) - /* Print (or display) a message before abort. msg must not be NULL. */ + /* Print (or display) a message before abnormal exit (including */ + /* abort). Invoked from ABORT(msg) macro (there msg is non-NULL) */ + /* and from EXIT() macro (msg is NULL in that case). */ void GC_on_abort(const char *msg) { -# if defined(MSWIN32) -# ifndef DONT_USE_USER32_DLL - /* Use static binding to "user32.dll". */ - (void)MessageBoxA(NULL, msg, "Fatal error in GC", MB_ICONERROR|MB_OK); -# else - /* This simplifies linking - resolve "MessageBoxA" at run-time. */ - HINSTANCE hU32 = LoadLibrary(TEXT("user32.dll")); - if (hU32) { - FARPROC pfn = GetProcAddress(hU32, "MessageBoxA"); - if (pfn) - (void)(*(int (WINAPI *)(HWND, LPCSTR, LPCSTR, UINT))pfn)( - NULL /* hWnd */, msg, "Fatal error in GC", - MB_ICONERROR | MB_OK); - (void)FreeLibrary(hU32); - } + if (msg != NULL) { +# if defined(MSWIN32) +# ifndef DONT_USE_USER32_DLL + /* Use static binding to "user32.dll". */ + (void)MessageBoxA(NULL, msg, "Fatal error in GC", + MB_ICONERROR | MB_OK); +# else + /* This simplifies linking - resolve "MessageBoxA" at run-time. */ + HINSTANCE hU32 = LoadLibrary(TEXT("user32.dll")); + if (hU32) { + FARPROC pfn = GetProcAddress(hU32, "MessageBoxA"); + if (pfn) + (void)(*(int (WINAPI *)(HWND, LPCSTR, LPCSTR, UINT))pfn)( + NULL /* hWnd */, msg, "Fatal error in GC", + MB_ICONERROR | MB_OK); + (void)FreeLibrary(hU32); + } +# endif + /* Also duplicate msg to GC log file. */ # endif - /* Also duplicate msg to GC log file. */ -# endif /* Avoid calling GC_err_printf() here, as GC_on_abort() could be */ /* called from it. Note 1: this is not an atomic output. */ /* Note 2: possible write errors are ignored. */ if (WRITE(GC_stderr, (void *)msg, strlen(msg)) >= 0) (void)WRITE(GC_stderr, (void *)("\n"), 1); + } if (GETENV("GC_LOOP_ON_ABORT") != NULL) { /* In many cases it's easier to debug a running process. */