/* * get the address of Dos32Debug, and get the flat selectors, too. */ int GetDos32Debug( char __far *err ) { char buff[256]; RESULTCODES resc; USHORT dummy; PSZ start; PSZ p; HFILE inh; HFILE outh; USHORT rc; struct { ULONG dos_debug; USHORT cs; USHORT ds; USHORT ss; } data; rc = DosGetModName( ThisDLLModHandle, sizeof( buff ), buff ); if( rc ) { StrCopy( TRP_OS2_no_dll, err ); return( FALSE ); } start = buff; for( p = buff; *p != '\0'; ++p ) { switch( *p ) { case ':': case '\\': case '/': start = p + 1; break; } } p = StrCopy( LOCATOR, start ); if( DosMakePipe( &inh, &outh, sizeof( data ) ) ) { StrCopy( TRP_OS2_no_pipe, err ); return( FALSE ); } *++p = outh + '0'; *++p = '\0'; *++p = '\0'; rc = DosExecPgm( NULL, 0, EXEC_ASYNC, buff, NULL, &resc, buff ); DosClose( outh ); if( rc ) { DosClose( inh ); StrCopy( TRP_OS2_no_help, err ); return( FALSE ); } rc = DosRead( inh, &data, sizeof( data ), &dummy ); DosClose( inh ); if( rc ) { StrCopy( TRP_OS2_no_help, err ); return( FALSE ); } DebugFunc = (void __far *)data.dos_debug; FlatCS = (USHORT) data.cs; FlatDS = (USHORT) data.ds; _retaddr = MakeLocalPtrFlat( (void __far *)DoReturn ); return( TRUE ); }
void WriteLinear( void __far *data, ULONG lin, USHORT size ) { Buff.Cmd = DBG_C_WriteMemBuf; Buff.Addr = lin; Buff.Buffer = MakeLocalPtrFlat( data ); Buff.Len = size; CallDosDebug( &Buff ); }
unsigned int Call32BitDosDebug( dos_debug __far *buff ) { return( DoCall( DebugFunc, MakeLocalPtrFlat( buff ), _retaddr ) ); }
bool DebugExecute( dos_debug *buff, ULONG cmd, bool stop_on_module_load ) { EXCEPTIONREPORTRECORD ex; ULONG value; ULONG stopvalue; ULONG notify=0; BOOL got_second_notification; ULONG fcp; CONTEXTRECORD fcr; 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; } for( ;; ) { buff->Value = value; buff->Cmd = cmd; CallDosDebug( buff ); value = stopvalue; cmd = DBG_C_Continue; /* * handle the preemptive notifications */ switch( buff->Cmd ) { case DBG_N_ModuleLoad: RecordModHandle( buff->Value ); if( stop_on_module_load ) return( TRUE ); 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: ExceptLinear = buff->Addr; 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! // if( buff->Value == DBG_X_FIRST_CHANCE && !ExpectingAFault ) { if( stopOnSecond && !got_second_notification ) { value = XCPT_CONTINUE_SEARCH; break; } } notify = DBG_N_Exception; value = XCPT_CONTINUE_STOP; /* * Buffer contains the ptr to the exception block */ buff->Cmd = DBG_C_ReadMemBuf; buff->Addr = buff->Buffer; buff->Buffer = MakeLocalPtrFlat( (void *) &ex ); buff->Len = sizeof( ex ); CallDosDebug( buff ); ExceptNum = ex.ExceptionNum; if( ExceptNum == XCPT_PROCESS_TERMINATE || ExceptNum == XCPT_ASYNC_PROCESS_TERMINATE || ExceptNum == XCPT_GUARD_PAGE_VIOLATION || ( ExceptNum & XCPT_CUSTOMER_CODE ) ) { value = XCPT_CONTINUE_SEARCH; break; } /* * get the context record */ buff->Cmd = DBG_C_ReadMemBuf; buff->Addr = fcp; buff->Buffer = MakeLocalPtrFlat( (void *) &fcr ); buff->Len = sizeof( fcr ); CallDosDebug( buff ); buff->EAX = fcr.ctx_RegEax; buff->EBX = fcr.ctx_RegEbx; buff->ECX = fcr.ctx_RegEcx; buff->EDX = fcr.ctx_RegEdx; buff->ESI = fcr.ctx_RegEsi; buff->EDI = fcr.ctx_RegEdi; buff->ESP = fcr.ctx_RegEsp; buff->EBP = fcr.ctx_RegEbp; buff->DS = fcr.ctx_SegDs; buff->CS = fcr.ctx_SegCs; buff->ES = fcr.ctx_SegEs; buff->FS = fcr.ctx_SegFs; buff->GS = fcr.ctx_SegGs; buff->SS = fcr.ctx_SegSs; buff->EIP = fcr.ctx_RegEip; buff->EFlags = fcr.ctx_EFlags; WriteRegs( buff ); if( ExpectingAFault || got_second_notification ) { break; } if( stopOnSecond ) { value = XCPT_CONTINUE_EXECUTION; got_second_notification = TRUE; } break; default: if( notify != 0 ) { buff->Cmd = notify; } return( FALSE ); } } // return( FALSE ); }