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 + -
显示快捷键?