Index: trunk/src/emx/src/lib/sys/signals.c
===================================================================
--- trunk/src/emx/src/lib/sys/signals.c	(revision 1880)
+++ trunk/src/emx/src/lib/sys/signals.c	(revision 1881)
@@ -206,4 +206,16 @@
     __LIBC_PTHREAD  pThrd;
 } SIGSCHEDENUMPARAM, *PSIGSCHEDENUMPARAM;
+
+
+/**
+ * Exception handler argument list.
+ */
+typedef struct XcptParams
+{
+    PEXCEPTIONREPORTRECORD       pXcptRepRec;
+    PEXCEPTIONREGISTRATIONRECORD pXcptRegRec;
+    PCONTEXTRECORD               pCtx;
+    PVOID                        pvWhatEver;
+} XCPTPARAMS, *PEXCPTPARAMS;
 
 
@@ -555,6 +567,5 @@
 static int              signalDeliver(__LIBC_PTHREAD pThrd, int iSignalNo, void *pvXcptParams);
 static void             signalTerminate(int iSignalNo) __dead2;
-static void             signalTerminateAbnormal(int iSignalNo) __dead2;
-static int              signalTerminateHex(char *pszBuf, unsigned u);
+static void             signalTerminateAbnormal(int iSignalNo, void *pvXcptParams) __dead2;
 static int              signalJobStop(int iSignalNo);
 static int              signalJobResume(void);
@@ -1012,5 +1023,5 @@
         LIBCLOG_MSG("we're toast!\n");
         DosWrite(HFILE_STDERR, szMsg, sizeof(szMsg) - 1, &cb);
-        signalTerminateAbnormal(iSignalNo);
+        signalTerminateAbnormal(iSignalNo, fFlags & __LIBC_BSRF_QUEUED ? NULL : pvXcptOrQueued);
     }
 
@@ -1778,5 +1789,5 @@
  * @param   iSignalNo           Deliver the first signal of this type no matter if it's
  *                              blocked or not. This is for use with hardware signals only!
- * @param   pvXcptParams        sPointer to exception parameter list is any.
+ * @param   pvXcptParams        Pointer to exception parameter list is any.
  */
 static int signalDeliver(__LIBC_PTHREAD pThrd, int iSignalNo, void *pvXcptParams)
@@ -1883,5 +1894,5 @@
                 case SPA_CORE:
                 case SPA_NEXT_CORE:
-                    signalTerminateAbnormal(iSignalNo);
+                    signalTerminateAbnormal(iSignalNo, pvXcptParams);
                     break;
 
@@ -2037,4 +2048,5 @@
 }
 
+
 /**
  * Cause immediate process termination because of the given signal.
@@ -2050,106 +2062,26 @@
      */
     __libc_spmTerm(__LIBC_EXIT_REASON_SIGNAL_BASE + iSignalNo, 127);
