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 >
Wrap
Text File
|
1993-10-19
|
23KB
|
534 lines
/**********************************************************************/
/* IBM DAPTOOLS UseOnly */
/**********************************************************************/
/* */
/* EXCEPTQ */
/* */
/* DLL containing an exception handler for gathering trap information */
/* This DLL dumps all important debugging Data and is accessible */
/* from both 16 bit and 32 bits programs */
/**********************************************************************/
/* Version: 2.2 | Marc Fiammante */
/* | La Gaude FRANCE */
/**********************************************************************/
/* */
/**********************************************************************/
/* History: */
/* -------- */
/* */
/* created: Marc Fiammante December 1992 */
/**********************************************************************/
#define INCL_BASE
#define INCL_DOSEXCEPTIONS
#define INCL_DOSSEMAPHORES /* Semaphore values */
#include <os2.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#define HF_STDERR 2
UCHAR *ProcessName = "DEBUGGEE.EXE";
FILE *hTrap;
struct debug_buffer
{
ULONG Pid; /* Debuggee Process ID */
ULONG Tid; /* Debuggee Thread ID */
LONG Cmd; /* Command or Notification */
LONG Value; /* Generic Data Value */
ULONG Addr; /* Debuggee Address */
ULONG Buffer; /* Debugger Buffer Address */
ULONG Len; /* Length of Range */
ULONG Index; /* Generic Identifier Index */
ULONG MTE; /* Module Handle */
ULONG EAX; /* Register Set */
ULONG ECX;
ULONG EDX;
ULONG EBX;
ULONG ESP;
ULONG EBP;
ULONG ESI;
ULONG EDI;
ULONG EFlags;
ULONG EIP;
ULONG CSLim; /* Byte Granular Limits */
ULONG CSBase; /* Byte Granular Base */
UCHAR CSAcc; /* Access Bytes */
UCHAR CSAtr; /* Attribute Bytes */
USHORT CS;
ULONG DSLim;
ULONG DSBase;
UCHAR DSAcc;
UCHAR DSAtr;
USHORT DS;
ULONG ESLim;
ULONG ESBase;
UCHAR ESAcc;
UCHAR ESAtr;
USHORT ES;
ULONG FSLim;
ULONG FSBase;
UCHAR FSAcc;
UCHAR FSAtr;
USHORT FS;
ULONG GSLim;
ULONG GSBase;
UCHAR GSAcc;
UCHAR GSAtr;
USHORT GS;
ULONG SSLim;
ULONG SSBase;
UCHAR SSAcc;
UCHAR SSAtr;
USHORT SS;
} DbgBuf;
/*-------------------------------------*/
APIRET APIENTRY DosQueryModFromEIP( HMODULE *phMod,
ULONG *pObjNum,
ULONG BuffLen,
PCHAR pBuff,
ULONG *pOffset,
ULONG Address );
/*-------------------------------------*/
#define DBG_O_OBJMTE 0x10000000L
#define DBG_C_NumToAddr 13
#define DBG_C_AddrToObject 28
#define DBG_C_Connect 21
#define DBG_L_386 1
RESULTCODES ReturnCodes;
UCHAR LoadError[40]; /*DosExecPGM buffer */
UCHAR Translate[17];
void GetObjects(struct debug_buffer * pDbgBuf,HMODULE hMte,PSZ pName);
VOID ListModules(VOID);
HMODULE hMod;
ULONG ObjNum;
ULONG Offset;
/*-------------------------------------*/
CHAR Buffer[CCHMAXPATH];
typedef ULONG * _Seg16 PULONG16;
APIRET16 APIENTRY16 DOS16SIZESEG( USHORT Seg , PULONG16 Size);
typedef APIRET16 (APIENTRY16 _PFN16)();
/*-------------------------------------*/
/*- DosQProcStatus interface ----------*/
APIRET16 APIENTRY16 DOSQPROCSTATUS( ULONG * _Seg16 pBuf, USHORT cbBuf);
#define CONVERT(fp,QSsel) MAKEP((QSsel),OFFSETOF(fp))
#pragma pack(1)
/* Global Data Section */
typedef struct qsGrec_s {
ULONG cThrds; /* number of threads in use */
ULONG Reserved1;
ULONG Reserved2;
}qsGrec_t;
/* Thread Record structure * Holds all per thread information. */
typedef struct qsTrec_s {
ULONG RecType; /* Record Type */
/* Thread rectype = 100 */
USHORT tid; /* thread ID */
USHORT slot; /* "unique" thread slot number */
ULONG sleepid; /* sleep id thread is sleeping on */
ULONG priority; /* thread priority */
ULONG systime; /* thread system time */
ULONG usertime; /* thread user time */
UCHAR state; /* thread state */
UCHAR PADCHAR;
USHORT PADSHORT;
} qsTrec_t;
/* Process and Thread Data Section */
typedef struct qsPrec_s {
ULONG RecType; /* type of record being processed */
/* process rectype = 1 */
qsTrec_t * pThrdRec; /* ptr to 1st thread rec for this prc*/
USHORT pid; /* process ID */
USHORT ppid; /* parent process ID */
ULONG type; /* process type */
ULONG stat; /* process status */
ULONG sgid; /* process screen group */
USHORT hMte; /* program module handle for process */
USHORT cTCB; /* # of TCBs in use in process */
ULONG Reserved1;
void * Reserved2;
USHORT c16Sem; /*# of 16 bit system sems in use by proc*/
USHORT cLib; /* number of runtime linked libraries */
USHORT cShrMem; /* number of shared memory handles */
USHORT Reserved3;
USHORT * p16SemRec; /*ptr to head of 16 bit sem inf for proc*/
USHORT * pLibRec; /*ptr to list of runtime lib in use by */
/*process*/
USHORT * pShrMemRec; /*ptr to list of shared mem handles in */
/*use by process*/
USHORT * Reserved4;
} qsPrec_t;
/* 16 Bit System Semaphore Section */
typedef struct qsS16Headrec_s {
ULONG RecType; /* semaphore rectype = 3 */
ULONG Reserved1; /* overlays NextRec of 1st qsS16rec_t */
ULONG Reserved2;
ULONG S16TblOff; /* index of first semaphore,SEE PSTAT OUTPUT*/
/* System Semaphore Information Section */
} qsS16Headrec_t;
/* 16 bit System Semaphore Header Record Structure */
typedef struct qsS16rec_s {
ULONG NextRec; /* offset to next record in buffer */
UINT s_SysSemOwner ; /* thread owning this semaphore */
UCHAR s_SysSemFlag ; /* system semaphore flag bit field */
UCHAR s_SysSemRefCnt ; /* number of references to this */
/* system semaphore */
UCHAR s_SysSemProcCnt ; /*number of requests by sem owner */
UCHAR Reserved1;
ULONG Reserved2;
UINT Reserved3;
CHAR SemName[1]; /* start of semaphore name string */
} qsS16rec_t;
/* Executable Module Section */
typedef struct qsLrec_s {
void * pNextRec; /* pointer to next record in buffer */
USHORT hmte; /* handle for this mte */
USHORT Reserved1; /* Reserved */
ULONG ctImpMod; /* # of imported modules in table */
ULONG Reserved2; /* Reserved */
/* qsLObjrec_t * Reserved3; Reserved */
ULONG * Reserved3; /* Reserved */
UCHAR * pName; /* ptr to name string following stru*/
} qsLrec_t;
/* Shared Memory Segment Section */
typedef struct qsMrec_s {
struct qsMrec_s *MemNextRec; /* offset to next record in buffer */
USHORT hmem; /* handle for shared memory */
USHORT sel; /* shared memory selector */
USHORT refcnt; /* reference count */
CHAR Memname[1]; /* start of shared memory name string */
} qsMrec_t;
/* Pointer Record Section */
typedef struct qsPtrRec_s {
qsGrec_t * pGlobalRec; /* ptr to the global data section */
qsPrec_t * pProcRec; /* ptr to process record section */
qsS16Headrec_t * p16SemRec; /* ptr to 16 bit sem section */
void * Reserved; /* a reserved area */
qsMrec_t * pShrMemRec; /* ptr to shared mem section */
qsLrec_t * pLibRec; /*ptr to exe module record section*/
} qsPtrRec_t;
/*-------------------------*/
ULONG * pBuf,*pTemp;
USHORT Selector;
qsPtrRec_t * pRec;
qsLrec_t * pLib;
qsMrec_t * pShrMemRec; /* ptr to shared mem section */
qsPrec_t * pProc;
qsTrec_t * pThread;
ULONG ListedThreads=0;
APIRET16 APIENTRY16 DOS16ALLOCSEG(
USHORT cbSize, /* number of bytes requested */
USHORT * _Seg16 pSel, /* sector allocated (returned) */
USHORT fsAlloc); /* sharing attributes of the allocated segment */
typedef struct
{
short int ilen; /* Instruction length */
long rref; /* Value of any IP relative storage reference */
unsigned short sel; /* Selector of any CS:eIP storage reference. */
long poff; /* eIP value of any CS:eIP storage reference. */
char longoper; /* YES/NO value. Is instr in 32 bit operand mode? **/
char longaddr; /* YES/NO value. Is instr in 32 bit address mode? **/
char buf[40]; /* String holding disassembled instruction **/
} * _Seg16 RETURN_FROM_DISASM;
RETURN_FROM_DISASM CDECL16 DISASM( CHAR * _Seg16 Source, USHORT IPvalue,USHORT segsize );
RETURN_FROM_DISASM AsmLine;
USHORT BigSeg;
/*-- --*/
/*-------------------------------------*/
typedef _PFN16 * _Seg16 PFN16;
ULONG _cdecl _System myHandler (PEXCEPTIONREPORTRECORD pERepRec,
PEXCEPTIONREGISTRATIONRECORD pERegRec,
PCONTEXTRECORD pCtxRec,
PVOID p)
{
PCHAR SegPtr;
PUSHORT StackPtr;
PUCHAR cStackPtr;
ULONG Size,Flags;
APIRET rc;
APIRET semrc;
APIRET16 rc16;
PTIB ptib;
PPIB ppib;
USHORT Count;
ULONG Nest;
UCHAR TrapFile[20];
struct debug_buffer DbgBuf;
if ((pERepRec->ExceptionNum&XCPT_SEVERITY_CODE)==XCPT_FATAL_EXCEPTION)
{
if ((pERepRec->ExceptionNum!=XCPT_PROCESS_TERMINATE)&&
(pERepRec->ExceptionNum!=XCPT_UNWIND)&&
(pERepRec->ExceptionNum!=XCPT_SIGNAL)&&
(pERepRec->ExceptionNum!=XCPT_ASYNC_PROCESS_TERMINATE)) {
DosEnterMustComplete(&Nest);
rc=DosGetInfoBlocks(&ptib,&ppib);
if (rc==NO_ERROR) {
sprintf(TrapFile,"%d%d.TRP",
ppib->pib_ulpid,ptib->tib_ptib2->tib2_ultid);
} else {
sprintf(TrapFile,"TRAP.TRP");
}
printf("Creating %s\n",TrapFile);
hTrap=fopen(TrapFile,"a");
if (hTrap==NULL) {
printf("hTrap NULL\n");
hTrap=stdout;
} /* endif */
fprintf(hTrap,"--------------------------\n");
fprintf(hTrap,"Exception %8.8lX Occurred\n",pERepRec->ExceptionNum);
fprintf(hTrap," at %s ",_strtime(Buffer));
fprintf(hTrap," %s\n",_strdate(Buffer));
if ( pERepRec->ExceptionNum == XCPT_ACCESS_VIOLATION)
{
switch (pERepRec->ExceptionInfo[0]) {
case XCPT_READ_ACCESS:
case XCPT_WRITE_ACCESS:
fprintf(hTrap,"Invalid linear address %8.8lX\n",pERepRec->ExceptionInfo[1]);
break;
case XCPT_SPACE_ACCESS:
fprintf(hTrap,"Invalid Selector %8.8lX\n",pERepRec->ExceptionInfo[1]);
break;
case XCPT_LIMIT_ACCESS:
fprintf(hTrap,"Limit access fault\n");
break;
case XCPT_UNKNOWN_ACCESS:
fprintf(hTrap,"Unknown access fault\n");
break;
break;
default:
fprintf(hTrap,"Other Unknown access fault\n");
} /* endswitch */
} /* endif */
if ( (pCtxRec->ContextFlags) & CONTEXT_SEGMENTS ) {
fprintf(hTrap,"GS : %4.4lX ",pCtxRec->ctx_SegGs);
fprintf(hTrap,"FS : %4.4lX ",pCtxRec->ctx_SegFs);
fprintf(hTrap,"ES : %4.4lX ",pCtxRec->ctx_SegEs);
fprintf(hTrap,"DS : %4.4lX \n",pCtxRec->ctx_SegDs);
} /* endif */
if ( (pCtxRec->ContextFlags) & CONTEXT_INTEGER ) {
fprintf(hTrap,"EDI : %8.8lX ",pCtxRec->ctx_RegEdi );
fprintf(hTrap,"ESI : %8.8lX ",pCtxRec->ctx_RegEsi );
fprintf(hTrap,"EAX : %8.8lX ",pCtxRec->ctx_RegEax );
fprintf(hTrap,"EBX : %8.8lX\n",pCtxRec->ctx_RegEbx );
fprintf(hTrap,"ECX : %8.8lX ",pCtxRec->ctx_RegEcx );
fprintf(hTrap,"EDX : %8.8lX\n",pCtxRec->ctx_RegEdx );
} /* endif */
if ( (pCtxRec->ContextFlags) & CONTEXT_CONTROL ) {
void * _Seg16 Ptr16;
fprintf(hTrap,"EBP : %8.8lX ",pCtxRec->ctx_RegEbp );
fprintf(hTrap,"EIP : %8.8lX ",pCtxRec->ctx_RegEip );
fprintf(hTrap,"EFLG: %8.8lX ",pCtxRec->ctx_EFlags );
fprintf(hTrap,"ESP : %8.8lX\n",pCtxRec->ctx_RegEsp );
fprintf(hTrap,"CS : %4.4lX ",pCtxRec->ctx_SegCs );
fprintf(hTrap,"SS : %4.4lX\n",pCtxRec->ctx_SegSs );
SegPtr =MAKEP((SHORT)pCtxRec->ctx_SegCs,0);
rc16 =DOS16SIZESEG( (USHORT)pCtxRec->ctx_SegCs , &Size);
if (rc16==NO_ERROR) {
printf("CSLIM: %8.8lX ",Size);
fprintf(hTrap,"CSLIM: %8.8lX ",Size);
} /* endif */
rc16 =DOS16SIZESEG( (USHORT)pCtxRec->ctx_SegSs , &Size);
if (rc16==NO_ERROR) {
printf("SSLIM: %8.8lX \n",Size);
fprintf(hTrap,"SSLIM: %8.8lX \n",Size);
} /* endif */
BigSeg=((pCtxRec->ctx_RegEip)>0x00010000);
if (BigSeg) {
AsmLine= DISASM( (PVOID) pCtxRec->ctx_RegEip,
(USHORT)pCtxRec->ctx_RegEip, BigSeg );
fprintf(hTrap,"CS:EIP : %4.4X:%8.8X %s\n",
pCtxRec->ctx_SegCs,
pCtxRec->ctx_RegEip,AsmLine->buf);
} else {
AsmLine= DISASM(MAKE16P(pCtxRec->ctx_SegCs,
pCtxRec->ctx_RegEip),
(USHORT)pCtxRec->ctx_RegEip, BigSeg );
fprintf(hTrap,"CS:IP : %4.4X:%4.4X %s\n",
pCtxRec->ctx_SegCs,
pCtxRec->ctx_RegEip,AsmLine->buf);
} /* endif */
rc=DosGetInfoBlocks(&ptib,&ppib);
if (rc==NO_ERROR) {
static CHAR Format[10];
static CHAR Name[CCHMAXPATH];
fprintf(hTrap,"Thread slot %lu , Id %lu , priority %p\n",
ptib->tib_ordinal,
ptib->tib_ptib2->tib2_ultid ,
ptib->tib_ptib2->tib2_ulpri );
Ptr16=ptib->tib_pstack;
sprintf(Format,"%8.8lX",Ptr16);
fprintf(hTrap,"Stack Bottom : %8.8lX (%4.4s:%4.4s) ;", ptib->tib_pstack ,Format,Format+4);
Ptr16=ptib->tib_pstacklimit;
sprintf(Format,"%8.8lX",Ptr16);
fprintf(hTrap,"Stack Top : %8.8lX (%4.4s:%4.4s) \n",ptib->tib_pstacklimit,Format,Format+4);
fprintf(hTrap,"Process Id : %lu ", ppib->pib_ulpid);
rc=DosQueryModuleName(ppib->pib_hmte,CCHMAXPATH, Name);
if (rc==NO_ERROR) {
fprintf(hTrap,".EXE name : %s\n",Name);
} else {
fprintf(hTrap,".EXE name : ??????\n");
} /* endif */
ListModules();
Count=0;
Translate[0]=0x00;
fprintf(hTrap,"\n/*----- Stack Bottom ---*/\n");
for (StackPtr=(PUSHORT)ptib->tib_pstack;
StackPtr<(PUSHORT)ptib->tib_pstacklimit;
StackPtr++) {
if (Count==0) {
fprintf(hTrap," %s\n %8.8X :",Translate,StackPtr);
Translate[0]=0x00;
} /* endif */
fprintf(hTrap,"%4.4hX ",*StackPtr);
cStackPtr=(PUCHAR)StackPtr;
if ((isprint(*cStackPtr)) &&
(*cStackPtr>=0x20) ) {
Translate[2*Count]=*cStackPtr;
} else {
Translate[2*Count]='.';
} /* endif */
cStackPtr++;
if ((isprint(*cStackPtr) )&&
( *cStackPtr >=0x20 ) ) {
Translate[2*Count+1]=*cStackPtr;
} else {
Translate[2*Count+1]='.';
} /* endif */
Count++;
Translate[2*Count]=0x00;
if (Count==8) {
Count=0;
} /* endif */
} /* endfor */
fprintf(hTrap,"%s\n/*----- Stack Top -----*/\n",Translate);
} /* endif */
} /* endif */
if (hTrap!=stdout) {
fclose(hTrap);
}
DosExitMustComplete(&Nest);
rc=DosUnsetExceptionHandler(pERegRec);
} /* endif */
} else {
printf("Other non fatal exception %8.8lx ",pERepRec->ExceptionNum);
printf("At address %8.8lx\n",pERepRec->ExceptionAddress);
} /* endif */
return (XCPT_CONTINUE_SEARCH);
}
APIRET16 APIENTRY16 SETEXCEPT(PEXCEPTIONREGISTRATIONRECORD _Seg16 pxcpthand)
{
APIRET rc;
rc=DosError(FERR_DISABLEEXCEPTION | FERR_DISABLEHARDERR );
printf("Set error rc %ld\n",rc);
pxcpthand->prev_structure=0;
pxcpthand->ExceptionHandler=&myHandler;
rc=DosSetExceptionHandler(pxcpthand);
printf("Set except rc %ld\n",rc);
}
VOID ListModules() {
APIRET rc;
APIRET16 rc16;
/**----------------------------------***/
rc16=DOS16ALLOCSEG( 0xFFFF , &Selector , 0);
if (rc16==0) {
pBuf=MAKEP(Selector,0);
rc16=DOSQPROCSTATUS(pBuf, 0xFFFF );
if (rc16==0) {
rc = DosExecPgm(LoadError, /* Object name buffer */
sizeof(LoadError), /* Length of object name buffer */
EXEC_TRACE, /* Asynchronous/Trace flags */
"Debug", /* Argument string */
NULL, /* Environment string */
&ReturnCodes, /* Termination codes */
ProcessName); /* Program file name */
if (rc != NO_ERROR) {
fprintf(hTrap,"rc = %d Process ID %d Return Code %d \n",
rc,
ReturnCodes.codeTerminate,
ReturnCodes.codeResult);
return;
}
fprintf(hTrap,"Connecting to PID %d\n",ReturnCodes.codeTerminate);
DbgBuf.Cmd = DBG_C_Connect; /* Indicate that a Connect is requested */
DbgBuf.Pid = ReturnCodes.codeTerminate;
DbgBuf.Tid = 0;
DbgBuf.Value = DBG_L_386;
rc = DosDebug(&DbgBuf);
if (rc != 0) {
fprintf(hTrap,"DosDebug error: return code = %ld Note %8.8lX\n", rc,DbgBuf.Cmd);
fprintf(hTrap,"Value = %8.8lX %ld\n",DbgBuf.Value,DbgBuf.Value);
}
fprintf(hTrap,"Connected to PID %d\n",ReturnCodes.codeTerminate);
/*****************************/
pRec=(qsPtrRec_t *) pBuf;
pLib=pRec->pLibRec;
while (pLib) {
GetObjects(&DbgBuf,pLib->hmte,pLib->pName);
pLib =pLib->pNextRec;
} /* endwhile */
} else {
fprintf(hTrap,"DosQProcStatus Failed %hd\n",rc16);
} /* endif */
} else {
fprintf(hTrap,"DosAllocSeg Failed %hd\n",rc16);
} /* endif */
}
VOID GetObjects(struct debug_buffer * pDbgBuf,HMODULE hMte,PSZ pName) {
APIRET rc;
int object;
pDbgBuf->MTE = (ULONG) hMte;
rc=0;
fprintf(hTrap,"DLL %s Handle %d\n",pName,hMte);
fprintf(hTrap,"Object Number Address Length Flags Type\n");
for (object=1;object<256;object++ ) {
pDbgBuf->Cmd = DBG_C_NumToAddr;
pDbgBuf->Pid = ReturnCodes.codeTerminate;
pDbgBuf->Value = object; /* Get nth object address in module with given MTE */
pDbgBuf->Buffer= 0;
pDbgBuf->Len = 0;
rc = DosDebug(pDbgBuf);
if ((rc == NO_ERROR)&&
(pDbgBuf->Cmd==NO_ERROR)) {
ULONG Size;
ULONG Flags;
APIRET16 rc16;
pDbgBuf->Len = 0;
pDbgBuf->Value = 0;
if (pDbgBuf->Addr!=0) {
pDbgBuf->Cmd = DBG_C_AddrToObject;
pDbgBuf->Pid = ReturnCodes.codeTerminate;
rc = DosDebug(pDbgBuf);
if ((rc != NO_ERROR) ||
(pDbgBuf->Cmd|=NO_ERROR)) {
pDbgBuf->Len = 0;
pDbgBuf->Value = 0;
}
}
fprintf(hTrap," % 6.6d %8.8lX %8.8lX %8.8lX ",object,
pDbgBuf->Addr, pDbgBuf->Len, pDbgBuf->Value);
if (pDbgBuf->Addr!=0) {
rc16 =DOS16SIZESEG( SELECTOROF(pDbgBuf->Addr), &Size);
if (rc16==0) {
fprintf(hTrap," - 16:16 Selector %4.4hX\n",SELECTOROF((PVOID)pDbgBuf->Addr));
} else {
fprintf(hTrap," - 32 Bits\n");
} /* endif */
} else {
fprintf(hTrap," - ?\n");
} /* endif */
} else {
// printf("DosDebug return code = %ld Notification %8.8lX\n", rc,pDbgBuf->Cmd);
// printf("Value = %8.8lX %ld\n",pDbgBuf->Value,pDbgBuf->Value);
break;
}
} /* endfor */
fprintf(hTrap,"\n");
}