home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
sherlock.zip
/
EXCEPT
/
EXCEPT.ZIP
/
SOURCE.ZIP
/
EXCEPT.C
< prev
next >
Wrap
Text File
|
1993-10-19
|
19KB
|
446 lines
/**********************************************************************/
/* IBM DAPTOOLS UseOnly */
/**********************************************************************/
/* */
/* EXCEPT */
/* */
/* 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 */
/* This uses PSTAT. EXCEPTQ uses DosQProcStatus which is far better */
/**********************************************************************/
/* 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>
#define HF_STDERR 2
UCHAR *ProcessFile = "PROCESS.TRM";
UCHAR *ProcessName = "DEBUGGEE.EXE";
CHAR ProcessHex[10];
FILE *hTrap;
FILE *hProcessFile;
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);
APIRET16 APIENTRY16 DOS16LOADMODULE( CHAR * _Seg16, USHORT, CHAR * _Seg16, USHORT * _Seg16);
typedef APIRET16 (APIENTRY16 _PFN16)();
typedef _PFN16 * _Seg16 PFN16;
#pragma pack(1)
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;
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];
void * _Seg16 Ptr16;
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);
sprintf(ProcessHex,"%4.4X",ppib->pib_ulpid);
} 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,"Exception %8.8lX Occurred\n",pERepRec->ExceptionNum);
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 ) {
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 */
/* sprintf(Buffer,"PSTAT /P:%X > %s",ppib->pib_ulpid,ProcessFile); */
sprintf(Buffer,"PSTAT /L > %s",ProcessFile);
system(Buffer);
ListModules();
GetObjects(&DbgBuf,ppib->pib_hmte,Name);
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);
DosCopy( ProcessFile, TrapFile,DCPY_APPEND);
DosDelete(ProcessFile);
}
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;
BOOL FoundProcess;
hProcessFile=fopen(ProcessFile,"r");
if (hProcessFile!=NULL) {
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);
FoundProcess=FALSE;
while (fscanf(hProcessFile,"%s",Buffer)!=EOF) {
/* printf("Processing >%s<\n",Buffer); */
if (FoundProcess) {
if (strcmp(Buffer+strlen(Buffer)-4,".DLL") ==0) {
HMODULE hMte;
rc=DosQueryModuleHandle(Buffer,&hMte);
if (rc==NO_ERROR) {
GetObjects(&DbgBuf,hMte,Buffer);
} /* endif */
} /* endif */
if (strcmp(Buffer+strlen(Buffer)-5,".DLL*")==0) {
HMODULE hMte;
Buffer[strlen(Buffer)-1]=0x00;
rc=DosQueryModuleHandle(Buffer,&hMte);
if (rc==NO_ERROR) {
GetObjects(&DbgBuf,hMte,Buffer);
} /* endif */
} /* endif */
/* If next .EXE then break */
if (strcmp(Buffer+strlen(Buffer)-4,".EXE")==0) {
break;
} /* endif */
} else {
if (strcmp(ProcessHex,Buffer)==0) {
FoundProcess=TRUE;
} /* endif */
} /* endif */
} /* endwhile */
fclose(hProcessFile);
} else {
printf("Cannot open processfile\n");
} /* 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");
}