home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / except2x.zip / traptrap.c < prev    next >
C/C++ Source or Header  |  1995-05-17  |  38KB  |  853 lines

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