Changeset 147


Ignore:
Timestamp:
Oct 29, 2006, 9:22:35 PM (19 years ago)
Author:
dmik
Message:

Common: System Exceptions:

  • Fixed the stack walking procedure so that the stack word beyond (above) the last valid (outermost) stack frame is not treated as EIP (therefore, it is not considered as a really last stack frame and isn't written) because it can actually contain any unrelated garbage.
  • Fixed an exception in the exception handler when DosQuerySysState() data was not available.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/tools/qsysxcpt_pm.cpp

    r146 r147  
    3535
    3636/*
    37  *  The below code is partly based on the except.h and except.c sources
    38  *  from the xwphelpers package (which is a part of the xworkplace product, see
    39  *  http://www.xworkplace.org, http://xworkplace.netlabs.org/ for more info).
    40  *  XWorkplace is Copyright (C) 1999-2002 Ulrich Moeller.
     37 *  The below code was started as a partial cut & paste from the except.h
     38 *  and except.c sources from the xwphelpers package (which is a part of the
     39 *  xworkplace product, see www.xworkplace.org, xworkplace.netlabs.org).
     40 *  XWorkplace is Copyright (C) 1999-2002 Ulrich Moeller. It has changed a lot
     41 *  since then, but thanks to XWP authors for a good example.
    4142 */
    4243
     
    249250    Writes information about a signle stack frame.
    250251*/
    251 static void qt_excWriteStackFrame( FILE *file, ULONG ulPointer, ULONG ulAddress )
     252static void qt_excWriteStackFrame (FILE *file, ULONG ulRegEbp, ULONG ulRegEip)
    252253{
    253254    APIRET  arc = NO_ERROR;
    254255    HMODULE hMod = NULLHANDLE;
    255     char   szMod[CCHMAXPATH] = "";
     256    char    szMod[CCHMAXPATH] = "";
    256257    ULONG   ulObject = 0,
    257258            ulOffset = 0;
    258259
    259     if (ulPointer)
    260         fprintf (file, "     <Frame pointer=\"%08lX\">\n", ulPointer);
    261     else
    262         fprintf (file, "     <Frame pointer=\"current\">\n");
    263 
    264     fprintf (file, "      <Location address=\"%08lX\">\n", ulAddress);
     260    fprintf (file, "     <Frame pointer=\"%08lX\">\n", ulRegEbp);
     261    fprintf (file, "      <Location address=\"%08lX\">\n", ulRegEip);
    265262   
    266263    arc = DosQueryModFromEIP (&hMod, &ulObject,
    267264                              sizeof (szMod), szMod, &ulOffset,
    268                               ulAddress);
     265                              ulRegEip);
    269266
    270267    if (arc != NO_ERROR)
     
    272269                             szMod, arc);
    273270    else
    274     {
    275271        fprintf (file, "       <Module ID=\"%04lX\" segment=\"%04lX\" "
    276272                                      "offset=\"%08lX\"/>\n",
    277273                 hMod, ulObject + 1, ulOffset);
    278     }
    279 
     274
     275    /* write a small memory dump with the location address in the middle */
    280276    {
    281277        enum { enmDelta = 8 };
    282         UCHAR *pch = (UCHAR *) ulAddress - enmDelta;
    283         UCHAR *pchEnd = (UCHAR *) ulAddress + enmDelta - 1;
     278        UCHAR *pch = (UCHAR *) ulRegEip - enmDelta;
     279        UCHAR *pchEnd = (UCHAR *) ulRegEip + enmDelta - 1;
    284280        ULONG ulCount = enmDelta * 2;
    285281        ULONG ulFlags = 0;
     
    292288                if (ulCount >= enmDelta * 2)
    293289                    break;
    294                 if (pch + ulCount <= (UCHAR *) ulAddress)
     290                if (pch + ulCount <= (UCHAR *) ulRegEip)
    295291                {
    296292                    /* ulAddress is outside the pch object */
     
    307303            else if (arc == ERROR_INVALID_ADDRESS)
    308304            {
    309                 if (((ULONG) pch) & 0xFFFFF000 == ulAddress & 0xFFFFF000)
     305                if (((ULONG) pch) & 0xFFFFF000 == ulRegEip & 0xFFFFF000)
    310306                    break; /* the same page, ulAddress inaccessible */
    311                 pch = (UCHAR *) (ulAddress & 0xFFFFF000);
     307                pch = (UCHAR *) (ulRegEip & 0xFFFFF000);
    312308            }
    313309        }
     
    318314            for (; pch < pchEnd; ++pch)
    319315                fprintf (file, "%02lX%c", (ULONG) *pch,
    320                          ulAddress - (ULONG) pch == 1 ? '-' : ' ');
     316                         ulRegEip - (ULONG) pch == 1 ? '-' : ' ');
    321317            fprintf (file, "\n");
    322318        }
     
    327323    }
    328324   
    329     fprintf (file, "      </Location>\n"
    330                   "     </Frame>\n");
     325    fprintf (file, "      </Location>\n");
     326    fprintf (file, "     </Frame>\n");
    331327}
    332328
     
    337333                                    PCONTEXTRECORD pContextRec)
    338334{
    339     PULONG pulStackWord = 0;
     335    ULONG ulRegEbp = pContextRec->ctx_RegEbp;
     336    ULONG ulRegEip = pContextRec->ctx_RegEip;
    340337
    341338    fprintf (file, "    <Frames>\n");
    342339
    343340    /* first the trapping address itself */
    344     qt_excWriteStackFrame (file, 0, pContextRec->ctx_RegEip);
    345 
    346     pulStackWord = (PULONG) pContextRec->ctx_RegEbp;
    347    
    348     while (   pulStackWord != 0
    349            && pulStackWord < (PULONG) ptib->tib_pstacklimit)
    350     {
    351         if (((ULONG) pulStackWord & 0x00000FFF) == 0x00000000)
     341    qt_excWriteStackFrame (file, ulRegEbp, ulRegEip);
     342   
     343    /* first call to qt_excWriteStackFrame() is done before the EBP validity
     344     * check below to get a chance to call qt_excWriteStackFrame() for the
     345     * trapping address itself even if EBP there is invalid. */
     346
     347    while (ulRegEbp != 0 && ulRegEbp < (ULONG) ptib->tib_pstacklimit)
     348    {
     349        /* skip the trapping stack frame -- already written above */
     350        if (pContextRec->ctx_RegEbp != ulRegEbp)
     351            qt_excWriteStackFrame (file, ulRegEbp, ulRegEip);
     352
     353        if ((ulRegEbp & 0x00000FFF) == 0x00000000)
    352354        {
    353355            /* we're on a page boundary: check access */
    354356            ULONG ulCount = 0x1000;
    355357            ULONG ulFlags = 0;
    356             APIRET arc = DosQueryMem ((void *) pulStackWord,
    357                                       &ulCount, &ulFlags);
     358            APIRET arc = DosQueryMem ((void *) ulRegEbp, &ulCount, &ulFlags);
    358359            if (   (arc != NO_ERROR)
    359360                || (   arc == NO_ERROR
     
    361362                        != (PAG_COMMIT|PAG_READ)))
    362363            {
    363                 fprintf (file, "     <Frame pointer=\"%08lX\">\n",
    364                          (ULONG) pulStackWord);
     364                fprintf (file, "     <Frame pointer=\"%08lX\">\n", ulRegEbp);
    365365                qt_excWriteErrorMsg (file, 6, "DosQueryMem returned %lu "
    366366                                     "and flags %08lX", arc, ulFlags);
    367367                fprintf (file, "     </Frame>\n");
    368                 pulStackWord += 0x1000;
     368                /* try go to the next page */
     369                /// @todo (r=dmik) I don't know how much it is accurate,
     370                //  I've just taken the logic from xwphelpers sources.
     371                ulRegEbp += 0x1000;
    369372                continue; /* while */
    370373            }
    371374        }
    372375
    373         qt_excWriteStackFrame (file, (ULONG) pulStackWord, *(pulStackWord + 1));
    374         pulStackWord = (PULONG) *(pulStackWord);
    375     } /* end while */
     376        /* get the return address of the current call */
     377        ulRegEip = *(((PULONG) ulRegEbp) + 1);
     378        /* get the address of the outer stack frame */
     379        ulRegEbp = *((PULONG) ulRegEbp);
     380    }
    376381
    377382    fprintf (file, "    </Frames>\n");
     
    573578    }
    574579   
    575     /* we do EBP validity check here as well as before the recursive call below
    576      * to get a chance to translate EIP passed on the first call (as taken
    577      * from the CONTEXTRECORD even if EBP there is invalid. */
     580    /* we do EBP validity check here as well as before the recursive
     581     * call below to get a chance for the above code (EIP to hmod translation)
     582     * to be executed even if EBP there is invalid. */
     583
    578584    if (pState->ulRegEbp != 0 && pState->ulRegEbp < pState->ulStackLimit)
    579585    {
     
    593599                {
    594600                    /* try go to the next page */
    595                     /// @todo (r=dmik) I'm not sure how much it is correct,
     601                    /// @todo (r=dmik) I don't know how much it is accurate,
    596602                    //  I've just taken the logic from xwphelpers sources.
    597603                    pState->ulRegEbp += 0x1000;
     
    602608        }
    603609
    604         /* get the return address to the previous call */
     610        /* get the return address of the current call */
    605611        pState->ulRegEip = *(((PULONG) pState->ulRegEbp) + 1);
    606612        /* get the address of the outer stack frame */
     
    717723   
    718724    /* first, the current thread */
    719     QSTREC *pThrdRec = pInfo->pProcRec->pThrdRec;
     725    QSTREC *pThrdRec = pInfo->bHaveSysState ? pInfo->pProcRec->pThrdRec : NULL;
    720726    if (pThrdRec)
    721727    {
Note: See TracChangeset for help on using the changeset viewer.