コード例 #1
0
ファイル: samplnx.c プロジェクト: Azarien/open-watcom-v2
static void RecordSample( unsigned offset, unsigned tid )
{
    samp_block  *old_samples;
    unsigned    old_sample_index;
    unsigned    old_sample_count;

    if( tid > MaxThread ) {
        GrowArrays( tid );
    }
    --tid;
    LastSampleIndex = SampleIndexP[tid];
    if( SampleIndexP[tid] == 0 ) {
        SamplesP[tid]->pref.tick = CurrTick;
        if( CallGraphMode ) {
            CallGraphP[tid]->pref.tick = CurrTick;
        }
    }
    ++CurrTick;
    SamplesP[tid]->d.sample.sample[SampleIndexP[tid]].offset = offset;
    SamplesP[tid]->d.sample.sample[SampleIndexP[tid]].segment = FlatSeg;
    SampleIndexP[tid]++;
    if( CallGraphMode ) {
        SampleCountP[tid]++;
    }
    if( CallGraphMode && tid == 0 ) {
        old_sample_count = SampleCount;
        old_samples = Samples;                  /* since RecordCGraph isn't */
        old_sample_index = SampleIndex;         /* used to threads, we fool */
        Samples = SamplesP[tid];              /* it into storing the info */
        SampleIndex = SampleIndexP[tid];      /* in the right place by    */
        SampleCount = SampleCountP[tid];
        RecordCGraph();                         /* changing its pointers    */
        SamplesP[tid] = Samples;              /* and restoring them later */
        SampleIndexP[tid] = SampleIndex;
        SampleCountP[tid] = SampleCount;
        Samples = old_samples;
        SampleIndex = old_sample_index;
        SampleCount = old_sample_count;
    }
    if( SampleIndexP[tid] >= Margin ) {
        StopAndSave();
    }
}
コード例 #2
0
ファイル: samplnx.c プロジェクト: Azarien/open-watcom-v2
void StartProg( char *cmd, char *prog, char *full_args, char *dos_args )
{
    char            exe_name[PATH_MAX];
    pid_t           save_pgrp;
    pid_t           pid;
    int             status;

    MaxThread = 0;
    GrowArrays( 1 );
    HaveRdebug = false;
    DbgDyn = NULL;
    OrigPGrp = getpgrp();
    Attached = true;
    pid = Pid = SamplePid;

    /* allow attaching to existing process by pid */
    if( pid == 0 || ptrace( PTRACE_ATTACH, pid, NULL, NULL ) == -1 ) {
        int         num_args;
        size_t      len;
        const char  **argv;

        Attached = false;

        /* massage 'full_args' into argv format */
        len = strlen( full_args );
        num_args = SplitParms( full_args, NULL, len );
        argv = alloca( ( num_args + 2 ) * sizeof( *argv ) );
        argv[SplitParms( full_args, argv + 1, len ) + 1] = NULL;
        argv[0] = prog;

        Output( MsgArray[MSG_SAMPLE_1 - ERR_FIRST_MESSAGE] );
        Output( prog );
        Output( "\n" );

        save_pgrp = getpgrp();
        setpgid( 0, OrigPGrp );
        pid = fork();
        if( pid == -1 )
            InternalError( MsgArray[MSG_SAMPLE_3 - ERR_FIRST_MESSAGE] );
        if( pid == 0 ) {
            int     rc;

            if( ptrace( PTRACE_TRACEME, 0, NULL, NULL ) < 0 ) {
                InternalError( MsgArray[MSG_SAMPLE_4 - ERR_FIRST_MESSAGE] );
            }
            dbg_printf( "executing '%s'\n", prog );
            for( rc = 0; argv[rc] != NULL; ++rc )
                dbg_printf( "argv[%d] = '%s'\n", rc, argv[rc] );

            rc = execve( prog, (char const * const *)argv, (char const * const *)environ );
            dbg_printf( "execve() failed, returned %d\n", rc );
            InternalError( MsgArray[MSG_SAMPLE_3 - ERR_FIRST_MESSAGE] );  // failsafe
        }
        setpgid( 0, save_pgrp );
        strcpy( exe_name, prog );
    } else if( pid ) {
        GetExeNameFromPid( pid, exe_name, PATH_MAX );
        Output( MsgArray[MSG_SAMPLE_1 - ERR_FIRST_MESSAGE] );
        Output( exe_name );
        Output( "\n" );
    }

    if( (pid != -1) && (pid != 0) ) {
        /* wait until it hits _start (upon execve) or
           gives us a SIGSTOP (if attached) */
        if( waitpid( pid, &status, 0 ) < 0 )
            goto fail;
        if( !WIFSTOPPED( status ) )
            goto fail;
        if( Attached ) {
            if( WSTOPSIG( status ) != SIGSTOP ) {
                goto fail;
            }
        } else {
            if( WSTOPSIG( status ) != SIGTRAP ) {
                goto fail;
            }
        }

        DbgDyn = GetDebuggeeDynSection( exe_name );
        errno = 0;
    }
    if( errno != 0 ) {
        pid = 0;
    } else {
        /* record information about main executable and initialize shared
         * library tracking
         */
        InitLibMap();
        CodeLoad( exe_name, 0, SAMP_MAIN_LOAD );
        SampleLoop( pid );
        FiniLibMap();
    }
    return;

fail:
    if( pid != 0 && pid != -1 ) {
        if( Attached ) {
            ptrace( PTRACE_DETACH, pid, NULL, NULL );
            Attached = false;
        } else {
            ptrace( PTRACE_KILL, pid, NULL, NULL );
            waitpid( pid, &status, 0 );
        }
    }
    InternalError( MsgArray[MSG_SAMPLE_5 - ERR_FIRST_MESSAGE] );
}
コード例 #3
0
void StartProg( const char *cmd, const char *prog, char *full_args, char *dos_args )
{

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

    /* unused parameters */ (void)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, (PBYTE)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;
    strcpy( dst, full_args );
    dst += strlen( dst );
    *++dst = '\0';      /* Need two nulls at end */
    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();
}