]> granicus.if.org Git - gc/commitdiff
Call GC_on_abort (with NULL argument) on exit(1)
authorIvan Maidanski <ivmai@mail.ru>
Sun, 24 Jun 2012 08:49:10 +0000 (12:49 +0400)
committerIvan Maidanski <ivmai@mail.ru>
Sun, 24 Jun 2012 08:50:10 +0000 (12:50 +0400)
* 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.

include/private/gc_priv.h
misc.c

index f7641deadb688c64a8db87a76ad3640bbe38dfd6..5ba0f718310c320ba144bbff76d996db6415cf51 100644 (file)
@@ -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 ad3ac09253d5676a47b0a1d2355d3d466a7dd5a6..deecc0effe5886fb36de5d7c2b75c79003178af0 100644 (file)
--- 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.    */