⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ntoacc.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    } else if( status.flags & _DEBUG_FLAG_TRACE_EXEC ) {
        ret |= COND_BREAK;
    } else if( status.flags & (_DEBUG_FLAG_TRACE_RD | _DEBUG_FLAG_TRACE_WR) ) {
        ret |= COND_BREAK;
    } else if( status.flags & _DEBUG_FLAG_ISTOP ) {
        switch( status.why ) {
        case _DEBUG_WHY_SIGNALLED:
        case _DEBUG_WHY_FAULTED:
        case _DEBUG_WHY_JOBCONTROL:
            dbg_print(( "stopped on signal: %d\n", status.info.si_signo ));
            if( status.info.si_signo == SIGINT ) {
                ret |= COND_USER;
            } else {
                ProcInfo.sig = status.info.si_signo;
                ret |= COND_EXCEPTION;
            }
            break;
        case _DEBUG_WHY_TERMINATED: {
            int     wait_val = 0;

            waitpid( ProcInfo.pid, &wait_val, WNOHANG );
            dbg_print(( "debuggee terminated (pid %d), status collected (%d)\n", 
                        ProcInfo.pid, wait_val ));
            ProcInfo.at_end = TRUE;
            ret |= COND_TERMINATE;
            break;
        }
        case _DEBUG_WHY_REQUESTED:
            /* We are assuming a requested stop is due to a SIGINT.  */
            ret |= COND_USER;
            break;
        }
    }
    /* Check the dynamic linker breakpoint. */
    if( (ret & COND_BREAK) && (status.ip == ProcInfo.ld_bp_va) ) {
        ret &= ~COND_BREAK;
        ret |= COND_LIBRARIES;
        ProcessLdBreakpoint( ProcInfo.procfd, ProcInfo.rdebug_va );
    }
    return( ret );
}


static unsigned ProgRun( bool step )
{
    debug_greg_t        regs;
    prog_go_ret         *ret;
    int                 regsize;

    ret = GetOutPtr( 0 );
    memset( ret, 0, sizeof( *ret ) );
    if( ProcInfo.at_end ) {
        dbg_print(( "process terminated - nothing to do\n" ));
        ret->conditions = COND_TERMINATE;
    } else if( step ) {
        dbg_print(( "about to step\n" ));
        ret->conditions = RunIt( 1 );
    } else {
        dbg_print(( "about to run\n" ));
        ret->conditions = RunIt( 0 );
    }
    if( !(ret->conditions & COND_TERMINATE) ) {
        memset( &regs, 0, sizeof( regs ) );
        devctl( ProcInfo.procfd, DCMD_PROC_GETGREG, &regs, sizeof( regs ), &regsize );
        ret->program_counter.offset  = regs.x86.eip;
        ret->program_counter.segment = regs.x86.cs;
        ret->stack_pointer.offset  = regs.x86.esp;
        ret->stack_pointer.segment = regs.x86.ss;

        /* If debuggee has dynamic section, try getting the r_debug struct
         * every time the debuggee stops. The r_debug data may not be available
         * immediately after the debuggee process loads.
         */
        if( !ProcInfo.have_rdebug && ProcInfo.dynsec_va ) {
            if( setup_rdebug() ) {
                ret->conditions |= COND_LIBRARIES;
            }
        }
    }
    dbg_print(( "stopped at %04x:%08x because of %x\n", ret->program_counter.segment, 
               (unsigned)ret->program_counter.offset, ret->conditions ));

    // Note: Some trap files always set COND_CONFIG here. This should only be
    // necessary if we were switching between 32-bit and 16-bit code and the like.
    // It should not be needed for QNX Neutrino.
    CONV_LE_32( ret->stack_pointer.offset );
    CONV_LE_16( ret->stack_pointer.segment );
    CONV_LE_32( ret->program_counter.offset );
    CONV_LE_16( ret->program_counter.segment );
    CONV_LE_16( ret->conditions );
    return( sizeof( *ret ) );
}


unsigned ReqProg_step( void )
{
    return( ProgRun( TRUE ) );
}


unsigned ReqProg_go( void )
{
    return( ProgRun( FALSE ) );
}


unsigned ReqRedirect_stdin( void  )
{
    redirect_stdin_ret *ret;

    // TODO: implement if possible
    ret = GetOutPtr( 0 );
    ret->err = 1;
    CONV_LE_32( ret->err );
    return( sizeof( *ret ) );
}


unsigned ReqRedirect_stdout( void  )
{
    redirect_stdout_ret *ret;

    // TODO: implement if possible
    ret = GetOutPtr( 0 );
    ret->err = 1;
    CONV_LE_32( ret->err );
    return( sizeof( *ret ) );
}


