Index: trunk/src/tools/qsysxcpt_pm.cpp
===================================================================
--- trunk/src/tools/qsysxcpt_pm.cpp	(revision 146)
+++ trunk/src/tools/qsysxcpt_pm.cpp	(revision 147)
@@ -35,8 +35,9 @@
 
 /*
- *  The below code is partly based on the except.h and except.c sources
- *  from the xwphelpers package (which is a part of the xworkplace product, see
- *  http://www.xworkplace.org, http://xworkplace.netlabs.org/ for more info).
- *  XWorkplace is Copyright (C) 1999-2002 Ulrich Moeller.
+ *  The below code was started as a partial cut & paste from the except.h
+ *  and except.c sources from the xwphelpers package (which is a part of the
+ *  xworkplace product, see www.xworkplace.org, xworkplace.netlabs.org).
+ *  XWorkplace is Copyright (C) 1999-2002 Ulrich Moeller. It has changed a lot
+ *  since then, but thanks to XWP authors for a good example.
  */
 
@@ -249,22 +250,18 @@
     Writes information about a signle stack frame.
 */
-static void qt_excWriteStackFrame( FILE *file, ULONG ulPointer, ULONG ulAddress )
+static void qt_excWriteStackFrame (FILE *file, ULONG ulRegEbp, ULONG ulRegEip)
 {
     APIRET  arc = NO_ERROR;
     HMODULE hMod = NULLHANDLE;
-    char   szMod[CCHMAXPATH] = "";
+    char    szMod[CCHMAXPATH] = "";
     ULONG   ulObject = 0,
             ulOffset = 0;
 
-    if (ulPointer)
-        fprintf (file, "     <Frame pointer=\"%08lX\">\n", ulPointer);
-    else
-        fprintf (file, "     <Frame pointer=\"current\">\n");
-
-    fprintf (file, "      <Location address=\"%08lX\">\n", ulAddress);
+    fprintf (file, "     <Frame pointer=\"%08lX\">\n", ulRegEbp);
+    fprintf (file, "      <Location address=\"%08lX\">\n", ulRegEip);
     
     arc = DosQueryModFromEIP (&hMod, &ulObject,
                               sizeof (szMod), szMod, &ulOffset,
-                              ulAddress);
+                              ulRegEip);
 
     if (arc != NO_ERROR)
@@ -272,14 +269,13 @@
                              szMod, arc);
     else
-    {
         fprintf (file, "       <Module ID=\"%04lX\" segment=\"%04lX\" "
                                       "offset=\"%08lX\"/>\n",
                  hMod, ulObject + 1, ulOffset); 
-    }
-
+
+    /* write a small memory dump with the location address in the middle */
     {
         enum { enmDelta = 8 };
-        UCHAR *pch = (UCHAR *) ulAddress - enmDelta;
-        UCHAR *pchEnd = (UCHAR *) ulAddress + enmDelta - 1;
+        UCHAR *pch = (UCHAR *) ulRegEip - enmDelta;
+        UCHAR *pchEnd = (UCHAR *) ulRegEip + enmDelta - 1;
         ULONG ulCount = enmDelta * 2;
         ULONG ulFlags = 0;
@@ -292,5 +288,5 @@
                 if (ulCount >= enmDelta * 2)
                     break;
-                if (pch + ulCount <= (UCHAR *) ulAddress)
+                if (pch + ulCount <= (UCHAR *) ulRegEip)
                 {
                     /* ulAddress is outside the pch object */
@@ -307,7 +303,7 @@
             else if (arc == ERROR_INVALID_ADDRESS)
             {
-                if (((ULONG) pch) & 0xFFFFF000 == ulAddress & 0xFFFFF000)
+                if (((ULONG) pch) & 0xFFFFF000 == ulRegEip & 0xFFFFF000)
                     break; /* the same page, ulAddress inaccessible */
-                pch = (UCHAR *) (ulAddress & 0xFFFFF000);
+                pch = (UCHAR *) (ulRegEip & 0xFFFFF000);
             }
         }
@@ -318,5 +314,5 @@
             for (; pch < pchEnd; ++pch)
                 fprintf (file, "%02lX%c", (ULONG) *pch,
-                         ulAddress - (ULONG) pch == 1 ? '-' : ' ');
+                         ulRegEip - (ULONG) pch == 1 ? '-' : ' ');
             fprintf (file, "\n");
         }
@@ -327,6 +323,6 @@
     }
     
-    fprintf (file, "      </Location>\n"
-                   "     </Frame>\n");
+    fprintf (file, "      </Location>\n");
+    fprintf (file, "     </Frame>\n");
 }
 
