home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
except2x.zip
/
traptrap.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-17
|
38KB
|
853 lines
/**********************************************************************/
/* IBM Internal Use Only */
/**********************************************************************/
/* */
/* TRAPTRAP */
/* */
/* TRAPTRAP is a sample usage of DosDebug to gather information */
/* on program traps without changing the source code. */
/* C-SET/2 compiler complies that code */
/**********************************************************************/
/* Version: 2.4 | Marc Fiammante (FIAMMANT at LGEVM2) */
/* | La Gaude FRANCE */
/* Version: 2.5 | Anthony Cruise (CRUISE at YKTVMH) */
/* | Watson Research */
/**********************************************************************/
/* Test only under OS/2 version 2.1 */
/**********************************************************************/
/* History: */
/* -------- */
/* */
/* created: Marc Fiammante September 1993 */
/* this traptrap.c uses DosStartSession which allows any kind */
/* of executables PM,TextWindowed or FullScreen */
/* changed: Anthony Cruise, May 1995 */
/* Do not dump duplicate lines */
/**********************************************************************/
#define INCL_BASE
#include <os2.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
/*-------- Various Buffers and pointers ------*/
CHAR CmdBuf[256];
CHAR ObjectBuffer[256];
CHAR *CmdPtr;
UCHAR LoadError[40]; /*DosExecPGM buffer */
UCHAR ProcessName[256];
CHAR Name[CCHMAXPATH];
UCHAR *StackCopy;
FILE *hTrap;
/*============================================*/
/*--╔════════════════════════════════╗ ------*/
/*--║ DosDebug Definitions ║ ------*/
/*--╚════════════════════════════════╝ ------*/
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;
/*-------------------------------------*/
/*---- Commands -----------------------*/
#define DBG_C_NULL 0
#define DBG_C_ReadMem 1
#define DBG_C_ReadMem_I 1
#define DBG_C_ReadMem_D 2
#define DBG_C_ReadReg 3
#define DBG_C_WriteMem 4
#define DBG_C_WriteMem_I 4
#define DBG_C_WriteMem_D 5
#define DBG_C_WriteReg 6
#define DBG_C_Go 7
#define DBG_C_Term 8
#define DBG_C_SStep 9
#define DBG_C_Stop 10
#define DBG_C_Freeze 11
#define DBG_C_Resume 12
#define DBG_C_NumToAddr 13
#define DBG_C_ReadCoRegs 14
#define DBG_C_WriteCoRegs 15
#define DBG_C_ThrdStat 17
#define DBG_C_MapROAlias 18
#define DBG_C_MapRWAlias 19
#define DBG_C_UnMapALias 20
#define DBG_C_Connect 21
#define DBG_C_ReadMemBuf 22
#define DBG_C_WriteMemBuf 23
#define DBG_C_SetWatch 24
#define DBG_C_ClearWatch 25
#define DBG_C_RangeStep 26
#define DBG_C_Continue 27
#define DBG_C_AddrToObject 28
#define DBG_C_XchngOpCode 29
#define DBG_C_LinToSel 30
#define DBG_C_SelToLin 31
/*------ Constants -------------------*/
#define DBG_L_386 1
#define DBG_O_OBJMTE 0x10000000L
/*------ Notifications ---------------*/
#define DBG_N_SUCCESS 0
#define DBG_N_ERROR -1
#define DBG_N_ProcTerm -6
#define DBG_N_Exception -7
#define DBG_N_ModuleLoad -8
#define DBG_N_CoError -9
#define DBG_N_ThreadTerm -10
#define DBG_N_AsyncStop -11
#define DBG_N_NewProc -12
#define DBG_N_AliasFree -13
#define DBG_N_Watchpoint -14
#define DBG_N_ThreadCreate -15
#define DBG_N_ModuleFree -16
#define DBG_N_RangeStep -17
#define DBG_X_FIRST_CHANCE 1
#define DBG_X_STACK_INVALID 3
#define DBG_W_Local 0x00000001
#define DBG_W_Global 0x00000002
#define DBG_W_Execute 0x00010000
#define DBG_W_Write 0x00020000
#define DBG_W_ReadWrite 0x00030000
RESULTCODES ReturnCodes;
APIRET CheckExcep( PEXCEPTIONREPORTRECORD pERepRec,
PCONTEXTRECORD pCtxRec);
/*-------------------------------------*/
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 */
VOID ListModules(VOID);
VOID GetObjects(struct debug_buffer * pDbgBuf,HMODULE hMte,PSZ pName);
CHAR *QueueName="\\QUEUES\\TRACE\\TRACE.QUE";
HQUEUE QueueHandle=0;
USHORT WatchPointCount=0;
ULONG WatchPoint[4];
ULONG WatchIndex[4];
char * stopstring;
typedef struct _LOADEDMODS {
struct _LOADEDMODS * Next;
HMODULE hMte;
} LOADEDMODS;
typedef LOADEDMODS * PLOADEDMODS;
PLOADEDMODS FirstLoaded=0;
PLOADEDMODS LastLoaded;
BOOL BigSeg;
/*-------------------------------------*/
int main(int argc, char **argv)
{
APIRET rc;
PEXCEPTIONREPORTRECORD pERepRec;
PCONTEXTRECORD pCtxRec;
char * Dot;
char * Slash;
BOOL First;
ULONG SessId;
STARTDATA StartData;
REQUESTDATA Request;
ULONG cbData;
PUSHORT Data;
BYTE priority;
ULONG cbEntries;
ULONG AppType;
int i;
if (argc==1) {
printf("Program Name Missing\n");
return ERROR_INVALID_PARAMETER;
} /* endif */
argc--;argv++;
/*--------------------------------------------------*/
/*- Check if watch points required -----------------*/
while (argv[0][0]=='/') {
if (WatchPointCount<4) {
WatchPoint[WatchPointCount]=strtoul(argv[0]+1,&stopstring,16);
WatchPointCount++;
} else {
printf("386 processor only supports a maximum of 4 watch points\n");
} /* endif */
argc--;argv++;
if (argc==0) {
break;
} /* endif */
} /* endwhile */
/*--------------------------------------------------*/
/*- Build new command line ----------------------*/
/* strcpy(CmdBuf,argv[0]); Only for DosExecPgm */
strcpy(ProcessName,argv[0]);
Dot=strrchr(ProcessName,'.');
/*-- look for .EXE */
if (Dot==NULL) {
strcat(ProcessName,".EXE");
} else {
Slash=strrchr(ProcessName,'\\');
/* Maybe '.' for current directory but no EXE extension */
if (Slash>Dot) {
strcat(ProcessName,".EXE");
} /* endif */
} /* endif */
strupr(ProcessName);
CmdPtr=CmdBuf/*+strlen(CmdBuf)+1*/;
*CmdPtr=0x00; /* Add supplem */
argc--;argv++;
for (i=0;i<argc;i++ ) {
strcat(CmdPtr," ");
strcat(CmdPtr,argv[i]);
} /* endfor */
/*--------------------------------------------------*/
hTrap=fopen("PROCESS.TRP","w");
/*--------------------------------------------------*/
// rc = DosExecPgm(LoadError, /* Object name buffer */
// sizeof(LoadError), /* Length of object name buffer */
// EXEC_TRACE, /* Asynchronous/Trace flags */
// CmdBuf, /* Argument string */
// NULL, /* Environment string */
// &ReturnCodes, /* Termination codes */
// ProcessName); /* Program file name */
rc=DosCreateQueue( &QueueHandle , QUE_FIFO,QueueName);
fprintf(hTrap,"Create queue rc %d\n", rc);
memset(&StartData,0x00,sizeof(STARTDATA));
DosQueryAppType(ProcessName,&AppType);
AppType=0x0003 & AppType;
StartData.Length=sizeof(STARTDATA); /* length of data structure */
StartData.Related=SSF_RELATED_CHILD; /* 0 = independent session, */
/* 1 = child session */
StartData.FgBg=SSF_FGBG_FORE; /* 0 = start in foreground, */
/* 1 = start in background */
StartData.TraceOpt=SSF_TRACEOPT_TRACEALL; /* 0 = no trace, 1 = trace */
StartData.PgmTitle=ProcessName; /* address of program title */
StartData.PgmName=ProcessName; /* address of program name */
StartData.PgmInputs=CmdBuf; /* input arguments */
StartData.TermQ =QueueName; /*address of program queue name*/
StartData.Environment=NULL; /* environment string */
StartData.InheritOpt=SSF_INHERTOPT_PARENT; /* where are handles and */
/* environment inherited from */
/* 0 = inherit from shell , */
/* 1 = inherit from caller */
StartData.SessionType=AppType; /* session type */
StartData.IconFile =0; /* address of icon definition */
StartData.PgmHandle =0; /* program handle */
StartData.PgmControl=SSF_CONTROL_VISIBLE; /*initial state of windowed app*/
StartData.InitXPos= 0; /*x coor of init session window*/
StartData.InitYPos= 0; /*y coor of init session window*/
StartData.InitXSize= 0; /* initial size of x */
StartData.InitYSize= 0; /* initial size of y */
StartData.Reserved =0;
StartData.ObjectBuffer=ObjectBuffer;
StartData.ObjectBuffLen=sizeof(ObjectBuffer);
DosSelectSession(0);
rc=DosStartSession(
&StartData,
&SessId,
&ReturnCodes.codeTerminate);
fprintf(hTrap,"rc = %d Process ID %d Session %d >%s<>%s<>%s<\n",
rc,
ReturnCodes.codeTerminate,
SessId,ProcessName,ObjectBuffer,CmdBuf);
if (rc != NO_ERROR) {
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);
}
for (i=0;i<WatchPointCount;i++) {
fprintf(hTrap,"Addind watch point %8.8X\n",WatchPoint[i]);
DbgBuf.Cmd = DBG_C_SetWatch;/* Indicate that a Connect is requested */
DbgBuf.Pid = ReturnCodes.codeTerminate;
DbgBuf.Tid = 0;
DbgBuf.Addr = WatchPoint[i];
switch (WatchPoint[i]&0x00000003) {
case 0:
DbgBuf.Len = 4; /* double word boundary */
break;
case 1:
DbgBuf.Len = 1; /* 1 byte boundary */
break;
case 2:
DbgBuf.Len = 2; /* word boundary */
break;
case 3:
DbgBuf.Len = 1; /* 1 byte boundary */
break;
} /* endswitch */
DbgBuf.Value = DBG_W_Write + DBG_W_Local;
DbgBuf.Index = 0;
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);
} else {
WatchIndex[i] =DbgBuf.Index;
}
} /* endfor */
while (DbgBuf.Cmd!=DBG_N_ProcTerm) {
DosSleep(50L);
fprintf(hTrap,"Now Issuing Go\n");
fflush(hTrap);
DbgBuf.Cmd = DBG_C_Go; /* Indicate that a Connect is requested */
DbgBuf.Pid = ReturnCodes.codeTerminate; /* Pid of Debuggee */
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);
}
switch (DbgBuf.Cmd) {
case DBG_N_SUCCESS:
fprintf(hTrap,"DosDebug GO Successfull\n");
break;
case DBG_N_ERROR:
fprintf(hTrap,"DosDebug Error %8.8lXx (%ld)\n",DbgBuf.Value,DbgBuf.Value);
break;
case DBG_N_ProcTerm:
fprintf(hTrap,"Process Terminated with rc %d\n",DbgBuf.Value);
break;
case DBG_N_Exception:
fprintf(hTrap,"Exception Occurred\n");
break;
case DBG_N_ModuleLoad:
Name[0]=0x00;
if (FirstLoaded==0) {
FirstLoaded =(PLOADEDMODS)malloc(sizeof(LOADEDMODS));
LastLoaded = FirstLoaded;
} else {
LastLoaded->Next =(PLOADEDMODS)malloc(sizeof(LOADEDMODS));
LastLoaded=LastLoaded->Next;
}
LastLoaded->Next=0;
LastLoaded->hMte=DbgBuf.Value;
rc=DosQueryModuleName(DbgBuf.Value,CCHMAXPATH, Name);
fprintf(hTrap,"MODULE %s loaded\n",Name);
break;
case DBG_N_CoError:
fprintf(hTrap,"Coprocessor Error\n");
break;
case DBG_N_ThreadTerm:
fprintf(hTrap,"Thread %d Terminated with rc %d\n",DbgBuf.Tid,DbgBuf.Value);
break;
case DBG_N_AsyncStop:
fprintf(hTrap,"Asynchronous Stop\n");
break;
case DBG_N_NewProc:
fprintf(hTrap,"Debuggee started New Process Pid %X\n",DbgBuf.Value);
break;
case DBG_N_AliasFree:
fprintf(hTrap,"Alias Freed\n");
break;
case DBG_N_Watchpoint:
fprintf(hTrap,"WatchPoint Hit\n");
for (i=0;i<WatchPointCount;i++) {
if (WatchIndex[i] ==DbgBuf.Index) {
fprintf(hTrap,"Process %d\n",DbgBuf.Value);
fprintf(hTrap,"Thread %d\n",DbgBuf.Len);
fprintf(hTrap,"Wrote at address %8.8X\n",WatchPoint[i]);
fprintf(hTrap,"From instruction at address %8.8X\n",DbgBuf.Addr);
Name[0]=0x00;
rc=DosQueryModuleName(DbgBuf.MTE,CCHMAXPATH, Name);
if (rc==0) {
fprintf(hTrap,"In module %s\n",Name);
GetObjects(&DbgBuf,DbgBuf.MTE,Name);
} /* endif */
break;
} /* endif */
} /* endfor */
break;
case DBG_N_ThreadCreate:
fprintf(hTrap,"Thread %d Created\n",DbgBuf.Tid);
break;
case DBG_N_ModuleFree:
Name[0]=0x00;
rc=DosQueryModuleName(DbgBuf.Value,CCHMAXPATH, Name);
fprintf(hTrap,"MODULE %s freed\n",Name);
break;
case DBG_N_RangeStep:
fprintf(hTrap,"RangeStep fault\n");
break;
} /* endswitch */
fflush(hTrap);
if (DbgBuf.Cmd==DBG_N_Exception) {
if ((DbgBuf.Value==DBG_X_FIRST_CHANCE) ||
(DbgBuf.Value==DBG_X_STACK_INVALID)) {
fprintf(hTrap,"Got the exception on Thread %d\n",DbgBuf.Tid);
pERepRec=(PEXCEPTIONREPORTRECORD)DbgBuf.Buffer;
pCtxRec =(PCONTEXTRECORD)DbgBuf.Len;
if (CheckExcep(pERepRec,pCtxRec)) break;
}
} /* endif */
} /* endwhile */
// fclose(hTrap);
}
static ULONG Version[2];
APIRET CheckExcep( PEXCEPTIONREPORTRECORD pERepRec,
PCONTEXTRECORD pCtxRec) {
APIRET rc;
USHORT Count;
USHORT Passes;
UCHAR Translate[17];
UCHAR OldStuff[16];
PUSHORT StackPtr;
PUCHAR cStackPtr;
EXCEPTIONREPORTRECORD ERepRec;
CONTEXTRECORD CtxRec;
static CHAR Format[10];
ULONG stacklen;
UCHAR *stackptr;
fprintf(hTrap,"\n/*----- getting exception records ---*/\n");
DbgBuf.Cmd = DBG_C_ReadMemBuf; /* Indicate that a Connect is requested */
DbgBuf.Pid = ReturnCodes.codeTerminate; /* Pid of Debuggee */
DbgBuf.Addr =(ULONG) pERepRec;
DbgBuf.Buffer =(ULONG) &ERepRec;
DbgBuf.Len = sizeof(EXCEPTIONREPORTRECORD);
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);
return 1;
}
fprintf(hTrap,"\n/*----- getting Context record ---*/\n");
DbgBuf.Cmd = DBG_C_ReadMemBuf; /* Indicate that a Connect is requested */
DbgBuf.Pid = ReturnCodes.codeTerminate; /* Pid of Debuggee */
DbgBuf.Addr =(ULONG) pCtxRec;
DbgBuf.Buffer =(ULONG) &CtxRec;
DbgBuf.Len = sizeof(CONTEXTRECORD);
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);
return 1;
}
if ((ERepRec.ExceptionNum&XCPT_SEVERITY_CODE)==XCPT_FATAL_EXCEPTION)
{
if ((ERepRec.ExceptionNum!=XCPT_PROCESS_TERMINATE)&&
(ERepRec.ExceptionNum!=XCPT_UNWIND)&&
(ERepRec.ExceptionNum!=XCPT_SIGNAL)&&
(ERepRec.ExceptionNum!=XCPT_ASYNC_PROCESS_TERMINATE)) {
fprintf(hTrap,"--------------------------\n");
fprintf(hTrap,"Exception %8.8lX Occurred\n",ERepRec.ExceptionNum);
fprintf(hTrap," at %s ",_strtime(Buffer));
fprintf(hTrap," %s\n",_strdate(Buffer));
if ( ERepRec.ExceptionNum == XCPT_ACCESS_VIOLATION)
{
switch (ERepRec.ExceptionInfo[0]) {
case XCPT_READ_ACCESS:
case XCPT_WRITE_ACCESS:
fprintf(hTrap,"Invalid linear address %8.8lX\n",ERepRec.ExceptionInfo[1]);
break;
case XCPT_SPACE_ACCESS:
fprintf(hTrap,"Invalid Selector %8.8lX\n",ERepRec.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 */
DbgBuf.Addr =(ULONG) ERepRec.ExceptionAddress;
DbgBuf.Cmd = DBG_C_AddrToObject;/* Indicate that a AddrToObject is requested */
DbgBuf.Pid = ReturnCodes.codeTerminate; /* Pid of Debuggee */
rc = DosDebug(&DbgBuf);
if ((rc==0)&&(DbgBuf.Value&DBG_O_OBJMTE)) {
rc=DosQueryModuleName(DbgBuf.MTE,CCHMAXPATH, Name);
fprintf(hTrap,"Failing code module file name : %s\n",Name);
fprintf(hTrap,"Failing Object starting at %x,failure at Offset %x \n",DbgBuf.Buffer,DbgBuf.Addr-DbgBuf.Buffer);
} /* endif */
BigSeg=((CtxRec.ctx_RegEip)>0x00010000);
if ( (CtxRec.ContextFlags) & CONTEXT_SEGMENTS ) {
fprintf(hTrap,"GS : %4.4lX ",CtxRec.ctx_SegGs);
fprintf(hTrap,"FS : %4.4lX ",CtxRec.ctx_SegFs);
fprintf(hTrap,"ES : %4.4lX ",CtxRec.ctx_SegEs);
fprintf(hTrap,"DS : %4.4lX \n",CtxRec.ctx_SegDs);
} /* endif */
if ( (CtxRec.ContextFlags) & CONTEXT_INTEGER ) {
fprintf(hTrap,"EDI : %8.8lX ",CtxRec.ctx_RegEdi );
fprintf(hTrap,"ESI : %8.8lX ",CtxRec.ctx_RegEsi );
fprintf(hTrap,"EAX : %8.8lX ",CtxRec.ctx_RegEax );
fprintf(hTrap,"EBX : %8.8lX\n",CtxRec.ctx_RegEbx );
fprintf(hTrap,"ECX : %8.8lX ",CtxRec.ctx_RegEcx );
fprintf(hTrap,"EDX : %8.8lX\n",CtxRec.ctx_RegEdx );
} /* endif */
if ( (CtxRec.ContextFlags) & CONTEXT_CONTROL ) {
void * _Seg16 Ptr16;
fprintf(hTrap,"EBP : %8.8lX ",CtxRec.ctx_RegEbp );
fprintf(hTrap,"EIP : %8.8lX ",CtxRec.ctx_RegEip );
fprintf(hTrap,"EFLG: %8.8lX ",CtxRec.ctx_EFlags );
fprintf(hTrap,"ESP : %8.8lX\n",CtxRec.ctx_RegEsp );
fprintf(hTrap,"CS : %4.4lX ",CtxRec.ctx_SegCs );
fprintf(hTrap,"SS : %4.4lX\n",CtxRec.ctx_SegSs );
fprintf(hTrap,"CSLIM: %8.8lX " ,DbgBuf.CSLim);
fprintf(hTrap,"SSLIM: %8.8lX \n",DbgBuf.SSLim);
fprintf(hTrap,"FSLIM: %8.8lX \n",DbgBuf.FSLim);
fprintf(hTrap,"FSBase: %8.8lX \n",DbgBuf.FSBase);
fprintf(hTrap,"FS : %4.4X \n",DbgBuf.FS);
ListModules();
/*------ Now the stack ---------------------------*/
/*--I should use the stacklimits in the struture--*/
/*--pointed by FS:0 but there is a bug in OS/2 --*/
/*--see APAR PJ06136 FS is mapped to the --*/
/*--debuggers thread not the debuggee !!!!!! --*/
fprintf(hTrap,"\n/*----- getting Stack Object ---*/\n");
if (CtxRec.ctx_RegEsp<0x10000) { /* stack is 16:16 */
DbgBuf.Cmd = DBG_C_SelToLin;
DbgBuf.Pid = ReturnCodes.codeTerminate; /* Pid of Debuggee */
DbgBuf.Value = CtxRec.ctx_SegSs;
DbgBuf.Index = CtxRec.ctx_RegEsp;
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);
return 1;
}
fprintf(hTrap,"Linear 16:16 stack Address %p\n",DbgBuf.Addr);
} else {
DbgBuf.Addr =(ULONG) CtxRec.ctx_RegEsp;
} /* endif */
DbgBuf.Cmd = DBG_C_AddrToObject;/* Indicate that a AddrToObject is requested */
DbgBuf.Pid = ReturnCodes.codeTerminate; /* Pid of Debuggee */
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);
return 1;
}
stacklen = DbgBuf.Len;
fprintf(hTrap,"Thread Id %lu \n", DbgBuf.Tid);
Ptr16=(void * _Seg16)DbgBuf.Buffer;
sprintf(Format,"%8.8lX",Ptr16);
fprintf(hTrap,"Stack Bottom : %8.8lX (%4.4s:%4.4s) ;",DbgBuf.Buffer,Format,Format+4);
Ptr16=(void * _Seg16)(DbgBuf.Buffer+DbgBuf.Len-1);
sprintf(Format,"%8.8lX",Ptr16);
fprintf(hTrap,"Stack Top : %8.8lX (%4.4s:%4.4s) \n",DbgBuf.Buffer+DbgBuf.Len,Format,Format+4);
fprintf(hTrap,"Process Id : %lu ", DbgBuf.Pid);
rc=DosQueryModuleName(DbgBuf.MTE,CCHMAXPATH, Name);
if (rc==NO_ERROR) {
fprintf(hTrap,".EXE name : %s\n",Name);
} else {
fprintf(hTrap,".EXE name : ??????\n");
} /* endif */
Count=0;
Translate[0]=0x00;
StackCopy=malloc(stacklen);
fprintf(hTrap,"\n/*----- Stack Object Bottom -<%8.8X>--*/\n",DbgBuf.Buffer);
fprintf(hTrap,"StackCopy %p Length %d\n\n", StackCopy,DbgBuf.Len);
DbgBuf.Cmd = DBG_C_ReadMemBuf; /* Indicate that a Connect is requested */
DbgBuf.Pid = ReturnCodes.codeTerminate; /* Pid of Debuggee */
DbgBuf.Addr = DbgBuf.Buffer;
DbgBuf.Len = stacklen;
DbgBuf.Buffer =(ULONG) StackCopy;
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);
} else {
memset(OldStuff,0,16);
for (StackPtr=(PUSHORT)StackCopy;
StackPtr<(PUSHORT)(StackCopy+stacklen);
StackPtr++) {
if (Count==0) {
if (memcmp(OldStuff,StackPtr,16)){
memcpy(OldStuff,StackPtr,16);
Passes = 0;
} else {
if (Passes == 0) {
Passes = 1;
fprintf(hTrap," Same as above.\n");
}
StackPtr+= 7;
continue;
}
}
if (Count==0) {
fprintf(hTrap," %8.8X :",DbgBuf.Addr+(((PUCHAR)StackPtr)-StackCopy));
} /* 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;
fprintf(hTrap," %s\n",Translate);
Translate[0]=0x00;
} /* endif */
} /* endfor */
fprintf(hTrap," %s\n/*----- Stack Object Top -<%8.8X>----*/\n",Translate
,DbgBuf.Addr+(((PUCHAR)StackPtr)-StackCopy));
} /* endif */
} /* endif */
} else {
fprintf(hTrap,"Other fatal exception %8.8lx ",ERepRec.ExceptionNum);
fprintf(hTrap,"At address %8.8lx\n",ERepRec.ExceptionAddress);
} /* endif */
return 1L;
} else {
fprintf(hTrap,"Other non fatal exception %8.8lx ",ERepRec.ExceptionNum);
fprintf(hTrap,"At address %8.8lx\n",ERepRec.ExceptionAddress);
return 0L;
} /* endif */
}
VOID ListModules() {
APIRET rc;
APIRET16 rc16;
#if USE_DOSQPROC
/**----------------------------------***/
rc16=DOS16ALLOCSEG( 0xFFFF , &Selector , 0);
if (rc16==0) {
pBuf=MAKEP(Selector,0);
rc16=DOSQPROCSTATUS(pBuf, 0xFFFF );
if (rc16==0) {
/*****************************/
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 */
#endif
/* Limit object dump to the loaded modules of the debuggee only */
LastLoaded=FirstLoaded;
while (LastLoaded!=0) {
rc=DosQueryModuleName(LastLoaded->hMte,CCHMAXPATH, Name);
GetObjects(&DbgBuf,LastLoaded->hMte,Name);
LastLoaded=LastLoaded->Next;
} /* endwhile */
}
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->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");
}