unsigned ReqFile_string_to_fullpath( void )
{
    pid_t              pid;
    bool               exe;
    int                len;
    char               *name;
    char               *fullname;
    file_string_to_fullpath_req *acc;
    file_string_to_fullpath_ret *ret;

/*     -- convert string in acc->name to full path (searchpath style)
 *        in acc->info (MAXIMUM len acc->info_len).
 */
    pid  = 0;
    acc  = GetInPtr( 0 );
    name = GetInPtr( sizeof( *acc ) );
    ret  = GetOutPtr( 0 );
    fullname = GetOutPtr( sizeof( *ret ) );
    exe = ( acc->file_type == TF_TYPE_EXE ) ? TRUE : FALSE;
    if( exe ) {
        pid = RunningProc( name, &name );
    }
    if( pid != 0 ) {
        /* We aren't told how big the output buffer is! */
        len = pid_to_name( pid, fullname, 512 );
        dbg_print(( "pid %d -> name '%s'\n", pid, name ));
    } else {
        len = FindFilePath( exe, name, fullname );
    }
    if( len == 0 ) {
        ret->err = ENOENT;      /* File not found */
    } else {
        ret->err = 0;
    }
    CONV_LE_32( ret->err );
    return( sizeof( *ret ) + len + 1 );
}


unsigned ReqGet_message_text( void )
{
    static const char *const ExceptionMsgs[] = {
        "",
        TRP_QNX_hangup,
        TRP_QNX_user_interrupt,
        TRP_QNX_quit,
        TRP_EXC_illegal_instruction,
        TRP_QNX_trap,
        //"I/O trap",
        TRP_QNX_abort,
        TRP_QNX_emt,
        TRP_QNX_floating_point_error,
        TRP_QNX_process_killed,
        TRP_QNX_bus_error,
        TRP_EXC_access_violation,
        TRP_QNX_sys,
        TRP_QNX_broken_pipe,
        TRP_QNX_alarm,
        TRP_QNX_process_termination,
        TRP_QNX_user_signal_1,
        TRP_QNX_user_signal_2,
        TRP_QNX_child_stopped,
        TRP_QNX_power_fail,
        TRP_QNX_winch,
        TRP_QNX_urgent,
        TRP_QNX_poll,
        TRP_QNX_process_stopped,
        "",
        TRP_QNX_process_continued,
        TRP_QNX_device_ready,
        "",
        ""
    };
    get_message_text_ret        *ret;
    char                        *err_txt;

    ret = GetOutPtr( 0 );
    err_txt = GetOutPtr( sizeof( *ret ) );
    if( ProcInfo.fork ) {
        ProcInfo.fork = FALSE;
        strcpy( err_txt, TRP_QNX_PROC_FORK );
        ret->flags = MSG_NEWLINE | MSG_WARNING;
    } else {
        if( ProcInfo.sig == -1 ) {
            err_txt[0] = '\0';
        } else if( ProcInfo.sig > ( (sizeof( ExceptionMsgs ) / sizeof( char * ) - 1) ) ) {
            strcpy( err_txt, TRP_EXC_unknown );
        } else {
            strcpy( err_txt, ExceptionMsgs[ProcInfo.sig] );
        }
        ProcInfo.sig = -1;
        ret->flags = MSG_NEWLINE | MSG_ERROR;
    }
    return( sizeof( *ret ) + strlen( err_txt ) + 1 );
}


unsigned ReqAddr_info( void )
{
    addr_info_req       *acc;
    addr_info_ret       *ret;

    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    ret->is_32 = TRUE;
    return( sizeof( *ret ) );
}


unsigned ReqMachine_data( void )
{
    machine_data_req    *acc;
    machine_data_ret    *ret;
    unsigned_8          *data;
    
    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    data = GetOutPtr( sizeof( *ret ) );
    ret->cache_start = 0;
    ret->cache_end = ~(addr_off)0;
    *data = X86AC_BIG;
    return( sizeof( *ret ) + sizeof( *data ) );
}


unsigned ReqThread_get_next( void )
{
    thread_get_next_req *req;
    thread_get_next_ret *ret;
    procfs_status       status;

    req = GetInPtr( 0 );
    CONV_LE_32( req->thread );
    ret = GetOutPtr( 0 );

    status.tid = req->thread + 1;
    ret->state = 0;
    if( ProcInfo.pid && !ProcInfo.at_end ) {
        if( devctl( ProcInfo.procfd, DCMD_PROC_TIDSTATUS, &status, sizeof( status ), 0 ) != EOK ) {
            dbg_print(( "failed to get thread status (tid %ld)\n", req->thread + 1 ));
            ret->thread = 0;
        } else {
            ret->thread = status.tid;
            ret->state  = status.tid_flags & _NTO_TF_FROZEN ? THREAD_FROZEN : THREAD_THAWED;
        }
    } else {
        /* If the debuggee isn't running, pretend there is one thread */
        ret->thread = req->thread ? 0 : 1;
    }
    dbg_print(( "next thread %ld (in %ld), state %d\n", ret->thread, req->thread, ret->state ));
    CONV_LE_32( ret->thread );
    return( sizeof( *ret ) );
}