-    LIBCLOG_MSG("Calling DosExit(,127)\n");
+    LIBCLOG_MSG("Calling DosKillProcess()\n");
     for (;;)
     {
         DosKillProcess(DKP_PROCESS, 0);
-        DosExit(EXIT_THREAD, 127);
-    }
-}
-
-/**
- * Cause immediate process termination because of the given signal.
- *
- * @param   iSignalNo   Signal causing the termination.
- */
-static void signalTerminateAbnormal(int iSignalNo)
-{
-    LIBCLOG_ENTER("iSignalNo=%d\n", iSignalNo);
-    /*
-     * Set the exit reason in SPM.
-     */
-    __libc_spmTerm(__LIBC_EXIT_REASON_SIGNAL_BASE + iSignalNo, 127);
-
-    /*
-     * Before we go crazy here, let's release the semaphore.
-     *
-     * If possible we'll stay in the must complete section to
-     * be sure we get to the exit. If not we'll have to mess with
-     * exception handlers and such now.
-     */
-    //if (__libc_back_signalSemIsOwner())
-    //    DosReleaseMutexSem(ghmtxSignals);
-
-    /*
-     * Terminate the exception handler chain to avoid recursive trouble.
-     */
-    FS_VAR();
-    FS_SAVE_LOAD();
-    PTIB pTib;
-    PPIB pPib;
-    DosGetInfoBlocks(&pTib, &pPib);
-    pTib->tib_pexchain = END_OF_CHAIN;
-
-    /*
-     * Write message to stderr.
-     */
-    ULONG   cb;
-    if (iSignalNo == SIGABRT)
-    {
-        static const char szMsg[] = "\n\rAbnormal program termination";
-        DosWrite(HFILE_STDERR, szMsg, sizeof(szMsg) - 1, &cb);
-    }
-    else
-    {
-        static const char szMsg[] = "\n\rProcess terminated by ";
-        DosWrite(HFILE_STDERR, szMsg, sizeof(szMsg) - 1, &cb);
-
-        const char *psz = "unknown signal";
-        if (iSignalNo < sizeof(gaszSignalNames) / sizeof(gaszSignalNames[0]))
-            psz = gaszSignalNames[iSignalNo];
-        for (cb = 0; psz[cb];)
-            cb++;
-        DosWrite(HFILE_STDERR, psz, cb, &cb);
-    }
-
-    /* pid */
-    static const char szMsgPid[] = " - pid=0x";
-    DosWrite(HFILE_STDERR, szMsgPid, sizeof(szMsgPid) - 1, &cb);
-    char szHexNum[12];
-    cb = signalTerminateHex(szHexNum, pPib->pib_ulpid);
-    DosWrite(HFILE_STDERR, szHexNum, cb, &cb);
-
-    /* tid */
-    static const char szMsgTid[] = " - tid=0x";
-    DosWrite(HFILE_STDERR, szMsgTid, sizeof(szMsgTid) - 1, &cb);
-    cb = signalTerminateHex(szHexNum, pTib->tib_ptib2->tib2_ultid);
-    DosWrite(HFILE_STDERR, szHexNum, cb, &cb);
-
-    /* executable name. */
-    static char szExeName[CCHMAXPATH];
-    if (!DosQueryModuleName(pPib->pib_hmte, sizeof(szExeName), &szExeName[0]))
-    {
-        static const char szHypen[] = " - ";
-        DosWrite(HFILE_STDERR, szHypen, sizeof(szHypen) - 1, &cb);
-
-        for (cb = 0; szExeName[cb];)
-            cb++;
-        DosWrite(HFILE_STDERR, szExeName, cb, &cb);
-    }
-
-    /* final newline */
-    static const char szNewLine[] = "\r\n";
-    DosWrite(HFILE_STDERR, szNewLine, sizeof(szNewLine) - 1, &cb);
-
-    /*
-     * Terminate the process.
-     */
-    LIBCLOG_MSG("Calling DosExit(,127)\n");
-    for (;;)
-    {
-        DosKillProcess(DKP_PROCESS, 0);
-        DosExit(EXIT_THREAD, 127);
-    }
-}
+        DosExit(EXIT_PROCESS, 127);
+    }
+}
+
+
+/**
+ * Calculates the length of a string.
+ * @returns String length in bytes.
+ * @param   psz     Pointer to the string.
+ */
+static size_t signalTerminateStrLen(const char *psz)
+{
+    const char *pszEnd = psz;
+    while (*pszEnd)
+        pszEnd++;
+    return pszEnd - psz;
+}
+
 
 /**
@@ -2159,9 +2091,16 @@
  * @param   pszBuf  Where to store the formatted number.
  * @param   u       Number to format.
- */
-static int signalTerminateHex(char *pszBuf, unsigned u)
+ * @param   cDigits Minimum number of digits in the output. Use 0 for whatever fits.
+ */
+static int signalTerminateHex(char *pszBuf, unsigned u, unsigned cDigits)
 {
     static const char szHex[17] = "0123456789abcdef";
-    if (u <= 0xff)
+    if (u <= 0xf && cDigits <= 1)
+    {
+        pszBuf[0] = szHex[u & 0xf];
+        pszBuf[1] = '\0';
+        return 1;
+    }
+    if (u <= 0xff && cDigits <= 2)
     {
         pszBuf[0] = szHex[u >> 4];
@@ -2170,5 +2109,5 @@
         return 2;
     }
-    else if (u <= 0xffff)
+    else if (u <= 0xffff && cDigits <= 4)
     {
         pszBuf[0] = szHex[u >> 12];
@@ -2194,4 +2133,124 @@
 }
 
+
+/**
+ * Cause immediate process termination because of the given signal.
+ *
+ * @param   iSignalNo       Signal causing the termination.
+ * @param   pvXcptParams    Pointer to the argument list of the OS/2 exception handler.
+ *                          NULL if not available.
+ */
+static void signalTerminateAbnormal(int iSignalNo, void *pvXcptParams)
+{
+    LIBCLOG_ENTER("iSignalNo=%d\n", iSignalNo);
+    /*
+     * Set the exit reason in SPM.
+     */
+    __libc_spmTerm(__LIBC_EXIT_REASON_SIGNAL_BASE + iSignalNo, 127);
+
+    /*
+     * Before we go crazy here, let's release the semaphore.
+     *
+     * If possible we'll stay in the must complete section to
+     * be sure we get to the exit. If not we'll have to mess with
+     * exception handlers and such now.
+     */
+    //if (__libc_back_signalSemIsOwner())
+    //    DosReleaseMutexSem(ghmtxSignals);
+
+    /*
+     * Terminate the exception handler chain to avoid recursive trouble.
+     */
+    FS_VAR();
+    FS_SAVE_LOAD();
+    PTIB pTib;
+    PPIB pPib;
+    DosGetInfoBlocks(&pTib, &pPib);
+    pTib->tib_pexchain = END_OF_CHAIN;
+
+    /*
+     * Write message to stderr.
+     */
+    ULONG   cb;
+    char szHexNum[12];
+#define SIG_PRINT_C(msg)  DosWrite(HFILE_STDERR, msg, sizeof(msg) - 1, &cb)
+#define SIG_PRINT_P(msg)  DosWrite(HFILE_STDERR, msg, signalTerminateStrLen(msg), &cb)
+#define SIG_PRINT_H(hex)  DosWrite(HFILE_STDERR, szHexNum, signalTerminateHex(szHexNum, hex, 0), &cb)
+#define SIG_PRINT_H16(hex)  DosWrite(HFILE_STDERR, szHexNum, signalTerminateHex(szHexNum, hex, 4), &cb)
+#define SIG_PRINT_H32(hex)  DosWrite(HFILE_STDERR, szHexNum, signalTerminateHex(szHexNum, hex, 8), &cb)
+    if (iSignalNo == SIGABRT)
+        SIG_PRINT_C("\n\rAbnormal program termination");
+    else
+    {
+        SIG_PRINT_C("\n\rProcess terminated by ");
+
+        if (iSignalNo < sizeof(gaszSignalNames) / sizeof(gaszSignalNames[0]))
+            SIG_PRINT_P(gaszSignalNames[iSignalNo]);
+        else
+        {
+            SIG_PRINT_C("unknown signal ");
+            SIG_PRINT_H(iSignalNo);
+        }
+    }
+
+    /* pid */
+    SIG_PRINT_C(" - pid=0x"); SIG_PRINT_H16(pPib->pib_ulpid);
+
+    /* tid */
+    SIG_PRINT_C(" - tid=0x"); SIG_PRINT_H16(pTib->tib_ptib2->tib2_ultid);
+
+    /* executable name. */
+    static char szExeName[CCHMAXPATH];
+    if (!DosQueryModuleName(pPib->pib_hmte, sizeof(szExeName), &szExeName[0]))
+    {
+        static const char szHypen[] = " - ";
+        DosWrite(HFILE_STDERR, szHypen, sizeof(szHypen) - 1, &cb);
+
+        for (cb = 0; szExeName[cb];)
+            cb++;
+        DosWrite(HFILE_STDERR, szExeName, cb, &cb);
+    }
+
+    /* eip */
+    PCONTEXTRECORD pCtx;
+    if (    pvXcptParams
+        &&  (pCtx = ((PEXCPTPARAMS)pvXcptParams)->pCtx))
+    {
+        SIG_PRINT_C("\r\ncs:eip=");
+        SIG_PRINT_H16(pCtx->ctx_SegCs);
+        SIG_PRINT_C(":");
+        SIG_PRINT_H32(pCtx->ctx_RegEip);
+        if (pCtx->ctx_RegEip >= 0x10000)
+        {
+            HMODULE hmod;
+            ULONG iObj = 0;
+            ULONG offObj = 0;
+            if (!DosQueryModFromEIP(&hmod, &iObj, sizeof(szExeName), szExeName, &offObj, pCtx->ctx_RegEip))
+            {
+                SIG_PRINT_C(" - ");
+                SIG_PRINT_H(iObj);
+                SIG_PRINT_C(":");
+                SIG_PRINT_H32(offObj);
+                SIG_PRINT_C(" ");
+                SIG_PRINT_P(szExeName);
+            }
+        }
+    }
+
+    /* final newline */
+    SIG_PRINT_C("\r\n");
+
+    /*
+     * Terminate the process.
+     */
+    LIBCLOG_MSG("Calling DosKillProcess()\n");
+    for (;;)
+    {
+        DosKillProcess(DKP_PROCESS, 0);
+        DosExit(EXIT_PROCESS, 127);
+    }
+}
+
+
 /**
  * Stop the process (job control emulation).
@@ -2222,4 +2281,5 @@
     return __libc_back_signalSemRequest();
 }
+
 
 /**
