sampos22.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 616 行 · 第 1/2 页
C
616 行
if( MainMod == 0 ) MainMod = buff->MTE;
value = stopvalue;
cmd = DBG_C_Continue;
/*
* handle the preemptive notifications
*/
switch( buff->Cmd ) {
case DBG_N_ModuleLoad:
DosQueryModuleName( buff->Value, BUFF_SIZE, name );
CodeLoad( buff, buff->Value, name,
(buff->Value == MainMod) ? SAMP_MAIN_LOAD : SAMP_CODE_LOAD );
buff->MTE = MainMod;
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 0
/*
* Value should contain a pointer to the user exception
* block
*/
buff->Cmd = DBG_C_ReadMemBuf;
buff->Buffer = &ex;
buff->Addr = buff->Value;
buff->Len = sizeof( ex );
DosDebug( buff );
ExceptNum = ex.ExceptionNum;
#endif
/*
* Buffer appears to hold the exception number for int 1
* and int 3
*/
ExceptNum = buff->Buffer;
switch( ExceptNum ) {
case XCPT_BREAKPOINT:
notify = DBG_N_Breakpoint;
value = XCPT_CONTINUE_STOP;
break;
case XCPT_SINGLE_STEP:
notify = DBG_N_SStep;
value = XCPT_CONTINUE_STOP;
break;
case XCPT_DATATYPE_MISALIGNMENT:
case XCPT_ACCESS_VIOLATION:
case XCPT_ILLEGAL_INSTRUCTION:
case XCPT_FLOAT_DENORMAL_OPERAND:
case XCPT_FLOAT_DIVIDE_BY_ZERO:
case XCPT_FLOAT_INEXACT_RESULT:
case XCPT_FLOAT_INVALID_OPERATION:
case XCPT_FLOAT_OVERFLOW:
case XCPT_FLOAT_STACK_CHECK:
case XCPT_FLOAT_UNDERFLOW:
case XCPT_INTEGER_DIVIDE_BY_ZERO:
case XCPT_INTEGER_OVERFLOW:
case XCPT_PRIVILEGED_INSTRUCTION:
notify = DBG_N_Exception;
value = XCPT_CONTINUE_STOP;
break;
default:
// value = XCPT_CONTINUE_SEARCH;
/*
* Index should contain which pass into the exception
* handler, but value appears to hold it
*/
if( buff->Value == 1 ) {
value = XCPT_CONTINUE_SEARCH;
break;
}
notify = DBG_N_Exception;
value = XCPT_CONTINUE_STOP;
break;
}
break;
default:
if( notify != 0 ) buff->Cmd = notify;
return;
}
}
}
void APIENTRY Sleeper( unsigned long parm )
{
static uDB_t mybuff;
parm = parm;
for( ;; ) {
DosSleep( SleepTime );
mybuff.Pid = Pid;
mybuff.Cmd = DBG_C_Stop;
if( DosDebug( &mybuff ) != 0 ) {
#if 0
/* Only reason to fail is if the process has already died/stopped.
This can happen if it takes us a long time to write out sample file
*/
InternalError( MsgArray[MSG_SAMPLE_8-ERR_FIRST_MESSAGE] );
#endif
}
if( mybuff.Cmd == -1 && mybuff.Value == ERROR_INVALID_PROCID ) {
sleepProcId = -1;
return;
}
}
}
static void LoadProg( char *cmd, char *cmd_tail )
{
RESULTCODES res;
STARTDATA start;
ULONG SID;
ULONG flags;
if( DosQueryAppType( cmd, &flags ) == 0 ) {
if( (flags & FAPPTYP_EXETYPE) == FAPPTYP_WINDOWAPI ) {
NewSession = 1;
}
}
if( NewSession ) {
start.Length = offsetof( STARTDATA, IconFile );
start.Related = 1;
start.FgBg = 0;
start.TraceOpt = 1;
start.PgmTitle = cmd;
start.PgmName = cmd;
start.PgmInputs = cmd_tail;
start.TermQ = 0;
start.Environment = NULL;
start.InheritOpt = 1;
start.SessionType = 0;
if( DosStartSession( &start, &SID, &Pid ) != 0 ) {
InternalError( MsgArray[MSG_SAMPLE_3-ERR_FIRST_MESSAGE] );
}
} else {
if( DosExecPgm( NULL, 0, EXEC_TRACE, cmd, NULL, &res, cmd ) != 0 ) {
InternalError( MsgArray[MSG_SAMPLE_3-ERR_FIRST_MESSAGE] );
}
Pid = res.codeTerminate;
}
}
void StartProg( char *cmd, char *prog, char *args )
{
char *src;
char *dst;
ULONG drive;
ULONG map;
ULONG len;
seg_offset where;
TID tid;
ULONG rc;
char *cmd_tail;
cmd = cmd;
MaxThread = 0;
GrowArrays( 1 );
src = prog;
dst = UtilBuff;
DosQueryCurrentDisk( &drive, &map );
if( src[0] == '\0' || src[1] == '\0' || src[1] != ':' ) {
*dst++ = drive - 1 + 'A';
*dst++ = ':';
} else {
*dst++ = *src++;
*dst++ = *src++;
}
if( src[0] != '\\' ) {
++dst;
len = BUFF_SIZE - ( dst - UtilBuff );
DosQueryCurrentDir( drive, dst, &len );
dst[ -1 ] = '\\';
if( *dst == '\\' || *dst == '\0' ) {
*dst = '\0';
} else {
while( *dst != '\0' ) {
++dst;
}
*dst++ = '\\';
}
}
strcpy( dst, src );
dst = UtilBuff + strlen( UtilBuff ) + 1;
cmd_tail = dst;
memcpy( dst, args+1, args[0] );
dst += args[0];
*dst = '\0';
++dst;
*dst = '\0';
LoadProg( UtilBuff, cmd_tail );
Buff.Pid = Pid;
Buff.Tid = 0;
Buff.Cmd = DBG_C_Connect;
Buff.Value = DBG_L_386;
if( DosDebug( &Buff ) != 0 ) {
InternalError( MsgArray[MSG_SAMPLE_9-ERR_FIRST_MESSAGE] );
}
Output( MsgArray[MSG_SAMPLE_1-ERR_FIRST_MESSAGE] );
Output( UtilBuff );
Output( "\r\n" );
DebugExecute( &Buff, DBG_C_Stop );
InitialCS = Buff.CS;
rc = DosCreateThread( &tid, Sleeper, 0, FALSE, STACK_SIZE );
if( rc != 0 ) {
InternalError( MsgArray[MSG_SAMPLE_4-ERR_FIRST_MESSAGE] );
}
rc = DosSetPriority( PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, tid );
if( rc != 0 ) {
InternalError( MsgArray[MSG_SAMPLE_5-ERR_FIRST_MESSAGE] );
}
Buff.Pid = Pid;
for( ;; ) {
DebugExecute( &Buff, DBG_C_Go );
switch( Buff.Cmd ) {
case DBG_N_AsyncStop:
RecordSample( Buff.EIP, Buff.CS, Buff.Tid );
break;
case DBG_N_Breakpoint:
if(( Buff.EDX & 0xffff ) != 0 ) { /* this is a mark */
Buff.Cmd = DBG_C_ReadReg;
DosDebug( &Buff );
len = 0;
for( ;; ) {
if( len >= BUFF_SIZE-1 ) break;
Buff.Cmd = DBG_C_ReadMemBuf;
Buff.Addr = Buff.EAX + len;
Buff.Len = 1;
Buff.Buffer = FP_OFF( &UtilBuff[ len ] );
DosDebug( &Buff );
if( UtilBuff[ len ] == '\0' ) break;
++len;
}
UtilBuff[ len ] = '\0';
where.segment = FP_SEG( CodeLoad );
where.offset = Buff.EIP;
WriteMark( UtilBuff, where );
} else { /* this passes CommonAddr */
CommonAddr.segment = Buff.ECX & 0xffff;
CommonAddr.offset = Buff.EBX;
}
Buff.EIP++;
Buff.Cmd = DBG_C_WriteReg;
DosDebug( &Buff );
break;
case DBG_N_Exception:
Output( MsgArray[MSG_SAMPLE_10-ERR_FIRST_MESSAGE] );
Output( "\r\n" );
/* fall through */
case DBG_N_ProcTerm:
Buff.Cmd = DBG_C_Term;
DosDebug( &Buff );
report();
return;
case DBG_N_ThreadTerm:
break;
default:
if( sleepProcId ) {
report();
return;
}
InternalError( MsgArray[MSG_SAMPLE_6-ERR_FIRST_MESSAGE] );
}
}
}
void SysDefaultOptions( void )
{
}
void SysParseOptions( char c, char **cmd )
{
char buff[2];
switch( c ) {
case 'r':
SetTimerRate( cmd );
break;
case 's':
NewSession = 1;
break;
default:
Output( MsgArray[MSG_INVALID_OPTION-ERR_FIRST_MESSAGE] );
buff[0] = c;
buff[1] = '\0';
Output( buff );
Output( "\r\n" );
fatal();
break;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?