dbgmisc.c

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

C
744
字号
/*
 * ProcSkip -- process skip command
 */

void ProcSkip( void )
{
    address    start;

    ReqMemAddr( EXPR_GIVEN, &start );
    ReqEOC();
    SkipToAddr( start );
}

/*
 * ProcIf -- process if command
 */

void ProcIf( void )
{
    char                *start;
    unsigned            len;
    char                *true_start;
    unsigned            true_len;
    unsigned_64         res;
    cmd_list            *cmd;
    bool                have_true;

    true_len = 0;
    have_true = FALSE;
    for( ;; ) {
        if( have_true ) {
            ChkExpr();
            U64Clear( res );
        } else {
            res = ReqU64Expr();
        }
        if( !ScanQuote( &start, &len ) ) {
            Error( ERR_LOC, LIT( ERR_WANT_COMMAND_LIST ) );
        }
        if( U64Test( &res ) != 0 ) {
            true_start = start;
            true_len   = len;
            have_true  = TRUE;
        }
        if( ScanCmd( ElseifTab ) == 0 ) break;
    }
    ScanCmd( ElseTab ); /* optional else */
    if( ScanQuote( &start, &len ) && !have_true ) {
        true_start = start;
        true_len   = len;
    }
    ReqEOC();
    if( true_len != 0 ) {
        cmd = AllocCmdList( true_start, true_len );
        PushCmdList( cmd );
        CopyInpFlags();
        FreeCmdList( cmd );
    }
}



/*
 * ProcWhile -- process While command
 */

void ProcWhile( void )
{
    char                *start;
    unsigned            len;
    unsigned_64         res;
    cmd_list            *cmd;

    res = ReqU64Expr();
    if( !ScanQuote( &start, &len ) || len == 0 ) {
        Error( ERR_LOC, LIT( ERR_WANT_COMMAND_LIST ) );
    }
    ReqEOC();
    if( U64Test( &res ) != 0 ) {
        cmd = AllocCmdList( start, len );
        ReScan( CmdStart );
        PushCmdList( cmd );
        CopyInpFlags();
        FreeCmdList( cmd );
    }
}


/*
 * ProcError -- proccess error command
 */

void ProcError( void )
{
    char        *start;
    unsigned    len;

    ScanItem( FALSE, &start, &len );
    ReqEOC();
    memcpy( TxtBuff, start, len );
    TxtBuff[ len ] = NULLCHAR;
    Error( ERR_NONE, LIT( ERR_GENERIC ), TxtBuff );
}


/*
 * ProcQuit -- process quit command
 */

void ProcQuit( void )
{
    ReqEOC();
    DebugExit();
}

/*
 * ProcThread -- process thread command
 */
enum thread_cmds { T_BAD, T_SHOW, T_FREEZE, T_THAW, T_CHANGE };

static void FormThdState( thread_state *thd, char *buff )
{
    char *p;

    buff = CnvULongHex( thd->tid, buff );
    *buff++ = ' ';
    *buff++ = ' ';
    switch( thd->state ) {
    case THD_THAW:  p = LIT( Runnable ); break;
    case THD_FREEZE:p = LIT( Frozen );   break;
    case THD_DEAD:  p = LIT( Dead );     break;
    }
    p = StrCopy( p, buff );
    while( (p - buff) < 10 ) *p++ = ' ';
    StrCopy( thd->name, p );
}


void MakeThdCurr( thread_state *thd )
{
    unsigned    err;

    if( !AdvMachState( ACTION_THREAD_CHANGE ) ) return;
    // NYI - PUI - record the thread change?
    WriteDbgRegs();
    if( RemoteSetThreadWithErr( thd->tid, &err ) == 0 ) {
        Error( ERR_NONE, LIT( ERR_NO_MAKE_CURR_THREAD ), thd->tid, err );
    }
    DbgRegs->tid = thd->tid;
    ReadDbgRegs();
    SetCodeDot( GetRegIP() );
    DbgUpdate( UP_REG_CHANGE | UP_CSIP_CHANGE | UP_THREAD_STATE );
}


static void ThdCmd( thread_state *thd, enum thread_cmds cmd )
{
    unsigned    up;

    up = UP_THREAD_STATE;
    switch( cmd ) {
    case T_SHOW:
        FormThdState( thd, TxtBuff );
        DUIDlgTxt( TxtBuff );
        up = UP_NO_CHANGE;
        break;
    case T_FREEZE:
        if( thd->state == THD_THAW ) thd->state = THD_FREEZE;
        break;
    case T_THAW:
        if( thd->state == THD_FREEZE ) thd->state = THD_THAW;
        break;
    case T_CHANGE:
        MakeThdCurr( thd );
        break;
    }
    DbgUpdate( up );
}


bool IsThdCurr( thread_state *thd )
{
    return( DbgRegs->tid == thd->tid );
}


