コード例 #1
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] );
}
コード例 #2
0
unsigned ReqProg_load( void )
{
    char                        **args;
    char                        *parms;
    char                        *parm_start;
    int                         i;
    char                        exe_name[PATH_MAX];
    char                        *name;
    pid_t                       save_pgrp;
    prog_load_req               *acc;
    prog_load_ret               *ret;
    unsigned                    len;
    int                         status;

    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );

    last_sig = -1;
    have_rdebug = FALSE;
    dbg_dyn = NULL;
    at_end = FALSE;
    parms = (char *)GetInPtr( sizeof( *acc ) );
    parm_start = parms;
    len = GetTotalSize() - sizeof( *acc );
    if( acc->true_argv ) {
        i = 1;
        for( ;; ) {
            if( len == 0 ) break;
            if( *parms == '\0' ) {
                i++;
            }
            ++parms;
            --len;
        }
        args = alloca( i * sizeof( *args ) );
        parms = parm_start;
        len = GetTotalSize() - sizeof( *acc );
        i = 1;
        for( ;; ) {
            if( len == 0 ) break;
            if( *parms == '\0' ) {
                args[i++] = parms + 1;
            }
            ++parms;
            --len;
        }
        args[i - 1] = NULL;
    } else {
        while( *parms != '\0' ) {
            ++parms;
            --len;
        }
        ++parms;
        --len;
        i = SplitParms( parms, NULL, len );
        args = alloca( (i + 2)  * sizeof( *args ) );
        args[SplitParms( parms, &args[1], len ) + 1] = NULL;
    }
    args[0] = parm_start;
    attached = TRUE;
    pid = RunningProc( args[0], &name );
    if( pid == 0 || ptrace( PTRACE_ATTACH, pid, NULL, NULL ) == -1 ) {
        attached = FALSE;
        args[0] = name;
        if( FindFilePath( TRUE, args[0], exe_name ) == 0 ) {
            exe_name[0] = '\0';
        }
        save_pgrp = getpgrp();
        setpgid( 0, OrigPGrp );
        pid = fork();
        if( pid == -1 )
            return( 0 );
        if( pid == 0 ) {
            if( ptrace( PTRACE_TRACEME, 0, NULL, NULL ) < 0 ) {
                exit( 1 );
            }
            execve( exe_name, (const char **)args, (const char **)dbg_environ );
            exit( 1 ); /* failsafe */
        }
        setpgid( 0, save_pgrp );
    } else if( pid ) {
        GetExeNameFromPid( pid, exe_name, PATH_MAX );
    }
    ret->flags = 0;
    ret->mod_handle = 0;
    if( (pid != -1) && (pid != 0) ) {
        int status;

        ret->task_id = pid;
        ret->flags |= LD_FLAG_IS_PROT | LD_FLAG_IS_32;
        /* 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 ) {
            ret->flags |= LD_FLAG_IS_STARTED;
            if( WSTOPSIG( status ) != SIGSTOP )
                goto fail;
        } else {
            if( WSTOPSIG( status ) != SIGTRAP )
                goto fail;
        }

#if defined( MD_x86 )
        if( !GetFlatSegs( &flatCS, &flatDS ) )
            goto fail;
#endif

        dbg_dyn = GetDebuggeeDynSection( exe_name );
        AddProcess();
        errno = 0;
    }
    ret->err = errno;
    if( ret->err != 0 ) {
        pid = 0;
    }
    CONV_LE_32( ret->err );
    CONV_LE_32( ret->task_id );
    CONV_LE_32( ret->mod_handle );
    return( sizeof( *ret ) );
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 );
        }
    }
    pid = 0;
    CONV_LE_32( ret->err );
    CONV_LE_32( ret->task_id );
    CONV_LE_32( ret->mod_handle );
    return( 0 );
}