4941d34ac775c6f2e82434867b9e7823387238c1
galt
  Sun Mar 5 15:04:00 2017 -0800
fixes #18983. hUserAbort in hg/lib/hCommon.c was not working right. In particular, although it sort of worked for errAbort, it did not work for hUserAbort. Hopefully this is now working better than ever.

diff --git src/hg/lib/hCommon.c src/hg/lib/hCommon.c
index 193a2bd..8eaedc1 100644
--- src/hg/lib/hCommon.c
+++ src/hg/lib/hCommon.c
@@ -321,73 +321,79 @@
 {
 puts("<!--hTableStart-->" "\n"
      "<TABLE BGCOLOR=\"#"HG_COL_BORDER"\" BORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"1\"><TR><TD>");
 puts("<TABLE BORDER=\"1\" BGCOLOR=\"#"HG_COL_INSIDE"\" CELLSPACING=\"0\">");
 }
 
 void hTableEnd()
 /* Close out table started with hTableStart() */
 {
 puts("</TABLE>");
 puts("</TD></TR></TABLE>");
 puts("<!--hTableEnd-->");
 }
 
 static boolean stackDumpDisabled = FALSE;  // prevent accidental recursion or undesired dumps
+static boolean hDumpAbortCalled = FALSE;
 
 static void hDumpStackAbortHandler()
 /* abort handle that prints stack dump then invokes the previous abort
  * handler on the stack. */
 {
-if (!stackDumpDisabled)
+if (stackDumpDisabled)
+    {
+    stackDumpDisabled = FALSE;
+    }
+else
     {
-    stackDumpDisabled = TRUE;
-    popAbortHandler(); // remove us from the stack
     dumpStack("\nStack dump:");
+    }
+hDumpAbortCalled = TRUE;
+popAbortHandler(); // remove us from the stack 
 // continue with next abort handler
 noWarnAbort();
 }
-}
 
 boolean hDumpStackEnabled(void)
 /* is browser.pstack enabled?  */
 {
 return cfgOptionBooleanDefault("browser.dumpStack", FALSE);
 }
 
 void hDumpStackDisallow(void)
 /* prevent any dumping of the stack */
 {
 stackDumpDisabled = TRUE;
 }
 
 void hDumpStackPushAbortHandler(void)
 /* push the stack dump abort handler on the stack if it's enabled.  This should be pushed
  * after the warn handle that will do the actual reporting */
 {
 if (hDumpStackEnabled())
     {
     errAbortDebugnPushPopErr();
     pushAbortHandler(hDumpStackAbortHandler);
     }
 }
 
 void hDumpStackPopAbortHandler()
 /* pop the stack dump abort handler from the stack if it's enabled */
 {
-if (hDumpStackEnabled() && !stackDumpDisabled)
+if (hDumpStackEnabled() && !hDumpAbortCalled)
     popAbortHandler();
+hDumpAbortCalled = FALSE;
 }
 
 void hVaUserAbort(char *format, va_list args)
 /* errAbort when a `user' error is detected.  This is an error that comes
  * from user input. This disables the logging stack dumps. */
 {
 hDumpStackDisallow();
 vaErrAbort(format, args);
 }
 
 void hUserAbort(char *format, ...)
 /* errAbort when a `user' error is detected.  This is an error that comes
  * from user input. This disables the logging stack dumps. */
 {
 va_list args;