ULONG ResolveException(PtraceBuffer *pptb) { UINT exception_no; UINT rc; PtraceBuffer LocalPtb; EXCEPTIONREPORTRECORD ExceptionReportRecord; UINT nbytes; /****************************************************************************/ /* First, get the exception number. */ /****************************************************************************/ exception_no = 0; nbytes = sizeof(EXCEPTIONREPORTRECORD); memset(&LocalPtb,0,sizeof(LocalPtb)); LocalPtb.Pid = pptb->Pid; LocalPtb.Cmd = DBG_C_ReadMemBuf ; LocalPtb.Addr = (ULONG)pptb->Buffer; LocalPtb.Buffer = (ULONG)&ExceptionReportRecord; LocalPtb.Len = (ULONG)nbytes ; rc = DosDebug( &LocalPtb ); if(rc || LocalPtb.Cmd!=DBG_N_Success) return(TRAP_EXP); /* return exception anomaly code */ exception_no = ExceptionReportRecord.ExceptionNum; /****************************************************************************/ /* Now, read the "real" register values into AppPTB. DosDebug gives us */ /* a bogus set of registers so we have to patch them up. */ /****************************************************************************/ { #define LDTBIT 4 CONTEXTRECORD XcptContextRecord; nbytes = sizeof(XcptContextRecord); memset(&LocalPtb,0,sizeof(LocalPtb)); LocalPtb.Pid = pptb->Pid; LocalPtb.Cmd = DBG_C_ReadMemBuf ; LocalPtb.Addr = (ULONG)pptb->Len; LocalPtb.Buffer = (ULONG)&XcptContextRecord; LocalPtb.Len = (ULONG)nbytes ; rc = DosDebug( &LocalPtb ); if(rc || LocalPtb.Cmd!=DBG_N_Success) return(TRAP_EXP); if( XcptContextRecord.ContextFlags & CONTEXT_CONTROL ) { pptb->EBP = XcptContextRecord.ctx_RegEbp; pptb->EIP = XcptContextRecord.ctx_RegEip; pptb->CS = XcptContextRecord.ctx_SegCs; pptb->EFlags = XcptContextRecord.ctx_EFlags; pptb->ESP = XcptContextRecord.ctx_RegEsp; pptb->SS = XcptContextRecord.ctx_SegSs; pptb->CSAtr = 0xd0; if( pptb->CS & LDTBIT ) pptb->CSAtr = 0; pptb->SSAtr = 0xd0; if( pptb->SS & LDTBIT ) pptb->SSAtr = 0; } if( XcptContextRecord.ContextFlags & CONTEXT_INTEGER ) { pptb->EDI = XcptContextRecord.ctx_RegEdi; pptb->ESI = XcptContextRecord.ctx_RegEsi; pptb->EAX = XcptContextRecord.ctx_RegEax; pptb->EBX = XcptContextRecord.ctx_RegEbx; pptb->ECX = XcptContextRecord.ctx_RegEcx; pptb->EDX = XcptContextRecord.ctx_RegEdx; } if( XcptContextRecord.ContextFlags & CONTEXT_SEGMENTS ) { pptb->GS = XcptContextRecord.ctx_SegGs; pptb->FS = XcptContextRecord.ctx_SegFs; pptb->ES = XcptContextRecord.ctx_SegEs; pptb->DS = XcptContextRecord.ctx_SegDs; pptb->GSAtr = 0xd0; if( pptb->GS & LDTBIT ) pptb->GSAtr = 0; pptb->FSAtr = 0xd0; if( pptb->FS & LDTBIT ) pptb->FSAtr = 0; pptb->ESAtr = 0xd0; if( pptb->ES & LDTBIT ) pptb->ESAtr = 0; pptb->DSAtr = 0xd0; if( pptb->DS & LDTBIT ) pptb->DSAtr = 0; } } return(exception_no); }
DebugIt( void *crap ) { STARTDATA start; int code; SWCNTRL SW; HSWITCH hswitch; PPIB pib; PTIB tib; HWND hwndme; QMSG qmsg; /* Message from message queue */ int i; PID Pid = 0; ULONG SID; uDB_t Buff; TID tid; HMQ the_q; DosGetInfoBlocks(&tib,&pib); start.Length = offsetof( STARTDATA, IconFile ); /* default for the rest */ start.Related = 1; start.FgBg = 1; start.TraceOpt = 1; start.PgmTitle = (PSZ) "Test Session"; start.PgmName = "HELLO.EXE"; start.PgmInputs = "hi there"; start.TermQ = 0; start.Environment = NULL; start.InheritOpt = 1; start.SessionType = SSF_TYPE_PM; code = DosStartSession( &start, &SID, &Pid ); Buff.Pid = Pid; Buff.Tid = 0; Buff.Cmd = DBG_C_Connect; Buff.Value = DBG_L_386; DosDebug( &Buff ); Buff.Pid = Pid; Buff.Tid = 1; DebugExecute( &Buff, DBG_C_Stop ); if( Buff.Cmd != DBG_N_Success ) { return; } DebugExecute( &Buff, DBG_C_Go ); if( Buff.Cmd != DBG_N_Breakpoint ) { return; } #if 0 Buff.Cmd = DBG_C_Stop; DosDebug( &Buff ); Buff.Cmd = DBG_C_ReadReg; DosDebug( &Buff ); Buff.EIP++; Buff.Cmd = DBG_C_WriteReg; DosDebug( &Buff ); #endif the_q = WinQueueFromID( Hab, Buff.Pid, Buff.Tid ); #if 0 for( ;; ) { hmq = WinQuerySendMsg( Hab, 0, Q, &qmsg ); if( hmq == 0 ) break; WinReplyMsg( Hab, hmq, Q, 1 ); } #endif WinThreadAssocQueue( Hab, the_q ); while( 1 ) { if( !WinGetMsg( Hab, &qmsg, 0L, 0, 0 ) ) break; } WinThreadAssocQueue( Hab, 0 ); for( ;; ) DosSleep( 100 ); }
APIRET rc = NO_ERROR; /* Return code */ DebugBuf.Cmd = DBG_C_WriteMem; /* Perform WRITE WORD command */ DebugBuf.Pid = TargetPID; /* Target process to control */ DebugBuf.Addr = TargetAddr; /* Target address for command */ DebugBuf.Value = NewValue; /* Value to change in other process */ rc = DosDebug ( &DebugBuf ); if (rc != NO_ERROR) { printf("DosDebug error: return code = %u\n", rc); return 1; }
void DebugExecute( uDB_t *buff, ULONG cmd ) { EXCEPTIONREPORTRECORD ex; ULONG value; ULONG stopvalue; ULONG notify=0; BOOL got_second_notification; ULONG fcp; CONTEXTRECORD fcr; ULONG ExceptNum; buff->Cmd = cmd; value = buff->Value; if( cmd == DBG_C_Go ) { value = 0; } stopvalue = XCPT_CONTINUE_EXECUTION; got_second_notification = FALSE; if( cmd == DBG_C_Stop ) { stopvalue = XCPT_CONTINUE_STOP; } while( 1 ) { buff->Value = value; buff->Cmd = cmd; DosDebug( buff ); value = stopvalue; cmd = DBG_C_Continue; /* * handle the preemptive notifications */ switch( buff->Cmd ) { case DBG_N_ModuleLoad: break; case DBG_N_ModuleFree: break; case DBG_N_NewProc: break; case DBG_N_ProcTerm: value = XCPT_CONTINUE_STOP; /* halt us */ notify = DBG_N_ProcTerm; break; case DBG_N_ThreadCreate: break; case DBG_N_ThreadTerm: break; case DBG_N_AliasFree: break; case DBG_N_Exception: if( buff->Value == DBG_X_STACK_INVALID ) { value = XCPT_CONTINUE_SEARCH; break; } fcp = buff->Len; if( buff->Value == DBG_X_PRE_FIRST_CHANCE ) { ExceptNum = buff->Buffer; if( ExceptNum == XCPT_BREAKPOINT ) { notify = DBG_N_Breakpoint; value = XCPT_CONTINUE_STOP; break; } else if( ExceptNum == XCPT_SINGLE_STEP ) { notify = DBG_N_SStep; value = XCPT_CONTINUE_STOP; break; } } // // NOTE: Going to second chance causes OS/2 to report the // exception in the debugee. However, if you report // the fault at the first chance notification, the // debugee's own fault handlers will not get invoked! // value = XCPT_CONTINUE_SEARCH; break; default: if( notify != 0 ) { buff->Cmd = notify; } return; } } }