home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sherlock.zip / EXCEPT / EXCEPT.ZIP / SOURCE.ZIP / EXCEPT.C < prev    next >
Text File  |  1993-10-19  |  19KB  |  446 lines

  1.  
  2. /**********************************************************************/
  3. /*                           IBM DAPTOOLS UseOnly                    */
  4. /**********************************************************************/
  5. /*                                                                    */
  6. /*  EXCEPT                                                            */
  7. /*                                                                    */
  8. /* DLL containing an exception handler for gathering trap information */
  9. /* This DLL dumps all important debugging Data and is accessible      */
  10. /* from both 16 bit and 32 bits programs                              */
  11. /* This uses PSTAT. EXCEPTQ uses DosQProcStatus which is far better   */
  12. /**********************************************************************/
  13. /* Version: 2.2             |   Marc Fiammante                        */
  14. /*                          |   La Gaude FRANCE                       */
  15. /**********************************************************************/
  16. /*                                                                    */
  17. /**********************************************************************/
  18. /* History:                                                           */
  19. /* --------                                                           */
  20. /*                                                                    */
  21. /* created: Marc Fiammante December 1992                              */
  22. /**********************************************************************/
  23. #define INCL_BASE
  24. #define INCL_DOSEXCEPTIONS
  25. #define INCL_DOSSEMAPHORES   /* Semaphore values */
  26. #include <os2.h>
  27. #include <stdlib.h>
  28. #include <stdio.h>
  29.  
  30. #define HF_STDERR 2
  31. UCHAR *ProcessFile = "PROCESS.TRM";
  32. UCHAR *ProcessName = "DEBUGGEE.EXE";
  33. CHAR   ProcessHex[10];
  34. FILE   *hTrap;
  35. FILE   *hProcessFile;
  36. struct debug_buffer
  37.  {
  38.    ULONG   Pid;        /* Debuggee Process ID */
  39.    ULONG   Tid;        /* Debuggee Thread ID */
  40.    LONG    Cmd;        /* Command or Notification */
  41.    LONG    Value;      /* Generic Data Value */
  42.    ULONG   Addr;       /* Debuggee Address */
  43.    ULONG   Buffer;     /* Debugger Buffer Address */
  44.    ULONG   Len;        /* Length of Range */
  45.    ULONG   Index;      /* Generic Identifier Index */
  46.    ULONG   MTE;        /* Module Handle */
  47.    ULONG   EAX;        /* Register Set */
  48.    ULONG   ECX;
  49.    ULONG   EDX;
  50.    ULONG   EBX;
  51.    ULONG   ESP;
  52.    ULONG   EBP;
  53.    ULONG   ESI;
  54.    ULONG   EDI;
  55.    ULONG   EFlags;
  56.    ULONG   EIP;
  57.    ULONG   CSLim;      /* Byte Granular Limits */
  58.    ULONG   CSBase;     /* Byte Granular Base */
  59.    UCHAR   CSAcc;      /* Access Bytes */
  60.    UCHAR   CSAtr;      /* Attribute Bytes */
  61.    USHORT  CS;
  62.    ULONG   DSLim;
  63.    ULONG   DSBase;
  64.    UCHAR   DSAcc;
  65.    UCHAR   DSAtr;
  66.    USHORT  DS;
  67.    ULONG   ESLim;
  68.    ULONG   ESBase;
  69.    UCHAR   ESAcc;
  70.    UCHAR   ESAtr;
  71.    USHORT  ES;
  72.    ULONG   FSLim;
  73.    ULONG   FSBase;
  74.    UCHAR   FSAcc;
  75.    UCHAR   FSAtr;
  76.    USHORT  FS;
  77.    ULONG   GSLim;
  78.    ULONG   GSBase;
  79.    UCHAR   GSAcc;
  80.    UCHAR   GSAtr;
  81.    USHORT  GS;
  82.    ULONG   SSLim;
  83.    ULONG   SSBase;
  84.    UCHAR   SSAcc;
  85.    UCHAR   SSAtr;
  86.    USHORT  SS;
  87. } DbgBuf;
  88. /*-------------------------------------*/
  89. APIRET APIENTRY DosQueryModFromEIP( HMODULE *phMod,
  90.                                     ULONG *pObjNum,
  91.                                     ULONG BuffLen,
  92.                                     PCHAR pBuff,
  93.                                     ULONG *pOffset,
  94.                                     ULONG Address );
  95. /*-------------------------------------*/
  96. #define DBG_O_OBJMTE       0x10000000L
  97. #define DBG_C_NumToAddr            13
  98. #define DBG_C_AddrToObject         28
  99. #define DBG_C_Connect              21
  100. #define DBG_L_386                   1
  101. RESULTCODES ReturnCodes;
  102. UCHAR   LoadError[40]; /*DosExecPGM buffer */
  103. UCHAR   Translate[17];
  104. void    GetObjects(struct debug_buffer * pDbgBuf,HMODULE hMte,PSZ pName);
  105. VOID    ListModules(VOID);
  106. HMODULE hMod;
  107. ULONG   ObjNum;
  108. ULONG   Offset;
  109. /*-------------------------------------*/
  110. CHAR    Buffer[CCHMAXPATH];
  111.  
  112. typedef ULONG     * _Seg16 PULONG16;
  113. APIRET16 APIENTRY16 DOS16SIZESEG( USHORT Seg , PULONG16 Size);
  114. APIRET16 APIENTRY16 DOS16LOADMODULE( CHAR * _Seg16, USHORT, CHAR * _Seg16, USHORT * _Seg16);
  115. typedef  APIRET16  (APIENTRY16  _PFN16)();
  116. typedef  _PFN16 * _Seg16 PFN16;
  117. #pragma pack(1)
  118. typedef struct
  119.   {
  120.     short int      ilen;     /* Instruction length */
  121.     long           rref;     /* Value of any IP relative storage reference */
  122.     unsigned short sel;      /* Selector of any CS:eIP storage reference.   */
  123.     long           poff;     /* eIP value of any CS:eIP storage reference. */
  124.     char           longoper; /* YES/NO value. Is instr in 32 bit operand mode? **/
  125.     char           longaddr; /* YES/NO value. Is instr in 32 bit address mode? **/
  126.     char           buf[40];  /* String holding disassembled instruction **/
  127.   } * _Seg16 RETURN_FROM_DISASM;
  128. RETURN_FROM_DISASM CDECL16 DISASM( CHAR * _Seg16 Source, USHORT IPvalue,USHORT segsize );
  129. RETURN_FROM_DISASM AsmLine;
  130. USHORT BigSeg;
  131.  
  132. ULONG _cdecl _System myHandler (PEXCEPTIONREPORTRECORD       pERepRec,
  133.                         PEXCEPTIONREGISTRATIONRECORD pERegRec,
  134.                         PCONTEXTRECORD               pCtxRec,
  135.                         PVOID                        p)
  136. {
  137.   PCHAR   SegPtr;
  138.   PUSHORT StackPtr;
  139.   PUCHAR  cStackPtr;
  140.   ULONG Size,Flags;
  141.   APIRET rc;
  142.   APIRET semrc;
  143.   APIRET16 rc16;
  144.   PTIB   ptib;
  145.   PPIB   ppib;
  146.   USHORT Count;
  147.   ULONG  Nest;
  148.   UCHAR  TrapFile[20];
  149.   void * _Seg16 Ptr16;
  150.   struct debug_buffer DbgBuf;
  151.  
  152.  
  153.   if ((pERepRec->ExceptionNum&XCPT_SEVERITY_CODE)==XCPT_FATAL_EXCEPTION)
  154.   {
  155.     if ((pERepRec->ExceptionNum!=XCPT_PROCESS_TERMINATE)&&
  156.         (pERepRec->ExceptionNum!=XCPT_UNWIND)&&
  157.         (pERepRec->ExceptionNum!=XCPT_SIGNAL)&&
  158.         (pERepRec->ExceptionNum!=XCPT_ASYNC_PROCESS_TERMINATE)) {
  159.        DosEnterMustComplete(&Nest);
  160.        rc=DosGetInfoBlocks(&ptib,&ppib);
  161.        if (rc==NO_ERROR) {
  162.           sprintf(TrapFile,"%d%d.TRP",
  163.                   ppib->pib_ulpid,ptib->tib_ptib2->tib2_ultid);
  164.           sprintf(ProcessHex,"%4.4X",ppib->pib_ulpid);
  165.        } else {
  166.           sprintf(TrapFile,"TRAP.TRP");
  167.        }
  168.        printf("Creating %s\n",TrapFile);
  169.        hTrap=fopen(TrapFile,"a");
  170.        if (hTrap==NULL) {
  171.           printf("hTrap NULL\n");
  172.           hTrap=stdout;
  173.        } /* endif */
  174.        fprintf(hTrap,"Exception %8.8lX Occurred\n",pERepRec->ExceptionNum);
  175.        if ( pERepRec->ExceptionNum     ==         XCPT_ACCESS_VIOLATION)
  176.        {
  177.           switch (pERepRec->ExceptionInfo[0]) {
  178.                case XCPT_READ_ACCESS:
  179.                case XCPT_WRITE_ACCESS:
  180.                   fprintf(hTrap,"Invalid linear address %8.8lX\n",pERepRec->ExceptionInfo[1]);
  181.                   break;
  182.                case XCPT_SPACE_ACCESS:
  183.                   fprintf(hTrap,"Invalid Selector %8.8lX\n",pERepRec->ExceptionInfo[1]);
  184.                   break;
  185.                case XCPT_LIMIT_ACCESS:
  186.                   fprintf(hTrap,"Limit access fault\n");
  187.                   break;
  188.                case XCPT_UNKNOWN_ACCESS:
  189.                   fprintf(hTrap,"Unknown access fault\n");
  190.                   break;
  191.              break;
  192.           default:
  193.                   fprintf(hTrap,"Other Unknown access fault\n");
  194.           } /* endswitch */
  195.        } /* endif */
  196.        if ( (pCtxRec->ContextFlags) & CONTEXT_SEGMENTS ) {
  197.             fprintf(hTrap,"GS  : %4.4lX     ",pCtxRec->ctx_SegGs);
  198.             fprintf(hTrap,"FS  : %4.4lX     ",pCtxRec->ctx_SegFs);
  199.             fprintf(hTrap,"ES  : %4.4lX     ",pCtxRec->ctx_SegEs);
  200.             fprintf(hTrap,"DS  : %4.4lX     \n",pCtxRec->ctx_SegDs);
  201.        } /* endif */
  202.        if ( (pCtxRec->ContextFlags) & CONTEXT_INTEGER  ) {
  203.             fprintf(hTrap,"EDI : %8.8lX ",pCtxRec->ctx_RegEdi  );
  204.             fprintf(hTrap,"ESI : %8.8lX ",pCtxRec->ctx_RegEsi  );
  205.             fprintf(hTrap,"EAX : %8.8lX ",pCtxRec->ctx_RegEax  );
  206.             fprintf(hTrap,"EBX : %8.8lX\n",pCtxRec->ctx_RegEbx  );
  207.             fprintf(hTrap,"ECX : %8.8lX ",pCtxRec->ctx_RegEcx  );
  208.             fprintf(hTrap,"EDX : %8.8lX\n",pCtxRec->ctx_RegEdx  );
  209.        } /* endif */
  210.        if ( (pCtxRec->ContextFlags) & CONTEXT_CONTROL  ) {
  211.             fprintf(hTrap,"EBP : %8.8lX ",pCtxRec->ctx_RegEbp  );
  212.             fprintf(hTrap,"EIP : %8.8lX ",pCtxRec->ctx_RegEip  );
  213.             fprintf(hTrap,"EFLG: %8.8lX ",pCtxRec->ctx_EFlags  );
  214.             fprintf(hTrap,"ESP : %8.8lX\n",pCtxRec->ctx_RegEsp  );
  215.             fprintf(hTrap,"CS  : %4.4lX     ",pCtxRec->ctx_SegCs   );
  216.             fprintf(hTrap,"SS  : %4.4lX\n",pCtxRec->ctx_SegSs   );
  217.             SegPtr =MAKEP((SHORT)pCtxRec->ctx_SegCs,0);
  218.             rc16 =DOS16SIZESEG( (USHORT)pCtxRec->ctx_SegCs , &Size);
  219.             if (rc16==NO_ERROR) {
  220.                printf("CSLIM: %8.8lX ",Size);
  221.                fprintf(hTrap,"CSLIM: %8.8lX ",Size);
  222.             } /* endif */
  223.             rc16 =DOS16SIZESEG( (USHORT)pCtxRec->ctx_SegSs , &Size);
  224.             if (rc16==NO_ERROR) {
  225.                printf("SSLIM: %8.8lX \n",Size);
  226.                fprintf(hTrap,"SSLIM: %8.8lX \n",Size);
  227.             } /* endif */
  228.             BigSeg=((pCtxRec->ctx_RegEip)>0x00010000);
  229.             if (BigSeg) {
  230.                 AsmLine= DISASM( (PVOID) pCtxRec->ctx_RegEip,
  231.                                   (USHORT)pCtxRec->ctx_RegEip, BigSeg );
  232.                 fprintf(hTrap,"CS:EIP : %4.4X:%8.8X   %s\n",
  233.                         pCtxRec->ctx_SegCs,
  234.                         pCtxRec->ctx_RegEip,AsmLine->buf);
  235.             } else {
  236.                 AsmLine= DISASM(MAKE16P(pCtxRec->ctx_SegCs,
  237.                                          pCtxRec->ctx_RegEip),
  238.                                  (USHORT)pCtxRec->ctx_RegEip, BigSeg );
  239.                 fprintf(hTrap,"CS:IP : %4.4X:%4.4X    %s\n",
  240.                         pCtxRec->ctx_SegCs,
  241.                         pCtxRec->ctx_RegEip,AsmLine->buf);
  242.             } /* endif */
  243.             rc=DosGetInfoBlocks(&ptib,&ppib);
  244.             if (rc==NO_ERROR) {
  245.                static CHAR Format[10];
  246.                static CHAR Name[CCHMAXPATH];
  247.                fprintf(hTrap,"Thread slot %lu , Id %lu , priority %p\n",
  248.                        ptib->tib_ordinal,
  249.                        ptib->tib_ptib2->tib2_ultid ,
  250.                        ptib->tib_ptib2->tib2_ulpri );
  251.                Ptr16=ptib->tib_pstack;
  252.                sprintf(Format,"%8.8lX",Ptr16);
  253.                fprintf(hTrap,"Stack Bottom : %8.8lX (%4.4s:%4.4s) ;", ptib->tib_pstack ,Format,Format+4);
  254.                Ptr16=ptib->tib_pstacklimit;
  255.                sprintf(Format,"%8.8lX",Ptr16);
  256.                fprintf(hTrap,"Stack Top    : %8.8lX (%4.4s:%4.4s) \n",ptib->tib_pstacklimit,Format,Format+4);
  257.                fprintf(hTrap,"Process Id : %lu ", ppib->pib_ulpid);
  258.                rc=DosQueryModuleName(ppib->pib_hmte,CCHMAXPATH, Name);
  259.                if (rc==NO_ERROR) {
  260.                   fprintf(hTrap,".EXE name : %s\n",Name);
  261.                } else {
  262.                   fprintf(hTrap,".EXE name : ??????\n");
  263.                } /* endif */
  264.  /*     sprintf(Buffer,"PSTAT /P:%X > %s",ppib->pib_ulpid,ProcessFile); */
  265.                sprintf(Buffer,"PSTAT /L > %s",ProcessFile);
  266.                system(Buffer);
  267.                ListModules();
  268.                GetObjects(&DbgBuf,ppib->pib_hmte,Name);
  269.                Count=0;
  270.                Translate[0]=0x00;
  271.                fprintf(hTrap,"\n/*----- Stack Bottom ---*/\n");
  272.                for (StackPtr=(PUSHORT)ptib->tib_pstack;
  273.                     StackPtr<(PUSHORT)ptib->tib_pstacklimit;
  274.                     StackPtr++) {
  275.                     if (Count==0) {
  276.                        fprintf(hTrap,"  %s\n %8.8X :",Translate,StackPtr);
  277.                        Translate[0]=0x00;
  278.                     } /* endif */
  279.                     fprintf(hTrap,"%4.4hX ",*StackPtr);
  280.                     cStackPtr=(PUCHAR)StackPtr;
  281.                     if ((isprint(*cStackPtr)) &&
  282.                         (*cStackPtr>=0x20)  ) {
  283.                        Translate[2*Count]=*cStackPtr;
  284.                     } else {
  285.                        Translate[2*Count]='.';
  286.                     } /* endif */
  287.                     cStackPtr++;
  288.                     if ((isprint(*cStackPtr) )&&
  289.                         ( *cStackPtr >=0x20 )  ) {
  290.                        Translate[2*Count+1]=*cStackPtr;
  291.                     } else {
  292.                        Translate[2*Count+1]='.';
  293.                     } /* endif */
  294.                     Count++;
  295.                     Translate[2*Count]=0x00;
  296.                     if (Count==8) {
  297.                         Count=0;
  298.                     } /* endif */
  299.                } /* endfor */
  300.                fprintf(hTrap,"%s\n/*----- Stack Top -----*/\n",Translate);
  301.  
  302.             } /* endif */
  303.        } /* endif */
  304.        if (hTrap!=stdout) {
  305.           fclose(hTrap);
  306.           DosCopy( ProcessFile, TrapFile,DCPY_APPEND);
  307.           DosDelete(ProcessFile);
  308.        }
  309.        DosExitMustComplete(&Nest);
  310.        rc=DosUnsetExceptionHandler(pERegRec);
  311.     } /* endif */
  312.   } else {
  313.      printf("Other non fatal exception %8.8lx ",pERepRec->ExceptionNum);
  314.      printf("At address                %8.8lx\n",pERepRec->ExceptionAddress);
  315.   } /* endif */
  316.   return (XCPT_CONTINUE_SEARCH);
  317.  
  318. }
  319. APIRET16 APIENTRY16 SETEXCEPT(PEXCEPTIONREGISTRATIONRECORD _Seg16 pxcpthand)
  320.  {
  321.    APIRET rc;
  322.  
  323.    rc=DosError(FERR_DISABLEEXCEPTION | FERR_DISABLEHARDERR );
  324.    printf("Set error rc %ld\n",rc);
  325.    pxcpthand->prev_structure=0;
  326.    pxcpthand->ExceptionHandler=&myHandler;
  327.    rc=DosSetExceptionHandler(pxcpthand);
  328.    printf("Set except rc %ld\n",rc);
  329. }
  330. VOID ListModules() {
  331.   APIRET rc;
  332.   BOOL   FoundProcess;
  333.   hProcessFile=fopen(ProcessFile,"r");
  334.   if (hProcessFile!=NULL) {
  335.         rc = DosExecPgm(LoadError,          /* Object name buffer */
  336.                         sizeof(LoadError),  /* Length of object name buffer */
  337.                         EXEC_TRACE,         /* Asynchronous/Trace flags */
  338.                         "Debug",            /* Argument string */
  339.                         NULL,               /* Environment string */
  340.                         &ReturnCodes,       /* Termination codes */
  341.                         ProcessName);           /* Program file name */
  342.         if (rc != NO_ERROR) {
  343.             fprintf(hTrap,"rc = %d Process ID %d  Return Code %d \n",
  344.                   rc,
  345.                   ReturnCodes.codeTerminate,
  346.                   ReturnCodes.codeResult);
  347.             return;
  348.         }
  349.        fprintf(hTrap,"Connecting  to PID %d\n",ReturnCodes.codeTerminate);
  350.        DbgBuf.Cmd = DBG_C_Connect; /* Indicate that a Connect is requested */
  351.        DbgBuf.Pid = ReturnCodes.codeTerminate;
  352.        DbgBuf.Tid = 0;
  353.        DbgBuf.Value = DBG_L_386;
  354.        rc = DosDebug(&DbgBuf);
  355.        if (rc != 0) {
  356.            fprintf(hTrap,"DosDebug error: return code = %ld Note %8.8lX\n", rc,DbgBuf.Cmd);
  357.            fprintf(hTrap,"Value          = %8.8lX %ld\n",DbgBuf.Value,DbgBuf.Value);
  358.        }
  359.  
  360.        fprintf(hTrap,"Connected to PID %d\n",ReturnCodes.codeTerminate);
  361.        FoundProcess=FALSE;
  362.        while (fscanf(hProcessFile,"%s",Buffer)!=EOF) {
  363.      /*     printf("Processing >%s<\n",Buffer); */
  364.           if (FoundProcess) {
  365.              if (strcmp(Buffer+strlen(Buffer)-4,".DLL") ==0) {
  366.                   HMODULE hMte;
  367.                   rc=DosQueryModuleHandle(Buffer,&hMte);
  368.                   if (rc==NO_ERROR) {
  369.                      GetObjects(&DbgBuf,hMte,Buffer);
  370.                   } /* endif */
  371.              } /* endif */
  372.              if  (strcmp(Buffer+strlen(Buffer)-5,".DLL*")==0) {
  373.                   HMODULE hMte;
  374.                   Buffer[strlen(Buffer)-1]=0x00;
  375.                   rc=DosQueryModuleHandle(Buffer,&hMte);
  376.                   if (rc==NO_ERROR) {
  377.                      GetObjects(&DbgBuf,hMte,Buffer);
  378.                   } /* endif */
  379.              } /* endif */
  380.              /* If next .EXE then break */
  381.              if (strcmp(Buffer+strlen(Buffer)-4,".EXE")==0) {
  382.                 break;
  383.              } /* endif */
  384.           } else {
  385.              if (strcmp(ProcessHex,Buffer)==0) {
  386.                 FoundProcess=TRUE;
  387.              } /* endif */
  388.           } /* endif */
  389.        } /* endwhile */
  390.        fclose(hProcessFile);
  391.   } else {
  392.      printf("Cannot open processfile\n");
  393.   } /* endif */
  394. }
  395. VOID  GetObjects(struct debug_buffer * pDbgBuf,HMODULE hMte,PSZ pName) {
  396.     APIRET rc;
  397.     int  object;
  398.     pDbgBuf->MTE  = (ULONG) hMte;
  399.     rc=0;
  400.     fprintf(hTrap,"DLL %s Handle %d\n",pName,hMte);
  401.     fprintf(hTrap,"Object Number    Address    Length     Flags      Type\n");
  402.     for (object=1;object<256;object++ ) {
  403.         pDbgBuf->Cmd   = DBG_C_NumToAddr;
  404.         pDbgBuf->Pid   = ReturnCodes.codeTerminate;
  405.         pDbgBuf->Value = object; /* Get nth object address in module with given MTE */
  406.         pDbgBuf->Buffer= 0;
  407.         pDbgBuf->Len   = 0;
  408.         rc = DosDebug(pDbgBuf);
  409.         if ((rc == NO_ERROR)&&
  410.             (pDbgBuf->Cmd==NO_ERROR)) {
  411.             ULONG Size;
  412.             ULONG Flags;
  413.             APIRET16 rc16;
  414.             pDbgBuf->Len   = 0;
  415.             pDbgBuf->Value = 0;
  416.             if (pDbgBuf->Addr!=0) {
  417.                 pDbgBuf->Cmd   = DBG_C_AddrToObject;
  418.                 pDbgBuf->Pid   = ReturnCodes.codeTerminate;
  419.                 rc = DosDebug(pDbgBuf);
  420.                 if ((rc != NO_ERROR) ||
  421.                     (pDbgBuf->Cmd|=NO_ERROR)) {
  422.                    pDbgBuf->Len   = 0;
  423.                    pDbgBuf->Value = 0;
  424.                 }
  425.             }
  426.             fprintf(hTrap,"      % 6.6d    %8.8lX   %8.8lX   %8.8lX ",object,
  427.                       pDbgBuf->Addr, pDbgBuf->Len, pDbgBuf->Value);
  428.             if (pDbgBuf->Addr!=0) {
  429.                 rc16 =DOS16SIZESEG( SELECTOROF(pDbgBuf->Addr), &Size);
  430.                 if (rc16==0) {
  431.                    fprintf(hTrap," - 16:16  Selector %4.4hX\n",SELECTOROF((PVOID)pDbgBuf->Addr));
  432.                 } else {
  433.                    fprintf(hTrap," - 32 Bits\n");
  434.                 } /* endif */
  435.             } else {
  436.                fprintf(hTrap," - ?\n");
  437.             } /* endif */
  438.         } else {
  439. //         printf("DosDebug return code = %ld Notification %8.8lX\n", rc,pDbgBuf->Cmd);
  440. //         printf("Value                = %8.8lX %ld\n",pDbgBuf->Value,pDbgBuf->Value);
  441.            break;
  442.         }
  443.     } /* endfor */
  444.     fprintf(hTrap,"\n");
  445. }
  446.