static thread_state     *AddThread( dtid_t tid, unsigned state )
{
    thread_state    **owner;
    thread_state    *thd;
    char            name[UTIL_LEN];

    owner =  &HeadThd;
    for( ;; ) {
        thd = *owner;
        if( thd == NULL ) break;
        if( tid < thd->tid ) break;
        if( tid == thd->tid ) {
            if( _IsOn( SW_THREAD_EXTRA_CHANGED ) ) {
                *owner = thd->link;
                state = thd->state & ~THD_DEAD;
                _Free( thd );
                break;
            }
            thd->state &= ~THD_DEAD;
            return( thd );
        }
        owner = &thd->link;
    }
    RemoteThdName( tid, name );
    _Alloc( thd, sizeof( thread_state ) + strlen( name ) );
    if( thd == NULL ) return( NULL );
    thd->link = *owner;
    *owner = thd;
    strcpy( thd->name, name );
    thd->tid = tid;
    thd->state = state;
    return( thd );
}


dtid_t GetNextTID( void )
/***********************/
{
    thread_state    *thd;

    for( thd = HeadThd; thd != NULL; thd = thd->link ) {
    if( IsThdCurr( thd ) ) {
        thd = thd -> link;
        break;
    }
    }
    if( thd == NULL ) thd = HeadThd;
    if( thd == NULL ) return( 0 );
    return( thd->tid );
}


void NameThread( dtid_t tid, char *name )
/***************************************/
{
    thread_state        **owner, *curr, *new;

    for( owner = &HeadThd; *owner != NULL; owner = &curr->link ) {
        curr = *owner;
        if( curr->tid == tid ) {
            _Alloc( new, sizeof( thread_state ) + strlen( name ) );
            *new = *curr;
            *owner = new;
            strcpy( new->name, name );
            DbgUpdate( UP_THREAD_STATE );
            _Free( curr );
            break;
        }
    }
}

static void MarkThreadsDead( void )
{
    thread_state    *thd;

    for( thd = HeadThd; thd != NULL; thd = thd->link ) {
        thd->state |= THD_DEAD;
    }
}

static void KillDeadThreads( void )
{
    thread_state    **owner;
    thread_state    *thd;

    owner = &HeadThd;
    for( ;; ) {
        thd = *owner;
        if( thd == NULL ) break;
        if( thd->state & THD_DEAD ) {
            *owner = thd->link;
            _Free( thd );
        } else {
            owner = &thd->link;
        }
    }
}

void CheckForNewThreads( bool set_exec )
{
    dtid_t              tid;
    thread_state        *thd;
    unsigned            state;

    if( set_exec ) ExecThd = NULL;
    tid = 0;
    MarkThreadsDead();
    for( ;; ) {
        tid = RemoteGetNextThread( tid, &state );
        if( tid == 0 ) break;
        thd = AddThread( tid, state );
        if( set_exec && thd != NULL && thd->tid == DbgRegs->tid ) ExecThd = thd;
    }
    KillDeadThreads();
    _SwitchOff( SW_THREAD_EXTRA_CHANGED );
}


thread_state   *FindThread( dtid_t tid )
{
    thread_state    *thd;

    for( thd = HeadThd; thd != NULL && thd->tid != tid; thd = thd->link )
        ;
    return( thd );
}


void ProcThread( void )
{
    enum thread_cmds cmd;
    dtid_t          tid;
    bool            all;
    thread_state    *thd;
    unsigned            old;

    cmd = T_BAD;
    if( CurrToken == T_DIV ) {
        Scan();
        cmd = ScanCmd( ThreadOps );
        if( cmd == T_BAD ) Error( ERR_NONE, LIT( ERR_BAD_OPTION ), GetCmdName( CMD_THREAD ) );
    }
    CheckForNewThreads( FALSE );
    if( CurrToken == T_MUL ) {
        if( cmd == T_BAD ) cmd = T_SHOW;
        Scan();
        all = TRUE;
    } else if( ScanEOC() ) {
        if( cmd == T_BAD ) cmd = T_SHOW;
        if( cmd == T_SHOW ) {
            all = TRUE;
        } else {
            tid = DbgRegs->tid;
            all = FALSE;
        }
    } else {
        if( cmd == T_BAD ) cmd = T_CHANGE;
        old = SetCurrRadix( 16 );
        tid = ReqExpr();
        all = FALSE;
        SetCurrRadix( old );
    }
    ReqEOC();
    if( all ) {
        if( cmd == T_CHANGE ) Error( ERR_NONE, LIT( ERR_CANT_SET_ALL_THREADS ) );
        for( thd = HeadThd; thd != NULL; thd = thd->link ) {
            ThdCmd( thd, cmd );
        }
    } else {
        thd = FindThread( tid );
        if( thd == NULL ) Error( ERR_NONE, LIT( ERR_NO_SUCH_THREAD ), tid );
        ThdCmd( thd, cmd );
    }
}

void FreeThreads( void )
{
    thread_state    *thd;

    while( HeadThd != NULL ) {
        thd = HeadThd->link;
        _Free( HeadThd );
        HeadThd = thd;
    }
}

⌨️ 快捷键说明

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