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

  1. /**********************************************************************/
  2. /*                           IBM DAPTOOLS UseOnly                    */
  3. /**********************************************************************/
  4. /*                                                                    */
  5. /*  TRAPTRAP                                                          */
  6. /*                                                                    */
  7. /* TRAPTRAP is a sample usage of DosDebug to gather information       */
  8. /* on program traps without changing the source code.                 */
  9. /* C-SET/2 compiler complies that code                                */
  10. /**********************************************************************/
  11. /* Version: 2.4             |   Marc Fiammante                        */
  12. /*                          |   La Gaude FRANCE                       */
  13. /**********************************************************************/
  14. /* Test only under OS/2 version 2.1                                   */
  15. /**********************************************************************/
  16. /* History:                                                           */
  17. /* --------                                                           */
  18. /*                                                                    */
  19. /* created: Marc Fiammante September 1993                             */
  20. /*      this traptrap.c uses DosStartSession which allows any kind    */
  21. /*           of executables PM,TextWindowed or FullScreen             */
  22. /**********************************************************************/
  23. #define INCL_BASE
  24. #include <os2.h>
  25. #include <string.h>
  26. #include <stdlib.h>
  27. #include <stdio.h>
  28. /*-------- Various Buffers and pointers ------*/
  29. CHAR   CmdBuf[256];
  30. CHAR   ObjectBuffer[256];
  31. CHAR   *CmdPtr;
  32. UCHAR  LoadError[40]; /*DosExecPGM buffer */
  33. UCHAR  ProcessName[256];
  34. CHAR   Name[CCHMAXPATH];
  35. UCHAR  *StackCopy;
  36. FILE   *hTrap;
  37. /*============================================*/
  38. /*--╔════════════════════════════════╗  ------*/
  39. /*--║ DosDebug Definitions           ║  ------*/
  40. /*--╚════════════════════════════════╝  ------*/
  41. struct debug_buffer
  42.  {
  43.    ULONG   Pid;        /* Debuggee Process ID */
  44.    ULONG   Tid;        /* Debuggee Thread ID */
  45.    LONG    Cmd;        /* Command or Notification */
  46.    LONG    Value;      /* Generic Data Value */
  47.    ULONG   Addr;       /* Debuggee Address */
  48.    ULONG   Buffer;     /* Debugger Buffer Address */
  49.    ULONG   Len;        /* Length of Range */
  50.    ULONG   Index;      /* Generic Identifier Index */
  51.    ULONG   MTE;        /* Module Handle */
  52.    ULONG   EAX;        /* Register Set */
  53.    ULONG   ECX;
  54.    ULONG   EDX;
  55.    ULONG   EBX;
  56.    ULONG   ESP;
  57.    ULONG   EBP;
  58.    ULONG   ESI;
  59.    ULONG   EDI;
  60.    ULONG   EFlags;
  61.    ULONG   EIP;
  62.    ULONG   CSLim;      /* Byte Granular Limits */
  63.    ULONG   CSBase;     /* Byte Granular Base */
  64.    UCHAR   CSAcc;      /* Access Bytes */
  65.    UCHAR   CSAtr;      /* Attribute Bytes */
  66.    USHORT  CS;
  67.    ULONG   DSLim;
  68.    ULONG   DSBase;
  69.    UCHAR   DSAcc;
  70.    UCHAR   DSAtr;
  71.    USHORT  DS;
  72.    ULONG   ESLim;
  73.    ULONG   ESBase;
  74.    UCHAR   ESAcc;
  75.    UCHAR   ESAtr;
  76.    USHORT  ES;
  77.    ULONG   FSLim;
  78.    ULONG   FSBase;
  79.    UCHAR   FSAcc;
  80.    UCHAR   FSAtr;
  81.    USHORT  FS;
  82.    ULONG   GSLim;
  83.    ULONG   GSBase;
  84.    UCHAR   GSAcc;
  85.    UCHAR   GSAtr;
  86.    USHORT  GS;
  87.    ULONG   SSLim;
  88.    ULONG   SSBase;
  89.    UCHAR   SSAcc;
  90.    UCHAR   SSAtr;
  91.    USHORT  SS;
  92. } DbgBuf;
  93. /*-------------------------------------*/
  94. /*---- Commands -----------------------*/
  95. #define DBG_C_NULL                 0
  96. #define DBG_C_ReadMem              1
  97. #define DBG_C_ReadMem_I            1
  98. #define DBG_C_ReadMem_D            2
  99. #define DBG_C_ReadReg              3
  100. #define DBG_C_WriteMem             4
  101. #define DBG_C_WriteMem_I           4
  102. #define DBG_C_WriteMem_D           5
  103. #define DBG_C_WriteReg             6
  104. #define DBG_C_Go                   7
  105. #define DBG_C_Term                 8
  106. #define DBG_C_SStep                9
  107. #define DBG_C_Stop                 10
  108. #define DBG_C_Freeze               11
  109. #define DBG_C_Resume               12
  110. #define DBG_C_NumToAddr            13
  111. #define DBG_C_ReadCoRegs           14
  112. #define DBG_C_WriteCoRegs          15
  113. #define DBG_C_ThrdStat             17
  114. #define DBG_C_MapROAlias           18
  115. #define DBG_C_MapRWAlias           19
  116. #define DBG_C_UnMapALias           20
  117. #define DBG_C_Connect              21
  118. #define DBG_C_ReadMemBuf           22
  119. #define DBG_C_WriteMemBuf          23
  120. #define DBG_C_SetWatch             24
  121. #define DBG_C_ClearWatch           25
  122. #define DBG_C_RangeStep            26
  123. #define DBG_C_Continue             27
  124. #define DBG_C_AddrToObject         28
  125. #define DBG_C_XchngOpCode          29
  126. #define DBG_C_LinToSel             30
  127. #define DBG_C_SelToLin             31
  128. /*------ Constants -------------------*/
  129. #define DBG_L_386                   1
  130. #define DBG_O_OBJMTE       0x10000000L
  131. /*------ Notifications ---------------*/
  132. #define DBG_N_SUCCESS               0
  133. #define DBG_N_ERROR                -1
  134. #define DBG_N_ProcTerm             -6
  135. #define DBG_N_Exception            -7
  136. #define DBG_N_ModuleLoad           -8
  137. #define DBG_N_CoError              -9
  138. #define DBG_N_ThreadTerm           -10
  139. #define DBG_N_AsyncStop            -11
  140. #define DBG_N_NewProc              -12
  141. #define DBG_N_AliasFree            -13
  142. #define DBG_N_Watchpoint           -14
  143. #define DBG_N_ThreadCreate         -15
  144. #define DBG_N_ModuleFree           -16
  145. #define DBG_N_RangeStep            -17
  146. #define DBG_X_FIRST_CHANCE          1
  147. #define DBG_X_STACK_INVALID         3
  148. RESULTCODES ReturnCodes;
  149. APIRET CheckExcep( PEXCEPTIONREPORTRECORD       pERepRec,
  150.                    PCONTEXTRECORD               pCtxRec);
  151. /*-------------------------------------*/
  152. CHAR    Buffer[CCHMAXPATH];
  153.  
  154. typedef ULONG     * _Seg16 PULONG16;
  155. APIRET16 APIENTRY16 DOS16SIZESEG( USHORT Seg , PULONG16 Size);
  156. typedef  APIRET16  (APIENTRY16  _PFN16)();
  157. /*-------------------------------------*/
  158. /*- DosQProcStatus interface ----------*/
  159. APIRET16 APIENTRY16 DOSQPROCSTATUS(  ULONG * _Seg16 pBuf, USHORT cbBuf);
  160. #define CONVERT(fp,QSsel) MAKEP((QSsel),OFFSETOF(fp))
  161. #pragma pack(1)
  162. /*  Global Data Section */
  163. typedef struct qsGrec_s {
  164.     ULONG     cThrds;  /* number of threads in use */
  165.     ULONG     Reserved1;
  166.     ULONG     Reserved2;
  167. }qsGrec_t;
  168. /* Thread Record structure *   Holds all per thread information. */
  169. typedef struct qsTrec_s {
  170.     ULONG     RecType;    /* Record Type */
  171.                           /* Thread rectype = 100 */
  172.     USHORT    tid;        /* thread ID */
  173.     USHORT    slot;       /* "unique" thread slot number */
  174.     ULONG     sleepid;    /* sleep id thread is sleeping on */
  175.     ULONG     priority;   /* thread priority */
  176.     ULONG     systime;    /* thread system time */
  177.     ULONG     usertime;   /* thread user time */
  178.     UCHAR     state;      /* thread state */
  179.     UCHAR     PADCHAR;
  180.     USHORT    PADSHORT;
  181. } qsTrec_t;
  182. /* Process and Thread Data Section */
  183. typedef struct qsPrec_s {
  184.     ULONG           RecType;    /* type of record being processed */
  185.                           /* process rectype = 1       */
  186.     qsTrec_t *      pThrdRec;  /* ptr to 1st thread rec for this prc*/
  187.     USHORT          pid;       /* process ID */
  188.     USHORT          ppid;      /* parent process ID */
  189.     ULONG           type;      /* process type */
  190.     ULONG           stat;      /* process status */
  191.     ULONG           sgid;      /* process screen group */
  192.     USHORT          hMte;      /* program module handle for process */
  193.     USHORT          cTCB;      /* # of TCBs in use in process */
  194.     ULONG           Reserved1;
  195.     void   *        Reserved2;
  196.     USHORT          c16Sem;     /*# of 16 bit system sems in use by proc*/
  197.     USHORT          cLib;       /* number of runtime linked libraries */
  198.     USHORT          cShrMem;    /* number of shared memory handles */
  199.     USHORT          Reserved3;
  200.     USHORT *        p16SemRec;   /*ptr to head of 16 bit sem inf for proc*/
  201.     USHORT *        pLibRec;     /*ptr to list of runtime lib in use by */
  202.                                   /*process*/
  203.     USHORT *        pShrMemRec;  /*ptr to list of shared mem handles in */
  204.                                   /*use by process*/
  205.     USHORT *        Reserved4;
  206. } qsPrec_t;
  207. /* 16 Bit System Semaphore Section */
  208. typedef struct qsS16Headrec_s {
  209.     ULONG     RecType;   /* semaphore rectype = 3 */
  210.     ULONG     Reserved1;  /* overlays NextRec of 1st qsS16rec_t */
  211.     ULONG     Reserved2;
  212.     ULONG     S16TblOff;  /* index of first semaphore,SEE PSTAT OUTPUT*/
  213.                           /* System Semaphore Information Section     */
  214. } qsS16Headrec_t;
  215. /*  16 bit System Semaphore Header Record Structure */
  216. typedef struct qsS16rec_s {
  217.     ULONG      NextRec;          /* offset to next record in buffer */
  218.     UINT       s_SysSemOwner ;   /* thread owning this semaphore    */
  219.     UCHAR      s_SysSemFlag ;    /* system semaphore flag bit field */
  220.     UCHAR      s_SysSemRefCnt ;  /* number of references to this    */
  221.                                  /*  system semaphore               */
  222.     UCHAR      s_SysSemProcCnt ; /*number of requests by sem owner  */
  223.     UCHAR      Reserved1;
  224.     ULONG      Reserved2;
  225.     UINT       Reserved3;
  226.     CHAR       SemName[1];       /* start of semaphore name string */
  227. } qsS16rec_t;
  228. /*  Executable Module Section */
  229. typedef struct qsLrec_s {
  230.     void        * pNextRec;    /* pointer to next record in buffer */
  231.     USHORT        hmte;         /* handle for this mte */
  232.     USHORT        Reserved1;    /* Reserved */
  233.     ULONG         ctImpMod;     /* # of imported modules in table */
  234.     ULONG         Reserved2;    /* Reserved */
  235. /*  qsLObjrec_t * Reserved3;       Reserved */
  236.     ULONG       * Reserved3;    /* Reserved */
  237.     UCHAR       * pName;        /* ptr to name string following stru*/
  238. } qsLrec_t;
  239. /*  Shared Memory Segment Section */
  240. typedef struct qsMrec_s {
  241.     struct qsMrec_s *MemNextRec;    /* offset to next record in buffer */
  242.     USHORT    hmem;          /* handle for shared memory */
  243.     USHORT    sel;           /* shared memory selector */
  244.     USHORT    refcnt;        /* reference count */
  245.     CHAR      Memname[1];    /* start of shared memory name string */
  246. } qsMrec_t;
  247. /*  Pointer Record Section */
  248. typedef struct qsPtrRec_s {
  249.     qsGrec_t       *  pGlobalRec;        /* ptr to the global data section */
  250.     qsPrec_t       *  pProcRec;          /* ptr to process record section  */
  251.     qsS16Headrec_t *  p16SemRec;         /* ptr to 16 bit sem section      */
  252.     void           *  Reserved;          /* a reserved area                */
  253.     qsMrec_t       *  pShrMemRec;        /* ptr to shared mem section      */
  254.     qsLrec_t       *  pLibRec;           /*ptr to exe module record section*/
  255. } qsPtrRec_t;
  256. /*-------------------------*/
  257. ULONG * pBuf,*pTemp;
  258. USHORT  Selector;
  259. qsPtrRec_t * pRec;
  260. qsLrec_t   * pLib;
  261. qsMrec_t   * pShrMemRec;        /* ptr to shared mem section      */
  262. qsPrec_t   * pProc;
  263. qsTrec_t   * pThread;
  264. ULONG      ListedThreads=0;
  265. APIRET16 APIENTRY16 DOS16ALLOCSEG(
  266.         USHORT          cbSize,          /* number of bytes requested                   */
  267.         USHORT  * _Seg16 pSel,           /* sector allocated (returned)                 */
  268.         USHORT fsAlloc);                 /* sharing attributes of the allocated segment */
  269. VOID ListModules(VOID);
  270. VOID  GetObjects(struct debug_buffer * pDbgBuf,HMODULE hMte,PSZ pName);
  271. CHAR *QueueName="\\QUEUES\\TRACE\\TRACE.QUE";
  272. HQUEUE QueueHandle=0;
  273. /*-------------------------------------*/
  274. int main(int argc, char **argv)
  275. {
  276.    APIRET rc;
  277.    PEXCEPTIONREPORTRECORD       pERepRec;
  278.    PCONTEXTRECORD               pCtxRec;
  279.    char  * Dot;
  280.    char  * Slash;
  281.    BOOL First;
  282.    ULONG SessId;
  283.    STARTDATA StartData;
  284.    REQUESTDATA Request;
  285.    ULONG       cbData;
  286.    PUSHORT     Data;
  287.    BYTE        priority;
  288.    ULONG       cbEntries;
  289.    ULONG       AppType;
  290.    int i;
  291.    if (argc==1) {
  292.       printf("Program Name Missing\n");
  293.       return ERROR_INVALID_PARAMETER;
  294.    } /* endif */
  295.    /*--------------------------------------------------*/
  296.    /*- Build new command line    ----------------------*/
  297.    argc--;argv++;
  298.    /* strcpy(CmdBuf,argv[0]); Only for DosExecPgm */
  299.    strcpy(ProcessName,argv[0]);
  300.    Dot=strrchr(ProcessName,'.');
  301.    /*-- look for .EXE */
  302.    if (Dot==NULL) {
  303.       strcat(ProcessName,".EXE");
  304.    } else {
  305.       Slash=strrchr(ProcessName,'\\');
  306.       /* Maybe '.' for current directory but no EXE extension */
  307.       if (Slash>Dot) {
  308.          strcat(ProcessName,".EXE");
  309.       } /* endif */
  310.    } /* endif */
  311.    strupr(ProcessName);
  312.    CmdPtr=CmdBuf/*+strlen(CmdBuf)+1*/;
  313.    *CmdPtr=0x00; /* Add supplem */
  314.    argc--;argv++;
  315.    for (i=0;i<argc;i++ ) {
  316.       strcat(CmdPtr," ");
  317.       strcat(CmdPtr,argv[i]);
  318.    } /* endfor */
  319.    /*--------------------------------------------------*/
  320.    hTrap=fopen("PROCESS.TRP","w");
  321.    /*--------------------------------------------------*/
  322. // rc = DosExecPgm(LoadError,          /* Object name buffer */
  323. //                 sizeof(LoadError),  /* Length of object name buffer */
  324. //                 EXEC_TRACE,         /* Asynchronous/Trace flags */
  325. //                 CmdBuf,            /* Argument string */
  326. //                 NULL,               /* Environment string */
  327. //                 &ReturnCodes,       /* Termination codes */
  328. //                 ProcessName);           /* Program file name */
  329.    rc=DosCreateQueue( &QueueHandle , QUE_FIFO,QueueName);
  330.    fprintf(hTrap,"Create queue rc %d\n", rc);
  331.    memset(&StartData,0x00,sizeof(STARTDATA));
  332.    DosQueryAppType(ProcessName,&AppType);
  333.    AppType=0x0003 & AppType;
  334.    StartData.Length=sizeof(STARTDATA);         /* length of data structure    */
  335.    StartData.Related=SSF_RELATED_CHILD;        /* 0 = independent session,    */
  336.                                                /* 1 = child session           */
  337.    StartData.FgBg=SSF_FGBG_FORE;               /* 0 = start in foreground,    */
  338.                                                /* 1 = start in background     */
  339.    StartData.TraceOpt=SSF_TRACEOPT_TRACEALL;   /* 0 = no trace, 1 = trace     */
  340.    StartData.PgmTitle=ProcessName;             /* address of program title    */
  341.    StartData.PgmName=ProcessName;              /* address of program name     */
  342.    StartData.PgmInputs=CmdBuf;                 /* input arguments             */
  343.    StartData.TermQ      =QueueName;            /*address of program queue name*/
  344.    StartData.Environment=NULL;                 /* environment string          */
  345.    StartData.InheritOpt=SSF_INHERTOPT_PARENT;  /* where are handles and       */
  346.                                                /*  environment inherited from */
  347.                                                /* 0 = inherit from shell ,    */
  348.                                                /*     1 = inherit from caller */
  349.    StartData.SessionType=AppType;              /* session type                */
  350.    StartData.IconFile  =0;                     /* address of icon definition  */
  351.    StartData.PgmHandle =0;                     /* program handle              */
  352.    StartData.PgmControl=SSF_CONTROL_VISIBLE;   /*initial state of windowed app*/
  353.    StartData.InitXPos=  0;                     /*x coor of init session window*/
  354.    StartData.InitYPos=  0;                     /*y coor of init session window*/
  355.    StartData.InitXSize= 0;                     /* initial size of x           */
  356.    StartData.InitYSize= 0;                     /* initial size of y           */
  357.    StartData.Reserved =0;
  358.    StartData.ObjectBuffer=ObjectBuffer;
  359.    StartData.ObjectBuffLen=sizeof(ObjectBuffer);
  360.    DosSelectSession(0);
  361.    rc=DosStartSession(
  362.      &StartData,
  363.      &SessId,
  364.      &ReturnCodes.codeTerminate);
  365.    fprintf(hTrap,"rc = %d Process ID %d  Session %d >%s<>%s<>%s<\n",
  366.              rc,
  367.              ReturnCodes.codeTerminate,
  368.              SessId,ProcessName,ObjectBuffer,CmdBuf);
  369.    if (rc != NO_ERROR) {
  370.        return;
  371.    }
  372.    fprintf(hTrap,"Connecting  to PID %d\n",ReturnCodes.codeTerminate);
  373.    DbgBuf.Cmd = DBG_C_Connect; /* Indicate that a Connect is requested */
  374.    DbgBuf.Pid = ReturnCodes.codeTerminate;
  375.    DbgBuf.Tid = 0;
  376.    DbgBuf.Value = DBG_L_386;
  377.    rc = DosDebug(&DbgBuf);
  378.    if (rc != 0) {
  379.        fprintf(hTrap,"DosDebug error: return code = %ld Note %8.8lX\n", rc,DbgBuf.Cmd);
  380.        fprintf(hTrap,"Value          = %8.8lX %ld\n",DbgBuf.Value,DbgBuf.Value);
  381.    }
  382.    while (DbgBuf.Cmd!=DBG_N_ProcTerm) {
  383.       DosSleep(50L);
  384.       fprintf(hTrap,"Now Issuing Go\n");
  385.       fflush(hTrap);
  386.       DbgBuf.Cmd = DBG_C_Go; /* Indicate that a Connect is requested */
  387.       DbgBuf.Pid = ReturnCodes.codeTerminate; /* Pid of Debuggee */
  388.       rc = DosDebug(&DbgBuf);
  389.       if (rc != 0) {
  390.           fprintf(hTrap,"DosDebug error: return code = %ld Note %8.8lX\n", rc,DbgBuf.Cmd);
  391.           fprintf(hTrap,"Value          = %8.8lX %ld\n",DbgBuf.Value,DbgBuf.Value);
  392.       }
  393.       switch (DbgBuf.Cmd) {
  394.           case DBG_N_SUCCESS:
  395.              fprintf(hTrap,"DosDebug GO Successfull\n");
  396.              break;
  397.           case DBG_N_ERROR:
  398.              fprintf(hTrap,"DosDebug Error %8.8lXx (%ld)\n",DbgBuf.Value,DbgBuf.Value);
  399.              break;
  400.           case DBG_N_ProcTerm:
  401.              fprintf(hTrap,"Process Terminated with rc %d\n",DbgBuf.Value);
  402.              break;
  403.           case DBG_N_Exception:
  404.              fprintf(hTrap,"Exception Occurred\n");
  405.              break;
  406.           case DBG_N_ModuleLoad:
  407.              Name[0]=0x00;
  408.              rc=DosQueryModuleName(DbgBuf.Value,CCHMAXPATH, Name);
  409.              fprintf(hTrap,"MODULE %s loaded\n",Name);
  410.              break;
  411.           case DBG_N_CoError:
  412.              fprintf(hTrap,"Coprocessor Error\n");
  413.              break;
  414.           case DBG_N_ThreadTerm:
  415.              fprintf(hTrap,"Thread %d Terminated with rc %d\n",DbgBuf.Tid,DbgBuf.Value);
  416.              break;
  417.           case DBG_N_AsyncStop:
  418.              fprintf(hTrap,"Asynchronous Stop\n");
  419.              break;
  420.           case DBG_N_NewProc:
  421.              fprintf(hTrap,"Debuggee started New Process Pid %X\n",DbgBuf.Value);
  422.              break;
  423.           case DBG_N_AliasFree:
  424.              fprintf(hTrap,"Alias Freed\n");
  425.              break;
  426.           case DBG_N_Watchpoint:
  427.              fprintf(hTrap,"WatchPoint Hit\n");
  428.              break;
  429.           case DBG_N_ThreadCreate:
  430.              fprintf(hTrap,"Thread %d Created\n",DbgBuf.Tid);
  431.              break;
  432.           case DBG_N_ModuleFree:
  433.              Name[0]=0x00;
  434.              rc=DosQueryModuleName(DbgBuf.Value,CCHMAXPATH, Name);
  435.              fprintf(hTrap,"MODULE %s freed\n",Name);
  436.              break;
  437.           case DBG_N_RangeStep:
  438.              fprintf(hTrap,"RangeStep fault\n");
  439.              break;
  440.       } /* endswitch */
  441.       fflush(hTrap);
  442.       if (DbgBuf.Cmd==DBG_N_Exception) {
  443.             if ((DbgBuf.Value==DBG_X_FIRST_CHANCE) ||
  444.                 (DbgBuf.Value==DBG_X_STACK_INVALID)) {
  445.                 fprintf(hTrap,"Got the exception on Thread %d\n",DbgBuf.Tid);
  446.                 pERepRec=(PEXCEPTIONREPORTRECORD)DbgBuf.Buffer;
  447.                 pCtxRec =(PCONTEXTRECORD)DbgBuf.Len;
  448.                 if (CheckExcep(pERepRec,pCtxRec)) break;
  449.             }
  450.       } /* endif */
  451.    } /* endwhile */
  452.   // fclose(hTrap);
  453. }
  454. APIRET CheckExcep( PEXCEPTIONREPORTRECORD       pERepRec,
  455.                    PCONTEXTRECORD               pCtxRec) {
  456.   APIRET rc;
  457.   USHORT Count;
  458.   UCHAR   Translate[17];
  459.   PUSHORT StackPtr;
  460.   PUCHAR  cStackPtr;
  461.   EXCEPTIONREPORTRECORD       ERepRec;
  462.   CONTEXTRECORD               CtxRec;
  463.   static CHAR Format[10];
  464.   ULONG  stacklen;
  465.   UCHAR *stackptr;
  466.   fprintf(hTrap,"\n/*----- getting exception records ---*/\n");
  467.   DbgBuf.Cmd = DBG_C_ReadMemBuf; /* Indicate that a Connect is requested */
  468.   DbgBuf.Pid = ReturnCodes.codeTerminate; /* Pid of Debuggee */
  469.   DbgBuf.Addr   =(ULONG) pERepRec;
  470.   DbgBuf.Buffer =(ULONG) &ERepRec;
  471.   DbgBuf.Len    = sizeof(EXCEPTIONREPORTRECORD);
  472.   rc = DosDebug(&DbgBuf);
  473.   if (rc != 0) {
  474.       fprintf(hTrap,"DosDebug error: return code = %ld Note %8.8lX\n", rc,DbgBuf.Cmd);
  475.       fprintf(hTrap,"Value          = %8.8lX %ld\n",DbgBuf.Value,DbgBuf.Value);
  476.       return 1;
  477.   }
  478.   fprintf(hTrap,"\n/*----- getting Context record ---*/\n");
  479.   DbgBuf.Cmd = DBG_C_ReadMemBuf; /* Indicate that a Connect is requested */
  480.   DbgBuf.Pid = ReturnCodes.codeTerminate; /* Pid of Debuggee */
  481.   DbgBuf.Addr   =(ULONG) pCtxRec;
  482.   DbgBuf.Buffer =(ULONG) &CtxRec;
  483.   DbgBuf.Len    = sizeof(CONTEXTRECORD);
  484.   rc = DosDebug(&DbgBuf);
  485.   if (rc != 0) {
  486.       fprintf(hTrap,"DosDebug error: return code = %ld Note %8.8lX\n", rc,DbgBuf.Cmd);
  487.       fprintf(hTrap,"Value          = %8.8lX %ld\n",DbgBuf.Value,DbgBuf.Value);
  488.       return 1;
  489.   }
  490.   if ((ERepRec.ExceptionNum&XCPT_SEVERITY_CODE)==XCPT_FATAL_EXCEPTION)
  491.   {
  492.     if ((ERepRec.ExceptionNum!=XCPT_PROCESS_TERMINATE)&&
  493.         (ERepRec.ExceptionNum!=XCPT_UNWIND)&&
  494.         (ERepRec.ExceptionNum!=XCPT_SIGNAL)&&
  495.         (ERepRec.ExceptionNum!=XCPT_ASYNC_PROCESS_TERMINATE)) {
  496.         fprintf(hTrap,"--------------------------\n");
  497.         fprintf(hTrap,"Exception %8.8lX Occurred\n",ERepRec.ExceptionNum);
  498.         fprintf(hTrap," at %s ",_strtime(Buffer));
  499.         fprintf(hTrap," %s\n",_strdate(Buffer));
  500.         if ( ERepRec.ExceptionNum     ==         XCPT_ACCESS_VIOLATION)
  501.         {
  502.            switch (ERepRec.ExceptionInfo[0]) {
  503.                 case XCPT_READ_ACCESS:
  504.                 case XCPT_WRITE_ACCESS:
  505.                    fprintf(hTrap,"Invalid linear address %8.8lX\n",ERepRec.ExceptionInfo[1]);
  506.                    break;
  507.                 case XCPT_SPACE_ACCESS:
  508.                    fprintf(hTrap,"Invalid Selector %8.8lX\n",ERepRec.ExceptionInfo[1]);
  509.                    break;
  510.                 case XCPT_LIMIT_ACCESS:
  511.                    fprintf(hTrap,"Limit access fault\n");
  512.                    break;
  513.                 case XCPT_UNKNOWN_ACCESS:
  514.                    fprintf(hTrap,"Unknown access fault\n");
  515.                    break;
  516.               break;
  517.            default:
  518.                    fprintf(hTrap,"Other Unknown access fault\n");
  519.            } /* endswitch */
  520.         } /* endif */
  521.         if ( (CtxRec.ContextFlags) & CONTEXT_SEGMENTS ) {
  522.              fprintf(hTrap,"GS  : %4.4lX     ",CtxRec.ctx_SegGs);
  523.              fprintf(hTrap,"FS  : %4.4lX     ",CtxRec.ctx_SegFs);
  524.              fprintf(hTrap,"ES  : %4.4lX     ",CtxRec.ctx_SegEs);
  525.              fprintf(hTrap,"DS  : %4.4lX     \n",CtxRec.ctx_SegDs);
  526.         } /* endif */
  527.         if ( (CtxRec.ContextFlags) & CONTEXT_INTEGER  ) {
  528.              fprintf(hTrap,"EDI : %8.8lX ",CtxRec.ctx_RegEdi  );
  529.              fprintf(hTrap,"ESI : %8.8lX ",CtxRec.ctx_RegEsi  );
  530.              fprintf(hTrap,"EAX : %8.8lX ",CtxRec.ctx_RegEax  );
  531.              fprintf(hTrap,"EBX : %8.8lX\n",CtxRec.ctx_RegEbx  );
  532.              fprintf(hTrap,"ECX : %8.8lX ",CtxRec.ctx_RegEcx  );
  533.              fprintf(hTrap,"EDX : %8.8lX\n",CtxRec.ctx_RegEdx  );
  534.         } /* endif */
  535.         if ( (CtxRec.ContextFlags) & CONTEXT_CONTROL  ) {
  536.              void * _Seg16 Ptr16;
  537.              fprintf(hTrap,"EBP : %8.8lX ",CtxRec.ctx_RegEbp  );
  538.              fprintf(hTrap,"EIP : %8.8lX ",CtxRec.ctx_RegEip  );
  539.              fprintf(hTrap,"EFLG: %8.8lX ",CtxRec.ctx_EFlags  );
  540.              fprintf(hTrap,"ESP : %8.8lX\n",CtxRec.ctx_RegEsp  );
  541.              fprintf(hTrap,"CS  : %4.4lX     ",CtxRec.ctx_SegCs   );
  542.              fprintf(hTrap,"SS  : %4.4lX\n",CtxRec.ctx_SegSs   );
  543.              fprintf(hTrap,"CSLIM: %8.8lX "  ,DbgBuf.CSLim);
  544.              fprintf(hTrap,"SSLIM: %8.8lX \n",DbgBuf.SSLim);
  545.              fprintf(hTrap,"FSLIM: %8.8lX \n",DbgBuf.FSLim);
  546.              fprintf(hTrap,"FSBase: %8.8lX \n",DbgBuf.FSBase);
  547.              fprintf(hTrap,"FS    : %4.4X \n",DbgBuf.FS);
  548.              ListModules();
  549.              /*------ Now the stack ---------------------------*/
  550.              /*--I should use the stacklimits in the struture--*/
  551.              /*--pointed by FS:0 but there is a bug in OS/2  --*/
  552.              /*--see APAR PJ06136 FS is mapped to the        --*/
  553.              /*--debuggers thread not the debuggee  !!!!!!   --*/
  554.              fprintf(hTrap,"\n/*----- getting Stack Object ---*/\n");
  555.              if (CtxRec.ctx_RegEsp<0x10000) { /* stack is 16:16 */
  556.                 DbgBuf.Cmd   = DBG_C_SelToLin;
  557.                 DbgBuf.Pid   = ReturnCodes.codeTerminate; /* Pid of Debuggee */
  558.                 DbgBuf.Value = CtxRec.ctx_SegSs;
  559.                 DbgBuf.Index = CtxRec.ctx_RegEsp;;
  560.                 rc = DosDebug(&DbgBuf);
  561.                 if (rc != 0) {
  562.                     fprintf(hTrap,"DosDebug error: return code = %ld Note %8.8lX\n", rc,DbgBuf.Cmd);
  563.                     fprintf(hTrap,"Value          = %8.8lX %ld\n",DbgBuf.Value,DbgBuf.Value);
  564.                     return 1;
  565.                 }
  566.                 fprintf(hTrap,"Linear 16:16 stack Address %p\n",DbgBuf.Addr);
  567.              } else {
  568.                 DbgBuf.Addr   =(ULONG) CtxRec.ctx_RegEsp;
  569.              } /* endif */
  570.              DbgBuf.Cmd = DBG_C_AddrToObject;/* Indicate that a Connect is requested */
  571.              DbgBuf.Pid = ReturnCodes.codeTerminate; /* Pid of Debuggee */
  572.              rc = DosDebug(&DbgBuf);
  573.              if (rc != 0) {
  574.                  fprintf(hTrap,"DosDebug error: return code = %ld Note %8.8lX\n", rc,DbgBuf.Cmd);
  575.                  fprintf(hTrap,"Value          = %8.8lX %ld\n",DbgBuf.Value,DbgBuf.Value);
  576.                  return 1;
  577.              }
  578.              stacklen   = DbgBuf.Len;
  579.              fprintf(hTrap,"Thread  Id %lu \n", DbgBuf.Tid);
  580.              Ptr16=(void * _Seg16)DbgBuf.Buffer;
  581.              sprintf(Format,"%8.8lX",Ptr16);
  582.              fprintf(hTrap,"Stack Bottom : %8.8lX (%4.4s:%4.4s) ;",DbgBuf.Buffer,Format,Format+4);
  583.              Ptr16=(void * _Seg16)(DbgBuf.Buffer+DbgBuf.Len-1);
  584.              sprintf(Format,"%8.8lX",Ptr16);
  585.              fprintf(hTrap,"Stack Top    : %8.8lX (%4.4s:%4.4s) \n",DbgBuf.Buffer+DbgBuf.Len,Format,Format+4);
  586.              fprintf(hTrap,"Process Id : %lu ", DbgBuf.Pid);
  587.              rc=DosQueryModuleName(DbgBuf.MTE,CCHMAXPATH, Name);
  588.              if (rc==NO_ERROR) {
  589.                 fprintf(hTrap,".EXE name : %s\n",Name);
  590.              } else {
  591.                 fprintf(hTrap,".EXE name : ??????\n");
  592.              } /* endif */
  593.              Count=0;
  594.              Translate[0]=0x00;
  595.              StackCopy=malloc(stacklen);
  596.              fprintf(hTrap,"\n/*----- Stack Object Bottom ---*/\n");
  597.              fprintf(hTrap,"StackCopy %p Length %d\n", StackCopy,DbgBuf.Len);
  598.              DbgBuf.Cmd  = DBG_C_ReadMemBuf; /* Indicate that a Connect is requested */
  599.              DbgBuf.Pid  = ReturnCodes.codeTerminate; /* Pid of Debuggee */
  600.              DbgBuf.Addr = DbgBuf.Buffer;
  601.              DbgBuf.Len  = stacklen;
  602.              DbgBuf.Buffer =(ULONG) StackCopy;
  603.              rc = DosDebug(&DbgBuf);
  604.              if (rc != 0) {
  605.                  fprintf(hTrap,"DosDebug error: return code = %ld Note %8.8lX\n", rc,DbgBuf.Cmd);
  606.                  fprintf(hTrap,"Value          = %8.8lX %ld\n",DbgBuf.Value,DbgBuf.Value);
  607.              } else {
  608.                  for (StackPtr=(PUSHORT)StackCopy;
  609.                       StackPtr<(PUSHORT)(StackCopy+stacklen);
  610.                       StackPtr++) {
  611.                       if (Count==0) {
  612.                          fprintf(hTrap,"  %s\n %8.8X :",Translate,DbgBuf.Addr+(((PUCHAR)StackPtr)-StackCopy));
  613.                          Translate[0]=0x00;
  614.                       } /* endif */
  615.                       fprintf(hTrap,"%4.4hX ",*StackPtr);
  616.                       cStackPtr=(PUCHAR)StackPtr;
  617.                       if ((isprint(*cStackPtr)) &&
  618.                           (*cStackPtr>=0x20)  ) {
  619.                          Translate[2*Count]=*cStackPtr;
  620.                       } else {
  621.                          Translate[2*Count]='.';
  622.                       } /* endif */
  623.                       cStackPtr++;
  624.                       if ((isprint(*cStackPtr) )&&
  625.                           ( *cStackPtr >=0x20 )  ) {
  626.                          Translate[2*Count+1]=*cStackPtr;
  627.                       } else {
  628.                          Translate[2*Count+1]='.';
  629.                       } /* endif */
  630.                       Count++;
  631.                       Translate[2*Count]=0x00;
  632.                       if (Count==8) {
  633.                           Count=0;
  634.                       } /* endif */
  635.                  } /* endfor */
  636.                  fprintf(hTrap,"%s\n/*----- Stack Object Top -----*/\n",Translate);
  637.              } /* endif */
  638.         } /* endif */
  639.      } else {
  640.         fprintf(hTrap,"Other fatal exception %8.8lx ",ERepRec.ExceptionNum);
  641.         fprintf(hTrap,"At address            %8.8lx\n",ERepRec.ExceptionAddress);
  642.      } /* endif */
  643.      return 1L;
  644.   } else {
  645.      fprintf(hTrap,"Other non fatal exception %8.8lx ",ERepRec.ExceptionNum);
  646.      fprintf(hTrap,"At address                %8.8lx\n",ERepRec.ExceptionAddress);
  647.      return 0L;
  648.   } /* endif */
  649.  
  650. }
  651. VOID ListModules() {
  652.   APIRET   rc;
  653.   APIRET16 rc16;
  654.   /**----------------------------------***/
  655.   rc16=DOS16ALLOCSEG( 0xFFFF , &Selector , 0);
  656.   if (rc16==0) {
  657.      pBuf=MAKEP(Selector,0);
  658.      rc16=DOSQPROCSTATUS(pBuf, 0xFFFF );
  659.      if (rc16==0) {
  660.        /*****************************/
  661.        pRec=(qsPtrRec_t *) pBuf;
  662.        pLib=pRec->pLibRec;
  663.        while (pLib) {
  664.            GetObjects(&DbgBuf,pLib->hmte,pLib->pName);
  665.            pLib =pLib->pNextRec;
  666.        } /* endwhile */
  667.      } else {
  668.        fprintf(hTrap,"DosQProcStatus Failed %hd\n",rc16);
  669.      } /* endif */
  670.   } else {
  671.      fprintf(hTrap,"DosAllocSeg Failed %hd\n",rc16);
  672.   } /* endif */
  673. }
  674. VOID  GetObjects(struct debug_buffer * pDbgBuf,HMODULE hMte,PSZ pName) {
  675.     APIRET rc;
  676.     int  object;
  677.     pDbgBuf->MTE  = (ULONG) hMte;
  678.     rc=0;
  679.     fprintf(hTrap,"DLL %s Handle %d\n",pName,hMte);
  680.     fprintf(hTrap,"Object Number    Address    Length     Flags      Type\n");
  681.     for (object=1;object<256;object++ ) {
  682.         pDbgBuf->Cmd   = DBG_C_NumToAddr;
  683.         pDbgBuf->Pid   = ReturnCodes.codeTerminate;
  684.         pDbgBuf->Value = object; /* Get nth object address in module with given MTE */
  685.         pDbgBuf->Buffer= 0;
  686.         pDbgBuf->Len   = 0;
  687.         rc = DosDebug(pDbgBuf);
  688.         if ((rc == NO_ERROR)&&
  689.             (pDbgBuf->Cmd==NO_ERROR)) {
  690.             ULONG Size;
  691.             ULONG Flags;
  692.             APIRET16 rc16;
  693.             pDbgBuf->Len   = 0;
  694.             pDbgBuf->Value = 0;
  695.             if (pDbgBuf->Addr!=0) {
  696.                 pDbgBuf->Cmd   = DBG_C_AddrToObject;
  697.                 pDbgBuf->Pid   = ReturnCodes.codeTerminate;
  698.                 rc = DosDebug(pDbgBuf);
  699.                 if ((rc != NO_ERROR) ||
  700.                     (pDbgBuf->Cmd|=NO_ERROR)) {
  701.                    pDbgBuf->Len   = 0;
  702.                    pDbgBuf->Value = 0;
  703.                 }
  704.             }
  705.             fprintf(hTrap,"      % 6.6d    %8.8lX   %8.8lX   %8.8lX ",object,
  706.                       pDbgBuf->Addr, pDbgBuf->Len, pDbgBuf->Value);
  707.             if (pDbgBuf->Addr!=0) {
  708.                 rc16 =DOS16SIZESEG( SELECTOROF(pDbgBuf->Addr), &Size);
  709.                 if (rc16==0) {
  710.                    fprintf(hTrap," - 16:16  Selector %4.4hX\n",SELECTOROF((PVOID)pDbgBuf->Addr));
  711.                 } else {
  712.                    fprintf(hTrap," - 32 Bits\n");
  713.                 } /* endif */
  714.             } else {
  715.                fprintf(hTrap," - ?\n");
  716.             } /* endif */
  717.         } else {
  718. //         printf("DosDebug return code = %ld Notification %8.8lX\n", rc,pDbgBuf->Cmd);
  719. //         printf("Value                = %8.8lX %ld\n",pDbgBuf->Value,pDbgBuf->Value);
  720.            break;
  721.         }
  722.     } /* endfor */
  723.     fprintf(hTrap,"\n");
  724. }
  725.