Changeset 1332


Ignore:
Timestamp:
Dec 12, 2008, 2:06:40 AM (17 years ago)
Author:
Steven Levine
Message:

Ticket 26: Clean up output. Add logic to support thread 1.

Location:
trunk/dll
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/dll/excputil.c

    r1331 r1332  
    2222#define INCL_DOSMISC                    // DosDumpProcess?
    2323#define INCL_DOSERRORS                  // NO_ERROR
    24 #include <os2.h>
     24// #include <os2.h>
    2525
    2626#include "wrappers.h"                   // xmalloc xfree
     
    2929#include "strutil.h"                    // GetPString
    3030
    31 // #include "excputil.h"                // 08 Dec 08 SHL fixme
     31#include "excputil.h"
    3232
    3333static PSZ pszSrcFile = __FILE__;
     
    3838} THREADDATA;
    3939
    40 _ERR HandleException;
    41 
    4240/**
    4341 * Wrapper thread that installs exception handler and invokes
     
    4745static VOID WrapperThread(PVOID pvArgs)
    4846{
    49   EXCEPTIONREGISTRATIONRECORD excpQReg = { NULL, NULL };
     47  EXCEPTIONREGISTRATIONRECORD regRec = { NULL, NULL };
    5048  APIRET apiret;
    5149  THREADDATA *ptd = (THREADDATA*)pvArgs;
     
    5654# endif
    5755
    58   excpQReg.ExceptionHandler = HandleException;
    59   apiret = DosSetExceptionHandler(&excpQReg);
     56  regRec.ExceptionHandler = HandleException;
     57  apiret = DosSetExceptionHandler(&regRec);
    6058  if (apiret != NO_ERROR) {
    6159    Dos_Error(MB_ENTER, apiret, HWND_DESKTOP, pszSrcFile, __LINE__,
     
    6361  }
    6462
     63#if 0 // 11 Dec 08 SHL fixme tobe gone - debug
     64  {
     65    static UINT when;
     66    if (++when == 2)
     67      *(char*)0 = 0;
     68  }
     69#endif
     70
    6571  (*ptd->pfnThread)(ptd->pvArgs);       // Invoke thread
    6672
     
    6874
    6975  if (apiret == NO_ERROR) {
    70     apiret = DosUnsetExceptionHandler(&excpQReg);
     76    apiret = DosUnsetExceptionHandler(&regRec);
    7177    if (apiret != NO_ERROR) {
    7278      Dos_Error(MB_ENTER, apiret, HWND_DESKTOP, pszSrcFile, __LINE__,
     
    8894
    8995int xbeginthread(VOID (*pfnThread)(PVOID),
    90                  PVOID unused,
    9196                 UINT cStackBytes,
    92                  PVOID pvArgs)
     97                 PVOID pvArgs,
     98                 PSZ pszSrcFile,
     99                 UINT uiLineNumber)
    93100{
    94101  int rc;
     
    98105  rc = _beginthread(WrapperThread, NULL, cStackBytes, ptd);
    99106  if (rc == -1)
    100     Runtime_Error(pszSrcFile, __LINE__,
     107    Runtime_Error(pszSrcFile, uiLineNumber,
    101108                  GetPString(IDS_COULDNTSTARTTHREADTEXT));
    102109  return rc;
     
    120127  PIB *ppib;
    121128  TIB *ptib;
     129  ULONG ulpid;
     130  ULONG ultid;
    122131  APIRET apiret;
     132  HMODULE hmod;
    123133
    124134  static unsigned working;
    125 
    126   // Report exception in handler only once
     135  static PSZ pszExcpMsg = "Caught exception %lx in process %lx (%lu) thread %u at %.24s";
     136
     137  // Try to report cascading exceptions in handler only once
     138  // This simple test can get confused if multiple threads trap at same time
    127139  if (++working > 1) {
    128140    if (working == 2) {
    129       DbgMsg(pszSrcFile, __LINE__, "Caught exception %lx in exception handler at %p",
     141      DbgMsg(pszSrcFile, __LINE__, "Caught exception %lx at %p while handler active",
    130142             ex, pContext->ctx_RegEip);
    131143    }
     
    134146  }
    135147
     148  // Bypass exceptions we don't handle or exceptions we ignore
     149  // Keep in sync with exceptq selections since exceptq will ignore anyway
    136150  if ((pReport->fHandlerFlags & (EH_UNWINDING | EH_NESTED_CALL)) ||
    137       (pReport->ExceptionNum & XCPT_SEVERITY_CODE) != XCPT_FATAL_EXCEPTION)
     151      (ex & XCPT_SEVERITY_CODE) != XCPT_FATAL_EXCEPTION ||
     152      ex == XCPT_ASYNC_PROCESS_TERMINATE ||
     153      ex == XCPT_PROCESS_TERMINATE ||
     154      ex == XCPT_UNWIND ||
     155      ex == XCPT_SIGNAL ||
     156      ex == XCPT_BREAKPOINT ||
     157      ex == XCPT_SINGLE_STEP)
    138158  {
    139159    working--;
     
    147167  apiret = DosGetInfoBlocks(&ptib, &ppib);
    148168  if (apiret) {
    149     ppib = NULL;
    150     ptib = NULL;
    151   }
    152 
    153   // 08 Dec 08 SHL fixme to report thread ordinal?
    154   DbgMsg(pszSrcFile, __LINE__, "Caught exception %lx in process %lx (%lu) thread %u at %.24s",
    155          ex,
    156          ppib->pib_ulpid,
    157          ppib->pib_ulpid,
    158          ptib ? ptib->tib_ptib2->tib2_ultid : 0,
    159          pszTime);
    160 
    161   // Check if this is an exception exceptq can handle
    162   // Keep in sync with exceptq selections since exceptq will ignore anyway
    163   if (ex != XCPT_PROCESS_TERMINATE &&
    164       ex != XCPT_UNWIND &&
    165       ex != XCPT_SIGNAL &&
    166       ex != XCPT_BREAKPOINT &&
    167       ex != XCPT_SINGLE_STEP &&
    168       ex != XCPT_ASYNC_PROCESS_TERMINATE)
    169   {
    170     HMODULE hmod;
    171     apiret = DosLoadModule (0, 0, "exceptq" ,&hmod);
    172     // Report errors with DbgMsg, Dos_Error unsafe here
    173     if (apiret) {
    174       if (apiret != ERROR_FILE_NOT_FOUND)
    175         DbgMsg(pszSrcFile, __LINE__, "DosLoadModule(exceptq) reported error %u", apiret);
    176     }
     169    ulpid = 0;
     170    ultid = 0;
     171  }
     172  else {
     173    ulpid = ppib->pib_ulpid;
     174    ultid = ptib->tib_ptib2->tib2_ultid;
     175  }
     176
     177  DbgMsg(pszSrcFile, __LINE__, pszExcpMsg,
     178         ex, ulpid, ulpid, ultid, pszTime);
     179
     180  // Report errors with DbgMsg, Dos_Error unsafe here
     181  apiret = DosLoadModule (0, 0, "exceptq" ,&hmod);
     182  if (apiret) {
     183    if (apiret != ERROR_FILE_NOT_FOUND)
     184      DbgMsg(pszSrcFile, __LINE__, "DosLoadModule(exceptq) reported error %u", apiret);
     185  }
     186  else {
     187    ERR pfn;
     188    apiret = DosQueryProcAddr(hmod, 0, "MYHANDLER", (PFN*)&pfn);
     189    if (apiret)
     190      DbgMsg(pszSrcFile, __LINE__, "DosQueryProcAddr(MYHANDLER) reported error %u", apiret);
    177191    else {
    178       ERR pfn;
    179       apiret = DosQueryProcAddr(hmod, 0, "MYHANDLER", (PFN*)&pfn);
    180       if (apiret)
    181         DbgMsg(pszSrcFile, __LINE__, "DosQueryProcAddr(MYHANDLER) reported error %u", apiret);
    182       else {
    183         // DbgMsg(pszSrcFile, __LINE__, "Invoking exceptq handler at %p", pfn);
    184         (*pfn)(pReport, pReg, pContext, pv);
    185         handled = TRUE;
    186       }
    187       DosFreeModule(hmod);
    188     }
    189 
    190     // If exceptq not available use local handler
    191     if (!handled) {
    192       union {
    193         struct {
    194           ULONG ulEBP;
    195           ULONG ulEIP;
    196         } stk32;
    197         struct {
    198           USHORT usBP;
    199           USHORT usIP;
    200           USHORT usCS;                  // > 1 and < 0xfff
    201         } stk16;
    202       } u;
    203       ULONG ulObjNum;
    204       ULONG ulOffset;
    205       ULONG ulEIP;
    206       ULONG ulEBP;
    207       CHAR szFileName[CCHMAXPATH];
    208       BOOL is32Bit;
    209       APIRET apiret;
    210       ULONG flags;
    211       ULONG cnt;
    212       ULONG ulOldEBP = 0;
    213       INT c;
    214       FILE* fp;
    215 
     192      // DbgMsg(pszSrcFile, __LINE__, "Invoking exceptq handler at %p", pfn);
     193      (*pfn)(pReport,   pReg, pContext, pv);
    216194      handled = TRUE;
    217 
    218       fp = fopen("fm2_trap.log", "a");
    219       if (!fp)
    220         fp = stderr;                    // Oh well
    221 
    222       if (fp == stderr)
    223         fputc('\n', stderr);
    224       else {
    225         fprintf(fp, "\nCaught exception %lx in process %x (%u) thread %u at %s\n",
    226                 ex,
    227                 ppib->pib_ulpid,
    228                 ppib->pib_ulpid,
    229                 ptib ? ptib->tib_ptib2->tib2_ultid : 0,
    230                 pszTime);
    231       }
    232 
    233       // fixme to do 16 bit better, 5b = FLAT_CS
    234       if (pContext->ctx_SegCs == 0x5b) {
    235         is32Bit = TRUE;                 // Assume 32-bit
    236         u.stk32.ulEIP = pContext->ctx_RegEip;
    237         u.stk32.ulEBP = pContext->ctx_RegEbp;
     195    }
     196    DosFreeModule(hmod);
     197  }
     198
     199  // If exceptq not available use local handler
     200  if (!handled) {
     201    union {
     202      struct {
     203        ULONG ulEBP;
     204        ULONG ulEIP;
     205      } stk32;
     206      struct {
     207        USHORT usBP;
     208        USHORT usIP;
     209        USHORT usCS;                    // > 1 and < 0xfff
     210      } stk16;
     211    } u;
     212    ULONG ulObjNum;
     213    ULONG ulOffset;
     214    ULONG ulEIP;
     215    ULONG ulEBP;
     216    CHAR szFileName[CCHMAXPATH];
     217    BOOL is32Bit;
     218    APIRET apiret;
     219    ULONG flags;
     220    ULONG cnt;
     221    ULONG ulOldEBP = 0;
     222    INT c;
     223    FILE* fp;
     224
     225    handled = TRUE;
     226
     227    // Write stack trace to log file - let kernel do popuplog.os2
     228    fp = fopen("fm2_trap.log", "a");
     229    if (!fp)
     230      fp = stderr;                      // Oh well
     231
     232    if (fp != stderr) {
     233      fputc('\n', fp);
     234      fprintf(fp, pszExcpMsg,
     235              ex, ulpid, ulpid, ultid, pszTime);
     236      fputc('\n', stderr);
     237    }
     238    fputc('\n', stderr);
     239
     240    // fixme to support mixed 32-bit/16-bit stacks, 5b = FLAT_CS
     241    if (pContext->ctx_SegCs == 0x5b) {
     242      is32Bit = TRUE;                   // Assume 32-bit
     243      u.stk32.ulEIP = pContext->ctx_RegEip;
     244      u.stk32.ulEBP = pContext->ctx_RegEbp;
     245    }
     246    else {
     247      is32Bit = FALSE;
     248      u.stk16.usIP = pContext->ctx_RegEip;
     249      u.stk16.usBP = pContext->ctx_RegEbp;
     250    }
     251
     252    // Walk stack frames
     253    for (c = 0; c < 100; c++) {
     254      if (is32Bit) {
     255        ulEIP = u.stk32.ulEIP;
     256        ulEBP = u.stk32.ulEBP;
    238257      }
    239258      else {
    240         is32Bit = FALSE;
    241         u.stk16.usIP = pContext->ctx_RegEip;
    242         u.stk16.usBP = pContext->ctx_RegEbp;
     259        ulEIP = ((ULONG) (pContext->ctx_SegCs & ~7) << 13) | u.stk16.usIP;
     260        ulEBP = ((ULONG) (pContext->ctx_SegSs & ~7) << 13) | u.stk16.usBP;
    243261      }
    244262
    245       // Walk stack
    246       for (c = 0; c < 100; c++) {
    247         if (is32Bit) {
    248           ulEIP = u.stk32.ulEIP;
    249           ulEBP = u.stk32.ulEBP;
    250         }
    251         else {
    252           ulEIP = ((ULONG) (pContext->ctx_SegCs & ~7) << 13) | u.stk16.usIP;
    253           ulEBP = ((ULONG) (pContext->ctx_SegSs & ~7) << 13) | u.stk16.usBP;
    254         }
    255 
    256         apiret = DosQueryModFromEIP(&hmod, &ulObjNum, CCHMAXPATH, szFileName,
    257                                 &ulOffset, ulEIP);
    258         if (apiret) {
    259           ulObjNum = 0;
    260           ulOffset = 0;
    261           strcpy(szFileName, "n/a");
    262         }
    263         else
    264           ulObjNum++;                   // Number from 1..n for display
    265 
    266         fprintf(fp, " Stack frame %u @ %lx:%lx %s %lx:%lx\n",
    267                 c,
    268                 pContext->ctx_SegCs, ulEIP,
    269                 szFileName, ulObjNum, ulOffset);
    270 
    271         if (apiret)
    272           break;
    273 
    274         if (!ulEBP || ulEBP <= ulOldEBP)
    275           break;
    276 
    277         cnt = sizeof(u);
    278 
    279         apiret = DosQueryMem((void*)ulEBP, &cnt, &flags);
    280         if (apiret || (flags & (PAG_COMMIT | PAG_READ)) != (PAG_COMMIT | PAG_READ))
    281           break;                        // We are lost
    282 
    283         ulOldEBP = ulEBP;
    284         memcpy((void*)&u, (void*)ulEBP, sizeof(u));
    285 
    286       } // for
    287 
    288       if (fp && fp != stderr)
    289         fclose(fp);
    290 
    291     } // if !handled
    292 
    293     // DbgMsg(pszSrcFile, __LINE__, "We are going to die now");
    294 
    295   } // if can handle here
     263      apiret = DosQueryModFromEIP(&hmod, &ulObjNum, CCHMAXPATH, szFileName,
     264                              &ulOffset, ulEIP);
     265      if (apiret) {
     266        ulObjNum = 0;
     267        ulOffset = 0;
     268        strcpy(szFileName, "n/a");
     269      }
     270      else
     271        ulObjNum++;                     // Number from 1..n for display
     272
     273      fprintf(fp, " Stack frame %u @ %lx:%lx %s %lx:%lx\n",
     274              c,
     275              pContext->ctx_SegCs, ulEIP,
     276              szFileName, ulObjNum, ulOffset);
     277
     278      if (apiret)
     279        break;
     280
     281      if (!ulEBP || ulEBP <= ulOldEBP)
     282        break;
     283
     284      cnt = sizeof(u);
     285
     286      apiret = DosQueryMem((void*)ulEBP, &cnt, &flags);
     287      if (apiret || (flags & (PAG_COMMIT | PAG_READ)) != (PAG_COMMIT | PAG_READ))
     288        break;                  // We are lost
     289
     290      ulOldEBP = ulEBP;
     291      memcpy((void*)&u, (void*)ulEBP, sizeof(u));
     292
     293    } // for
     294
     295    if (fp || fp != stderr)
     296      fclose(fp);
     297
     298  } // if !handled
     299
     300  // DbgMsg(pszSrcFile, __LINE__, "We are going to die now");
    296301
    297302  working--;
  • trunk/dll/excputil.h

    r1331 r1332  
    1313
    1414#if !defined(OS2_INCLUDED)
     15#define INCL_DOSEXCEPTIONS              // XCTP_...
    1516#include <os2.h>
    1617#endif
    1718
    1819int xbeginthread(VOID (*pfnThread)(PVOID),
    19                  PVOID unused,
    2020                 UINT cStackBytes,
    21                  PVOID pvArgs);
     21                 PVOID pvArgs,
     22                 PSZ pszSrcFile,
     23                 UINT uiLineNumber);
     24
     25_ERR HandleException;
    2226
    2327#endif // EXCPUTIL_H
Note: See TracChangeset for help on using the changeset viewer.