unsigned ReqThread_set( void )
{
    thread_set_req      *req;
    thread_set_ret      *ret;
    pthread_t           tid;

    req = GetInPtr( 0 );
    CONV_LE_32( req->thread );
    ret = GetOutPtr( 0 );
    tid = req->thread;
    ret->err = 0;
    ret->old_thread = ProcInfo.tid;
    dbg_print(( "setting thread %d (currently %d)\n", tid, ProcInfo.tid ));
    if( tid ) {
        if( devctl( ProcInfo.procfd, DCMD_PROC_CURTHREAD, &tid, sizeof( tid ), 0 ) != EOK ) {
            dbg_print(( "failed to set current thread to %d\n", tid ));
            ret->err = EINVAL;
        } else {
            ProcInfo.tid = tid;
        }
    }
    CONV_LE_32( ret->old_thread );
    CONV_LE_32( ret->err );
    return( sizeof( *ret ) );
}


unsigned ReqThread_freeze( void )
{
    thread_freeze_req   *req;
    thread_freeze_ret   *ret;
    pthread_t           tid;

    req = GetInPtr( 0 );
    CONV_LE_32( req->thread );
    ret = GetOutPtr( 0 );
    tid = req->thread;
    ret->err = 0;
    dbg_print(( "freezing thread %d\n", tid ));
    if( tid ) {
        /* If debuggee isn't running, do nothing but pretend it worked */
        if( ProcInfo.pid && !ProcInfo.at_end ) {
            if( devctl( ProcInfo.procfd, DCMD_PROC_FREEZETHREAD, &tid, sizeof( tid ), 0 ) != EOK ) {
                dbg_print(( "failed to freeze thread %d\n", tid ));
                ret->err = EINVAL;
            }
        }
    } else {
        ret->err = EINVAL;
    }
    CONV_LE_32( ret->err );
    return( sizeof( *ret ) );
}


unsigned ReqThread_thaw( void )
{
    thread_thaw_req     *req;
    thread_thaw_ret     *ret;
    pthread_t           tid;

    req = GetInPtr( 0 );
    CONV_LE_32( req->thread );
    ret = GetOutPtr( 0 );
    tid = req->thread;
    ret->err = 0;
    dbg_print(( "thawing thread %d\n", tid ));
    if( tid ) {
        /* If debuggee isn't running, do nothing but pretend it worked */
        if( ProcInfo.pid && !ProcInfo.at_end ) {
            if( devctl( ProcInfo.procfd, DCMD_PROC_THAWTHREAD, &tid, sizeof( tid ), 0 ) != EOK ) {
                dbg_print(( "failed to thaw thread %d\n", tid ));
                ret->err = EINVAL;
            }
        }
    } else {
        ret->err = EINVAL;
    }
    CONV_LE_32( ret->err );
    return( sizeof( *ret ) );
}


/* see <sys/state.h> */
static char     *tstate_desc[STATE_MAX] = {
    "DEAD",
    "RUNNING",
    "READY",
    "STOPPED",
    "SEND",
    "RECEIVE",
    "REPLY",
    "STACK",
    "WAITTHREAD",
    "WAITPAGE",
    "SIGSUSPEND",
    "SIGWAITINFO",
    "NANOSLEEP",
    "MUTEX",
    "CONDVAR",
    "JOIN",
    "INTR",
    "SEM",
    "WAITCTX",
    "NET_SEND",
    "NET_REPLY"
};

unsigned ReqThread_get_extra( void )
{
    thread_get_extra_req    *req;
    char                    *ret;
    procfs_status           status;

    req = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    ret[0] = '\0';
    if( req->thread ) {
        status.tid = req->thread;
        if( devctl( ProcInfo.procfd, DCMD_PROC_TIDSTATUS, &status, sizeof( status ), 0 ) != EOK ) {
            dbg_print(( "failed to get extra for thread %ld\n", req->thread ));
            strcpy( ret, "error" );
        } else {
            if( tstate_desc[status.state] ) {
                strcpy( ret, tstate_desc[status.state] );
            } else {
                strcpy( ret, "unknown" );
            }
        }
    } else {
        strcpy( ret, "QNX Thread State" );
    }
    return( strlen( ret ) + 1 );
}


trap_version TRAPENTRY TrapInit( char *parm, char *err, bool remote )
{
    trap_version    ver;
    sigset_t        sig_set;

    parm = parm;
    remote = remote;

    /* We use SIGUSR1 to gain control after blocking wait for a process. */
    sigemptyset( &sig_set );
    sigaddset( &sig_set, SIGUSR1 );
    sigprocmask( SIG_BLOCK, &sig_set, NULL );

    ProcInfo.save_in = -1;
    ProcInfo.save_out = -1;
    ProcInfo.node = ND_LOCAL_NODE;
    strcpy( ProcInfo.procfs_path, "/proc" );
    err[0] = '\0';      /* all ok */
    ver.major = TRAP_MAJOR_VERSION;
    ver.minor = TRAP_MINOR_VERSION;
    ver.remote = FALSE;
    OrigPGrp = getpgrp();
    return( ver );
}


void TRAPENTRY TrapFini( void )
{
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -