sampos2.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 600 行 · 第 1/2 页

C
600
字号
        CGraphSeg = 0;
    } else {
        addr.segment = FP_SEG( Comm.cgraph_top );
        addr.offset = FP_OFF( Comm.cgraph_top );
        readMemory( &addr, sizeof( stack_entry ), (char *) &stack_entry );
        CGraphOff = stack_entry.ip;
        CGraphSeg = stack_entry.cs;
        Comm.cgraph_top = stack_entry.ptr;
    }
}

void StopProg()
{
}


static void CodeLoad( TRACEBUF FAR_PTR *buff, USHORT mte,
                      char *name, samp_block_kinds kind )
{
    seg_offset  ovl;
    int         i;

    ovl.offset = 0;
    ovl.segment = 0;
    WriteCodeLoad( ovl, name, kind );
    buff->mte = mte;
    for( i = 1;; ++i ) {
        buff->cmd = PT_CMD_SEG_TO_SEL;
        buff->value = i;
        if( DosPTrace( buff ) != 0 ) break;
        if( buff->cmd != PT_RET_SUCCESS ) break;
        WriteAddrMap( i, buff->value, 0 );
    }
}


USHORT LibLoadPTrace( TRACEBUF FAR_PTR *buff )
{
    int         cmd;
    int         value;
    USHORT      rv;
    USHORT      offv;
    USHORT      segv;
    char        name[ BUFF_SIZE ];

    cmd = buff->cmd;
    value = buff->value;
    segv = buff->segv;
    offv = buff->offv;
    for( ;; ) {
        rv = DosPTrace( buff );
        if( MainMod == 0 ) MainMod = buff->mte;
        if( buff->cmd != PT_RET_LIB_LOADED ) return( rv );
        buff->cmd = PT_CMD_GET_LIB_NAME;
        buff->segv = FP_SEG( name );
        buff->offv = FP_OFF( name );
        DosPTrace( buff );
        CodeLoad( buff, buff->value, name,
                 (MainMod == buff->value) ? SAMP_MAIN_LOAD : SAMP_CODE_LOAD );
        buff->value = value;
        buff->cmd = cmd;
        buff->offv = offv;
        buff->segv = segv;
    }
}

static void InternalError( char * str )
{
    Output( MsgArray[MSG_SAMPLE_2-ERR_FIRST_MESSAGE] );
    Output( str );
    Output( "\r\n" );
    _exit( -1 );
}


void __far Sleeper( void )
{
    static TRACEBUF     mybuff;

    for( ;; ) {
        DosSleep( SleepTime );
        mybuff.pid = Pid;
        mybuff.tid = 1;
        mybuff.cmd = PT_CMD_STOP;
        if( DosPTrace( &mybuff ) != 0 ) {
#if 0
            InternalError( "DosPTrace( STOP ) failed" );
#endif
        }
    }
}

typedef struct _NEWSTARTDATA {  /* stdata */
    USHORT  Length;
    USHORT  Related;
    USHORT  FgBg;
    USHORT  TraceOpt;
    PSZ     PgmTitle;
    PSZ     PgmName;
    PBYTE   PgmInputs;
    PBYTE   TermQ;
    PBYTE   Environment;
    USHORT  InheritOpt;
    USHORT  SessionType;
    PSZ     IconFile;
    ULONG   PgmHandle;
    USHORT  PgmControl;
    USHORT  InitXPos;
    USHORT  InitYPos;
    USHORT  InitXSize;
    USHORT  InitYSize;
    USHORT  Reserved;
    PSZ     ObjectBuffer;
    ULONG   ObjectBuffLen;
} NEWSTARTDATA;

