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

  1. /**********************************************************************/
  2. /*                           IBM DAPTOOLS UseOnly                    */
  3. /**********************************************************************/
  4. /*                                                                    */
  5. /*  EXCEPTQ                                                           */
  6. /*                                                                    */
  7. /* DLL containing an exception handler for gathering trap information */
  8. /* This DLL dumps all important debugging Data and is accessible      */
  9. /* from both 16 bit and 32 bits programs                              */
  10. /**********************************************************************/
  11. /* Version: 2.2             |   Marc Fiammante                        */
  12. /*                          |   La Gaude FRANCE                       */
  13. /**********************************************************************/
  14. /*                                                                    */
  15. /**********************************************************************/
  16. /* History:                                                           */
  17. /* --------                                                           */
  18. /*                                                                    */
  19. /* created: Marc Fiammante December 1992                              */
  20. /**********************************************************************/
  21. #define INCL_BASE
  22. #define INCL_DOSEXCEPTIONS
  23. #define INCL_DOSSEMAPHORES   /* Semaphore values */
  24. #include <os2.h>
  25. #include <stdlib.h>
  26. #include <stdio.h>
  27. #include <time.h>
  28.  
  29. #define HF_STDERR 2
  30. UCHAR *ProcessName = "DEBUGGEE.EXE";
  31. FILE   *hTrap;
  32. struct debug_buffer
  33.  {
  34.    ULONG   Pid;        /* Debuggee Process ID */
  35.    ULONG   Tid;        /* Debuggee Thread ID */
  36.    LONG    Cmd;        /* Command or Notification */
  37.    LONG    Value;      /* Generic Data Value */
  38.    ULONG   Addr;       /* Debuggee Address */
  39.    ULONG   Buffer;     /* Debugger Buffer Address */
  40.    ULONG   Len;        /* Length of Range */
  41.    ULONG   Index;      /* Generic Identifier Index */
  42.    ULONG   MTE;        /* Module Handle */
  43.    ULONG   EAX;        /* Register Set */
  44.    ULONG   ECX;
  45.    ULONG   EDX;
  46.    ULONG   EBX;
  47.    ULONG   ESP;
  48.    ULONG   EBP;
  49.    ULONG   ESI;
  50.    ULONG   EDI;
  51.    ULONG   EFlags;
  52.    ULONG   EIP;
  53.    ULONG   CSLim;      /* Byte Granular Limits */
  54.    ULONG   CSBase;     /* Byte Granular Base */
  55.    UCHAR   CSAcc;      /* Access Bytes */
  56.    UCHAR   CSAtr;      /* Attribute Bytes */
  57.    USHORT  CS;
  58.    ULONG   DSLim;
  59.    ULONG   DSBase;
  60.    UCHAR   DSAcc;
  61.    UCHAR   DSAtr;
  62.    USHORT  DS;
  63.    ULONG   ESLim;
  64.    ULONG   ESBase;
  65.    UCHAR   ESAcc;
  66.    UCHAR   ESAtr;
  67.    USHORT  ES;
  68.    ULONG   FSLim;
  69.    ULONG   FSBase;
  70.    UCHAR   FSAcc;
  71.    UCHAR   FSAtr;
  72.    USHORT  FS;
  73.    ULONG   GSLim;
  74.    ULONG   GSBase;
  75.    UCHAR   GSAcc;
  76.    UCHAR   GSAtr;
  77.    USHORT  GS;
  78.    ULONG   SSLim;
  79.    ULONG   SSBase;
  80.    UCHAR   SSAcc;
  81.    UCHAR   SSAtr;
  82.    USHORT  SS;
  83. } DbgBuf;
  84. /*-------------------------------------*/
  85. APIRET APIENTRY DosQueryModFromEIP( HMODULE *phMod,
  86.                                     ULONG *pObjNum,
  87.                                     ULONG BuffLen,
  88.                                     PCHAR pBuff,
  89.                                     ULONG *pOffset,
  90.                                     ULONG Address );
  91. /*-------------------------------------*/
  92. #define DBG_O_OBJMTE       0x10000000L
  93. #define DBG_C_NumToAddr            13
  94. #define DBG_C_AddrToObject         28
  95. #define DBG_C_Connect              21
  96. #define DBG_L_386                   1
  97. RESULTCODES ReturnCodes;
  98. UCHAR   LoadError[40]; /*DosExecPGM buffer */
  99. UCHAR   Translate[17];
  100. void    GetObjects(struct debug_buffer * pDbgBuf,HMODULE hMte,PSZ pName);
  101. VOID    ListModules(VOID);
  102. HMODULE hMod;
  103. ULONG   ObjNum;
  104. ULONG   Offset;
  105. /*-------------------------------------*/
  106. CHAR    Buffer[CCHMAXPATH];
  107.  
  108. typedef ULONG     * _Seg16 PULONG16;
  109. APIRET16 APIENTRY16 DOS16SIZESEG( USHORT Seg , PULONG16 Size);
  110. typedef  APIRET16  (APIENTRY16  _PFN16)();
  111. /*-------------------------------------*/
  112. /*- DosQProcStatus interface ----------*/
  113. APIRET16 APIENTRY16 DOSQPROCSTATUS(  ULONG * _Seg16 pBuf, USHORT cbBuf);
  114. #define CONVERT(fp,QSsel) MAKEP((QSsel),OFFSETOF(fp))
  115. #pragma pack(1)
  116. /*  Global Data Section */
  117. typedef struct qsGrec_s {
  118.     ULONG     cThrds;  /* number of threads in use */
  119.     ULONG     Reserved1;
  120.     ULONG     Reserved2;
  121. }qsGrec_t;
  122. /* Thread Record structure *   Holds all per thread information. */
  123. typedef struct qsTrec_s {
  124.     ULONG     RecType;    /* Record Type */
  125.                           /* Thread rectype = 100 */
  126.     USHORT    tid;        /* thread ID */
  127.     USHORT    slot;       /* "unique" thread slot number */
  128.     ULONG     sleepid;    /* sleep id thread is sleeping on */
  129.     ULONG     priority;   /* thread priority */
  130.     ULONG     systime;    /* thread system time */
  131.     ULONG     usertime;   /* thread user time */
  132.     UCHAR     state;      /* thread state */
  133.     UCHAR     PADCHAR;
  134.     USHORT    PADSHORT;
  135. } qsTrec_t;
  136. /* Process and Thread Data Section */
  137. typedef struct qsPrec_s {
  138.     ULONG           RecType;    /* type of record being processed */
  139.                           /* process rectype = 1       */
  140.     qsTrec_t *      pThrdRec;  /* ptr to 1st thread rec for this prc*/
  141.     USHORT          pid;       /* process ID */
  142.     USHORT          ppid;      /* parent process ID */
  143.     ULONG           type;      /* process type */
  144.     ULONG           stat;      /* process status */
  145.     ULONG           sgid;      /* process screen group */
  146.     USHORT          hMte;      /* program module handle for process */
  147.     USHORT          cTCB;      /* # of TCBs in use in process */
  148.     ULONG           Reserved1;
  149.     void   *        Reserved2;
  150.     USHORT          c16Sem;     /*# of 16 bit system sems in use by proc*/
  151.     USHORT          cLib;       /* number of runtime linked libraries */
  152.     USHORT          cShrMem;    /* number of shared memory handles */
  153.     USHORT          Reserved3;
  154.     USHORT *        p16SemRec;   /*ptr to head of 16 bit sem inf for proc*/
  155.     USHORT *        pLibRec;     /*ptr to list of runtime lib in use by */
  156.                                   /*process*/
  157.     USHORT *        pShrMemRec;  /*ptr to list of shared mem handles in */
  158.                                   /*use by process*/
  159.     USHORT *        Reserved4;
  160. } qsPrec_t;
  161. /* 16 Bit System Semaphore Section */
  162. typedef struct qsS16Headrec_s {
  163.     ULONG     RecType;   /* semaphore rectype = 3 */
  164.     ULONG     Reserved1;  /* overlays NextRec of 1st qsS16rec_t */
  165.     ULONG     Reserved2;
  166.     ULONG     S16TblOff;  /* index of first semaphore,SEE PSTAT OUTPUT*/
  167.                           /* System Semaphore Information Section     */
  168. } qsS16Headrec_t;
  169. /*  16 bit System Semaphore Header Record Structure */
  170. typedef struct qsS16rec_s {
  171.     ULONG      NextRec;          /* offset to next record in buffer */
  172.     UINT       s_SysSemOwner ;   /* thread owning this semaphore    */
  173.     UCHAR      s_SysSemFlag ;    /* system semaphore flag bit field */
  174.     UCHAR      s_SysSemRefCnt ;  /* number of references to this    */
  175.                                  /*  system semaphore               */
  176.     UCHAR      s_SysSemProcCnt ; /*number of requests by sem owner  */
  177.     UCHAR      Reserved1;
  178.     ULONG      Reserved2;
  179.     UINT       Reserved3;
  180.     CHAR       SemName[1];       /* start of semaphore name string */
  181. } qsS16rec_t;
  182. /*  Executable Module Section */
  183. typedef struct qsLrec_s {
  184.     void        * pNextRec;    /* pointer to next record in buffer */
  185.     USHORT        hmte;         /* handle for this mte */
  186.     USHORT        Reserved1;    /* Reserved */
  187.     ULONG         ctImpMod;     /* # of imported modules in table */
  188.     ULONG         Reserved2;    /* Reserved */
  189. /*  qsLObjrec_t * Reserved3;       Reserved */
  190.     ULONG       * Reserved3;    /* Reserved */
  191.     UCHAR       * pName;        /* ptr to name string following stru*/
  192. } qsLrec_t;
  193. /*  Shared Memory Segment Section */
  194. typedef struct qsMrec_s {
  195.     struct qsMrec_s *MemNextRec;    /* offset to next record in buffer */
  196.     USHORT    hmem;          /* handle for shared memory */
  197.     USHORT    sel;           /* shared memory selector */
  198.     USHORT    refcnt;        /* reference count */
  199.     CHAR      Memname[1];    /* start of shared memory name string */
  200. } qsMrec_t;
  201. /*  Pointer Record Section */
  202. typedef struct qsPtrRec_s {
  203.     qsGrec_t       *  pGlobalRec;        /* ptr to the global data section */
  204.     qsPrec_t       *  pProcRec;          /* ptr to process record section  */
  205.     qsS16Headrec_t *  p16SemRec;         /* ptr to 16 bit sem section      */
  206.     void           *  Reserved;          /* a reserved area                */
  207.     qsMrec_t       *  pShrMemRec;        /* ptr to shared mem section      */
  208.     qsLrec_t       *  pLibRec;           /*ptr to exe module record section*/
  209. } qsPtrRec_t;
  210. /*-------------------------*/
  211. ULONG * pBuf,*pTemp;
  212. USHORT  Selector;
  213. qsPtrRec_t * pRec;
  214. qsLrec_t   * pLib;
  215. qsMrec_t   * pShrMemRec;        /* ptr to shared mem section      */
  216. qsPrec_t   * pProc;
  217. qsTrec_t   * pThread;
  218. ULONG      ListedThreads=0;
  219. APIRET16 APIENTRY16 DOS16ALLOCSEG(
  220.         USHORT          cbSize,          /* number of bytes requested                   */
  221.         USHORT  * _Seg16 pSel,           /* sector allocated (returned)                 */
  222.         USHORT fsAlloc);                 /* sharing attributes of the allocated segment */
  223. typedef struct
  224.   {
  225.     short int      ilen;     /* Instruction length */
  226.     long           rref;     /* Value of any IP relative storage reference */
  227.     unsigned short sel;      /* Selector of any CS:eIP storage reference.   */
  228.     long           poff;     /* eIP value of any CS:eIP storage reference. */
  229.     char           longoper; /* YES/NO value. Is instr in 32 bit operand mode? **/
  230.     char           longaddr; /* YES/NO value. Is instr in 32 bit address mode? **/
  231.     char           buf[40];  /* String holding disassembled instruction **/
  232.   } * _Seg16 RETURN_FROM_DISASM;
  233. RETURN_FROM_DISASM CDECL16 DISASM( CHAR * _Seg16 Source, USHORT IPvalue,USHORT segsize );
  234. RETURN_FROM_DISASM AsmLine;
  235. USHORT BigSeg;
  236. /*--                                 --*/
  237. /*-------------------------------------*/
  238.  
  239.  
  240. typedef  _PFN16 * _Seg16 PFN16;
  241. ULONG _cdecl _System myHandler (PEXCEPTIONREPORTRECORD       pERepRec,
  242.                         PEXCEPTIONREGISTRATIONRECORD pERegRec,
  243.                         PCONTEXTRECORD               pCtxRec,
  244.                         PVOID                        p)
  245. {
  246.   PCHAR   SegPtr;
  247.   PUSHORT StackPtr;
  248.   PUCHAR  cStackPtr;
  249.   ULONG Size,Flags;
  250.   APIRET rc;
  251.   APIRET semrc;
  252.   APIRET16 rc16;
  253.   PTIB   ptib;
  254.   PPIB   ppib;
  255.   USHORT Count;
  256.   ULONG  Nest;
  257.   UCHAR  TrapFile[20];
  258.   struct debug_buffer DbgBuf;
  259.  
  260.  
  261.   if ((pERepRec->ExceptionNum&XCPT_SEVERITY_CODE)==XCPT_FATAL_EXCEPTION)
  262.   {
  263.     if ((pERepRec->ExceptionNum!=XCPT_PROCESS_TERMINATE)&&
  264.         (pERepRec->ExceptionNum!=XCPT_UNWIND)&&
  265.         (pERepRec->ExceptionNum!=XCPT_SIGNAL)&&
  266.         (pERepRec->ExceptionNum!=XCPT_ASYNC_PROCESS_TERMINATE)) {
  267.         DosEnterMustComplete(&Nest);
  268.         rc=DosGetInfoBlocks(&ptib,&ppib);
  269.         if (rc==NO_ERROR) {
  270.            sprintf(TrapFile,"%d%d.TRP",
  271.                    ppib->pib_ulpid,ptib->tib_ptib2->tib2_ultid);
  272.         } else {
  273.            sprintf(TrapFile,"TRAP.TRP");
  274.         }
  275.         printf("Creating %s\n",TrapFile);
  276.         hTrap=fopen(TrapFile,"a");
  277.         if (hTrap==NULL) {
  278.            printf("hTrap NULL\n");
  279.            hTrap=stdout;
  280.         } /* endif */
  281.         fprintf(hTrap,"--------------------------\n");
  282.         fprintf(hTrap,"Exception %8.8lX Occurred\n",pERepRec->ExceptionNum);
  283.         fprintf(hTrap," at %s ",_strtime(Buffer));
  284.         fprintf(hTrap," %s\n",_strdate(Buffer));
  285.         if ( pERepRec->ExceptionNum     ==         XCPT_ACCESS_VIOLATION)
  286.         {
  287.            switch (pERepRec->ExceptionInfo[0]) {
  288.                 case XCPT_READ_ACCESS:
  289.                 case XCPT_WRITE_ACCESS:
  290.                    fprintf(hTrap,"Invalid linear address %8.8lX\n",pERepRec->ExceptionInfo[1]);
  291.                    break;
  292.                 case XCPT_SPACE_ACCESS:
  293.                    fprintf(hTrap,"Invalid Selector %8.8lX\n",pERepRec->ExceptionInfo[1]);
  294.                    break;
  295.                 case XCPT_LIMIT_ACCESS:
  296.                    fprintf(hTrap,"Limit access fault\n");
  297.                    break;
  298.                 case XCPT_UNKNOWN_ACCESS:
  299.                    fprintf(hTrap,"Unknown access fault\n");
  300.                    break;
  301.               break;
  302.            default:
  303.                    fprintf(hTrap,"Other Unknown access fault\n");
  304.            } /* endswitch */
  305.         } /* endif */
  306.         if ( (pCtxRec->ContextFlags) & CONTEXT_SEGMENTS ) {
  307.              fprintf(hTrap,"GS  : %4.4lX     ",pCtxRec->ctx_SegGs);
  308.              fprintf(hTrap,"FS  : %4.4lX     ",pCtxRec->ctx_SegFs);
  309.              fprintf(hTrap,"ES  : %4.4lX     ",pCtxRec->ctx_SegEs);
  310.              fprintf(hTrap,"DS  : %4.4lX     \n",pCtxRec->ctx_SegDs);
  311.         } /* endif */
  312.         if ( (pCtxRec->ContextFlags) & CONTEXT_INTEGER  ) {
  313.              fprintf(hTrap,"EDI : %8.8lX ",pCtxRec->ctx_RegEdi  );
  314.              fprintf(hTrap,"ESI : %8.8lX ",pCtxRec->ctx_RegEsi  );
  315.              fprintf(hTrap,"EAX : %8.8lX ",pCtxRec->ctx_RegEax  );
  316.              fprintf(hTrap,"EBX : %8.8lX\n",pCtxRec->ctx_RegEbx  );
  317.              fprintf(hTrap,"ECX : %8.8lX ",pCtxRec->ctx_RegEcx  );
  318.              fprintf(hTrap,"EDX : %8.8lX\n",pCtxRec->ctx_RegEdx  );
  319.         } /* endif */
  320.         if ( (pCtxRec->ContextFlags) & CONTEXT_CONTROL  ) {
  321.              void * _Seg16 Ptr16;
  322.              fprintf(hTrap,"EBP : %8.8lX ",pCtxRec->ctx_RegEbp  );
  323.              fprintf(hTrap,"EIP : %8.8lX ",pCtxRec->ctx_RegEip  );
  324.              fprintf(hTrap,"EFLG: %8.8lX ",pCtxRec->ctx_EFlags  );
  325.              fprintf(hTrap,"ESP : %8.8lX\n",pCtxRec->ctx_RegEsp  );
  326.              fprintf(hTrap,"CS  : %4.4lX     ",pCtxRec->ctx_SegCs   );
  327.              fprintf(hTrap,"SS  : %4.4lX\n",pCtxRec->ctx_SegSs   );
  328.              SegPtr =MAKEP((SHORT)pCtxRec->ctx_SegCs,0);
  329.              rc16 =DOS16SIZESEG( (USHORT)pCtxRec->ctx_SegCs , &Size);
  330.              if (rc16==NO_ERROR) {
  331.                 printf("CSLIM: %8.8lX ",Size);
  332.                 fprintf(hTrap,"CSLIM: %8.8lX ",Size);
  333.              } /* endif */
  334.              rc16 =DOS16SIZESEG( (USHORT)pCtxRec->ctx_SegSs , &Size);
  335.              if (rc16==NO_ERROR) {
  336.                 printf("SSLIM: %8.8lX \n",Size);
  337.                 fprintf(hTrap,"SSLIM: %8.8lX \n",Size);
  338.              } /* endif */
  339.              BigSeg=((pCtxRec->ctx_RegEip)>0x00010000);
  340.              if (BigSeg) {
  341.                  AsmLine= DISASM( (PVOID) pCtxRec->ctx_RegEip,
  342.                                   (USHORT)pCtxRec->ctx_RegEip, BigSeg );
  343.                  fprintf(hTrap,"CS:EIP : %4.4X:%8.8X   %s\n",
  344.                          pCtxRec->ctx_SegCs,
  345.                          pCtxRec->ctx_RegEip,AsmLine->buf);
  346.              } else {
  347.                  AsmLine= DISASM(MAKE16P(pCtxRec->ctx_SegCs,
  348.                                          pCtxRec->ctx_RegEip),
  349.                                  (USHORT)pCtxRec->ctx_RegEip, BigSeg );
  350.                  fprintf(hTrap,"CS:IP : %4.4X:%4.4X    %s\n",
  351.                          pCtxRec->ctx_SegCs,
  352.                          pCtxRec->ctx_RegEip,AsmLine->buf);
  353.              } /* endif */
  354.              rc=DosGetInfoBlocks(&ptib,&ppib);
  355.              if (rc==NO_ERROR) {
  356.                 static CHAR Format[10];
  357.                 static CHAR Name[CCHMAXPATH];
  358.                 fprintf(hTrap,"Thread slot %lu , Id %lu , priority %p\n",
  359.                         ptib->tib_ordinal,
  360.                         ptib->tib_ptib2->tib2_ultid ,
  361.                         ptib->tib_ptib2->tib2_ulpri );
  362.                 Ptr16=ptib->tib_pstack;
  363.                 sprintf(Format,"%8.8lX",Ptr16);
  364.                 fprintf(hTrap,"Stack Bottom : %8.8lX (%4.4s:%4.4s) ;", ptib->tib_pstack ,Format,Format+4);
  365.                 Ptr16=ptib->tib_pstacklimit;
  366.                 sprintf(Format,"%8.8lX",Ptr16);
  367.                 fprintf(hTrap,"Stack Top    : %8.8lX (%4.4s:%4.4s) \n",ptib->tib_pstacklimit,Format,Format+4);
  368.                 fprintf(hTrap,"Process Id : %lu ", ppib->pib_ulpid);
  369.                 rc=DosQueryModuleName(ppib->pib_hmte,CCHMAXPATH, Name);
  370.                 if (rc==NO_ERROR) {
  371.                    fprintf(hTrap,".EXE name : %s\n",Name);
  372.                 } else {
  373.                    fprintf(hTrap,".EXE name : ??????\n");
  374.                 } /* endif */
  375.                 ListModules();
  376.                 Count=0;
  377.                 Translate[0]=0x00;
  378.                 fprintf(hTrap,"\n/*----- Stack Bottom ---*/\n");
  379.                 for (StackPtr=(PUSHORT)ptib->tib_pstack;
  380.                      StackPtr<(PUSHORT)ptib->tib_pstacklimit;
  381.                      StackPtr++) {
  382.                      if (Count==0) {
  383.                         fprintf(hTrap,"  %s\n %8.8X :",Translate,StackPtr);
  384.                         Translate[0]=0x00;
  385.                      } /* endif */
  386.                      fprintf(hTrap,"%4.4hX ",*StackPtr);
  387.                      cStackPtr=(PUCHAR)StackPtr;
  388.                      if ((isprint(*cStackPtr)) &&
  389.                          (*cStackPtr>=0x20)  ) {
  390.                         Translate[2*Count]=*cStackPtr;
  391.                      } else {
  392.                         Translate[2*Count]='.';
  393.                      } /* endif */
  394.                      cStackPtr++;
  395.                      if ((isprint(*cStackPtr) )&&
  396.                          ( *cStackPtr >=0x20 )  ) {
  397.                         Translate[2*Count+1]=*cStackPtr;
  398.                      } else {
  399.                         Translate[2*Count+1]='.';
  400.                      } /* endif */
  401.                      Count++;
  402.                      Translate[2*Count]=0x00;
  403.                      if (Count==8) {
  404.                          Count=0;
  405.                      } /* endif */
  406.                 } /* endfor */
  407.                 fprintf(hTrap,"%s\n/*----- Stack Top -----*/\n",Translate);
  408.  
  409.              } /* endif */
  410.         } /* endif */
  411.         if (hTrap!=stdout) {
  412.            fclose(hTrap);
  413.         }
  414.         DosExitMustComplete(&Nest);
  415.         rc=DosUnsetExceptionHandler(pERegRec);
  416.      } /* endif */
  417.   } else {
  418.      printf("Other non fatal exception %8.8lx ",pERepRec->ExceptionNum);
  419.      printf("At address                %8.8lx\n",pERepRec->ExceptionAddress);
  420.   } /* endif */
  421.   return (XCPT_CONTINUE_SEARCH);
  422.  
  423. }
  424. APIRET16 APIENTRY16 SETEXCEPT(PEXCEPTIONREGISTRATIONRECORD _Seg16 pxcpthand)
  425.  {
  426.    APIRET rc;
  427.  
  428.    rc=DosError(FERR_DISABLEEXCEPTION | FERR_DISABLEHARDERR );
  429.    printf("Set error rc %ld\n",rc);
  430.    pxcpthand->prev_structure=0;
  431.    pxcpthand->ExceptionHandler=&myHandler;
  432.    rc=DosSetExceptionHandler(pxcpthand);
  433.    printf("Set except rc %ld\n",rc);
  434. }
  435. VOID ListModules() {
  436.   APIRET   rc;
  437.   APIRET16 rc16;
  438.   /**----------------------------------***/
  439.   rc16=DOS16ALLOCSEG( 0xFFFF , &Selector , 0);
  440.   if (rc16==0) {
  441.      pBuf=MAKEP(Selector,0);
  442.      rc16=DOSQPROCSTATUS(pBuf, 0xFFFF );
  443.      if (rc16==0) {
  444.         rc = DosExecPgm(LoadError,          /* Object name buffer */
  445.                         sizeof(LoadError),  /* Length of object name buffer */
  446.                         EXEC_TRACE,         /* Asynchronous/Trace flags */
  447.                         "Debug",            /* Argument string */
  448.                         NULL,               /* Environment string */
  449.                         &ReturnCodes,       /* Termination codes */
  450.                         ProcessName);           /* Program file name */
  451.         if (rc != NO_ERROR) {
  452.             fprintf(hTrap,"rc = %d Process ID %d  Return Code %d \n",
  453.                   rc,
  454.                   ReturnCodes.codeTerminate,
  455.                   ReturnCodes.codeResult);
  456.             return;
  457.         }
  458.        fprintf(hTrap,"Connecting  to PID %d\n",ReturnCodes.codeTerminate);
  459.        DbgBuf.Cmd = DBG_C_Connect; /* Indicate that a Connect is requested */
  460.        DbgBuf.Pid = ReturnCodes.codeTerminate;
  461.        DbgBuf.Tid = 0;
  462.        DbgBuf.Value = DBG_L_386;
  463.        rc = DosDebug(&DbgBuf);
  464.        if (rc != 0) {
  465.            fprintf(hTrap,"DosDebug error: return code = %ld Note %8.8lX\n", rc,DbgBuf.Cmd);
  466.            fprintf(hTrap,"Value          = %8.8lX %ld\n",DbgBuf.Value,DbgBuf.Value);
  467.        }
  468.        fprintf(hTrap,"Connected to PID %d\n",ReturnCodes.codeTerminate);
  469.        /*****************************/
  470.        pRec=(qsPtrRec_t *) pBuf;
  471.        pLib=pRec->pLibRec;
  472.        while (pLib) {
  473.            GetObjects(&DbgBuf,pLib->hmte,pLib->pName);
  474.            pLib =pLib->pNextRec;
  475.        } /* endwhile */
  476.      } else {
  477.        fprintf(hTrap,"DosQProcStatus Failed %hd\n",rc16);
  478.      } /* endif */
  479.   } else {
  480.      fprintf(hTrap,"DosAllocSeg Failed %hd\n",rc16);
  481.   } /* endif */
  482. }
  483. VOID  GetObjects(struct debug_buffer * pDbgBuf,HMODULE hMte,PSZ pName) {
  484.     APIRET rc;
  485.     int  object;
  486.     pDbgBuf->MTE  = (ULONG) hMte;
  487.     rc=0;
  488.     fprintf(hTrap,"DLL %s Handle %d\n",pName,hMte);
  489.     fprintf(hTrap,"Object Number    Address    Length     Flags      Type\n");
  490.     for (object=1;object<256;object++ ) {
  491.         pDbgBuf->Cmd   = DBG_C_NumToAddr;
  492.         pDbgBuf->Pid   = ReturnCodes.codeTerminate;
  493.         pDbgBuf->Value = object; /* Get nth object address in module with given MTE */
  494.         pDbgBuf->Buffer= 0;
  495.         pDbgBuf->Len   = 0;
  496.         rc = DosDebug(pDbgBuf);
  497.         if ((rc == NO_ERROR)&&
  498.             (pDbgBuf->Cmd==NO_ERROR)) {
  499.             ULONG Size;
  500.             ULONG Flags;
  501.             APIRET16 rc16;
  502.             pDbgBuf->Len   = 0;
  503.             pDbgBuf->Value = 0;
  504.             if (pDbgBuf->Addr!=0) {
  505.                 pDbgBuf->Cmd   = DBG_C_AddrToObject;
  506.                 pDbgBuf->Pid   = ReturnCodes.codeTerminate;
  507.                 rc = DosDebug(pDbgBuf);
  508.                 if ((rc != NO_ERROR) ||
  509.                     (pDbgBuf->Cmd|=NO_ERROR)) {
  510.                    pDbgBuf->Len   = 0;
  511.                    pDbgBuf->Value = 0;
  512.                 }
  513.             }
  514.             fprintf(hTrap,"      % 6.6d    %8.8lX   %8.8lX   %8.8lX ",object,
  515.                       pDbgBuf->Addr, pDbgBuf->Len, pDbgBuf->Value);
  516.             if (pDbgBuf->Addr!=0) {
  517.                 rc16 =DOS16SIZESEG( SELECTOROF(pDbgBuf->Addr), &Size);
  518.                 if (rc16==0) {
  519.                    fprintf(hTrap," - 16:16  Selector %4.4hX\n",SELECTOROF((PVOID)pDbgBuf->Addr));
  520.                 } else {
  521.                    fprintf(hTrap," - 32 Bits\n");
  522.                 } /* endif */
  523.             } else {
  524.                fprintf(hTrap," - ?\n");
  525.             } /* endif */
  526.         } else {
  527. //         printf("DosDebug return code = %ld Notification %8.8lX\n", rc,pDbgBuf->Cmd);
  528. //         printf("Value                = %8.8lX %ld\n",pDbgBuf->Value,pDbgBuf->Value);
  529.            break;
  530.         }
  531.     } /* endfor */
  532.     fprintf(hTrap,"\n");
  533. }
  534.