@@ -337,23 +333,28 @@
                                     PCONTEXTRECORD pContextRec)
 {
-    PULONG pulStackWord = 0;
+    ULONG ulRegEbp = pContextRec->ctx_RegEbp;
+    ULONG ulRegEip = pContextRec->ctx_RegEip;
 
     fprintf (file, "    <Frames>\n");
 
     /* first the trapping address itself */
-    qt_excWriteStackFrame (file, 0, pContextRec->ctx_RegEip);
-
-    pulStackWord = (PULONG) pContextRec->ctx_RegEbp;
-    
-    while (   pulStackWord != 0
-           && pulStackWord < (PULONG) ptib->tib_pstacklimit)
-    {
-        if (((ULONG) pulStackWord & 0x00000FFF) == 0x00000000)
+    qt_excWriteStackFrame (file, ulRegEbp, ulRegEip);
+    
+    /* first call to qt_excWriteStackFrame() is done before the EBP validity
+     * check below to get a chance to call qt_excWriteStackFrame() for the
+     * trapping address itself even if EBP there is invalid. */
+
+    while (ulRegEbp != 0 && ulRegEbp < (ULONG) ptib->tib_pstacklimit)
+    {
+        /* skip the trapping stack frame -- already written above */
+        if (pContextRec->ctx_RegEbp != ulRegEbp)
+            qt_excWriteStackFrame (file, ulRegEbp, ulRegEip);
+
+        if ((ulRegEbp & 0x00000FFF) == 0x00000000)
         {
             /* we're on a page boundary: check access */
             ULONG ulCount = 0x1000;
             ULONG ulFlags = 0;
-            APIRET arc = DosQueryMem ((void *) pulStackWord,
-                                      &ulCount, &ulFlags);
+            APIRET arc = DosQueryMem ((void *) ulRegEbp, &ulCount, &ulFlags);
             if (   (arc != NO_ERROR)
                 || (   arc == NO_ERROR
@@ -361,17 +362,21 @@
                         != (PAG_COMMIT|PAG_READ)))
             {
-                fprintf (file, "     <Frame pointer=\"%08lX\">\n",
-                         (ULONG) pulStackWord);
+                fprintf (file, "     <Frame pointer=\"%08lX\">\n", ulRegEbp);
                 qt_excWriteErrorMsg (file, 6, "DosQueryMem returned %lu "
                                      "and flags %08lX", arc, ulFlags);
                 fprintf (file, "     </Frame>\n");
-                pulStackWord += 0x1000;
+                /* try go to the next page */
+                /// @todo (r=dmik) I don't know how much it is accurate,
+                //  I've just taken the logic from xwphelpers sources.
+                ulRegEbp += 0x1000;
                 continue; /* while */
             }
         }
 
-        qt_excWriteStackFrame (file, (ULONG) pulStackWord, *(pulStackWord + 1));
-        pulStackWord = (PULONG) *(pulStackWord);
-    } /* end while */
+        /* get the return address of the current call */
+        ulRegEip = *(((PULONG) ulRegEbp) + 1);
+        /* get the address of the outer stack frame */
+        ulRegEbp = *((PULONG) ulRegEbp);
+    }
 
     fprintf (file, "    </Frames>\n");
@@ -573,7 +578,8 @@
     }
     
-    /* we do EBP validity check here as well as before the recursive call below
-     * to get a chance to translate EIP passed on the first call (as taken
-     * from the CONTEXTRECORD even if EBP there is invalid. */
+    /* we do EBP validity check here as well as before the recursive
+     * call below to get a chance for the above code (EIP to hmod translation)
+     * to be executed even if EBP there is invalid. */
+
     if (pState->ulRegEbp != 0 && pState->ulRegEbp < pState->ulStackLimit)
     {
@@ -593,5 +599,5 @@
                 {
                     /* try go to the next page */
-                    /// @todo (r=dmik) I'm not sure how much it is correct,
+                    /// @todo (r=dmik) I don't know how much it is accurate,
                     //  I've just taken the logic from xwphelpers sources.
                     pState->ulRegEbp += 0x1000;
@@ -602,5 +608,5 @@
         }
 
-        /* get the return address to the previous call */
+        /* get the return address of the current call */
         pState->ulRegEip = *(((PULONG) pState->ulRegEbp) + 1);
         /* get the address of the outer stack frame */
@@ -717,5 +723,5 @@
     
     /* first, the current thread */
-    QSTREC *pThrdRec = pInfo->pProcRec->pThrdRec;
+    QSTREC *pThrdRec = pInfo->bHaveSysState ? pInfo->pProcRec->pThrdRec : NULL;
     if (pThrdRec)
     {