static void LoadProg( char *cmd, char *cmd_tail )
{
    RESULTCODES         res;
    NEWSTARTDATA        start;
    USHORT              SID;

    if( NewSession ) {
        start.Length = 50;
        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;
        start.IconFile = NULL;
        start.PgmHandle = 0;
        start.PgmControl = 0;
        if( DosStartSession( (void far *)&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;
    }
}


#define BSIZE 256

void StartProg( char *cmd, char *prog, char *args )
{

    char        *src;
    char        *dst;
    USHORT      drive;
    ULONG       map;
    USHORT      len;
    USHORT      tid;
    USHORT      rc;
    char        buff[BSIZE];
    seg_offset  where;
    char        *cmd_tail;

    cmd = cmd;
    MaxThread = 0;
    GrowArrays( 1 );
    src = prog;
    dst = UtilBuff;
    DosQCurDisk( &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 );
        DosQCurDir( 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 );
    Output( MsgArray[MSG_SAMPLE_1-ERR_FIRST_MESSAGE] );
    Output( UtilBuff );
    Output( "\r\n" );
    Buff.pid = Pid;
    Buff.tid = 1;
    Buff.cmd = PT_CMD_STOP;
    LibLoadPTrace( &Buff );
    if( OSVer < 0x1400 ) {
        /* OS/2 2.x already dumped out MainMod as a Module load */
        CodeLoad( &Buff, MainMod, ExeName, SAMP_MAIN_LOAD );
    }
    InitialCS = Buff.u.r.CS;
    rc = DosCreateThread( Sleeper, (PUSHORT)&tid, Stack+STACK_SIZE );
    if( rc != 0 ) {
        InternalError( MsgArray[MSG_SAMPLE_4-ERR_FIRST_MESSAGE] );
    }
    rc = DosSetPrty( PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, tid );
    if( rc != 0 ) {
        InternalError( MsgArray[MSG_SAMPLE_5-ERR_FIRST_MESSAGE] );
    }
    Buff.pid = Pid;
    Buff.tid = 1;
    for( ;; ) {
        Buff.cmd = PT_CMD_GO;
        if( LibLoadPTrace( &Buff ) != 0 ) {
            InternalError( MsgArray[MSG_SAMPLE_7-ERR_FIRST_MESSAGE] );
        }
        if( Buff.cmd == PT_RET_BREAK && Buff.u.r.DX != 0 ) {    /* a mark */
            len = 0;
            Buff.segv = Buff.u.r.DX;
            Buff.offv = Buff.u.r.AX;
            for( ;; ) {
                Buff.cmd = PT_CMD_READ_MEM_D;
                DosPTrace( &Buff );
                buff[ len ] = Buff.value;
                if( Buff.cmd != PT_RET_SUCCESS ) buff[ len ] = '\0';
                if( len == BSIZE ) buff[ len ] = '\0';
                if( buff[ len ] == '\0' ) break;
                ++len;
                Buff.offv++;
            }
            where.segment = Buff.u.r.CS;
            where.offset = Buff.u.r.IP;
            WriteMark( buff, where );
            Buff.cmd = PT_CMD_READ_REGS;
            DosPTrace( &Buff );
            Buff.u.r.IP++;
            Buff.cmd = PT_CMD_WRITE_REGS;
            DosPTrace( &Buff );
            continue;
        } else if( Buff.cmd == PT_RET_BREAK ) {         /* common info pass */
            CommonAddr.segment = Buff.u.r.CX;
            CommonAddr.offset = Buff.u.r.BX;
            Buff.cmd = PT_CMD_READ_REGS;
            DosPTrace( &Buff );
            Buff.u.r.IP++;
            Buff.cmd = PT_CMD_WRITE_REGS;
            DosPTrace( &Buff );
            continue;
        }
        if( Buff.cmd == PT_RET_FUNERAL ) break;
        if( Buff.cmd != PT_RET_LIB_LOADED
         && Buff.cmd != PT_RET_STOPPED
         && Buff.cmd != PT_RET_TRD_TERMINATE ) {
            InternalError( MsgArray[MSG_SAMPLE_6-ERR_FIRST_MESSAGE] );
            break;
        }
        RecordSample( Buff.u.r.IP, Buff.u.r.CS, Buff.tid );
    }
    report();
}

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