示例#1
0
unsigned ExecProg( bool tracing, bool do_flip, bool want_wps )
{
    bool                have_brk_at_ip;
    bool                act_wps;
    bool                first_time;
    mad_trace_how       how;
    execute_state       es;
    unsigned            conditions;
    unsigned            run_conditions;
    bool                already_stopping;
    bool                force_stop;

    if( !want_wps )
        ++InCall;
    tracing = TraceStart( tracing );
    WriteDbgRegs();
    first_time = true;
    es = ES_NORMAL;
    run_conditions = 0;
    if( !HaveRemoteAsync() ) {
        DUIPlayDead( true );
    }
    how = MTRH_STOP;
    for( ;; ) {
        switch( es ) {
        case ES_FORCE_BREAK:
        case ES_NORMAL:
            if( tracing ) {
                how = TraceHow( false );
            } else {
                _SwitchOn( SW_EXECUTE_LONG );
                how = MTRH_BREAK;
            }
            break;
        case ES_STEP_ONE:
            how = TraceHow( true );
            break;
        }
        if( how == MTRH_STOP )
            break;
        switch( how ) {
        case MTRH_BREAK:
            DbgUpdate( UP_CSIP_JUMPED );
            _SwitchOn( SW_TOUCH_SCREEN_BUFF );
            /* fall through */
        case MTRH_SIMULATE:
        case MTRH_STEP:
        case MTRH_STEPBREAK:
            if( _IsOff( SW_TOUCH_SCREEN_BUFF ) )
                break;
            /* fall through */
        default:
            if( !(ScrnState & USR_SCRN_ACTIVE) && do_flip ) {
                DUIStop();
            }
            _SwitchOff( SW_TOUCH_SCREEN_BUFF );
            break;
        }
        if( first_time ) {
            /* got to be down here so that SW_EXECUTE_LONG is properly set */
            SetThreadStates();
            first_time = false;
        }
        have_brk_at_ip = InsertBPs( (es == ES_FORCE_BREAK) );
        act_wps = UpdateWPs();
        if( how == MTRH_BREAK ) {
            if( have_brk_at_ip ) {
                es = ES_STEP_ONE;
                RemoveBPs();
                continue;       /* back to top */
            }
            if( act_wps && want_wps ) {
                InsertWPs();
            }
        }

        SetMemBefore( tracing );
        switch( how ) {
        case MTRH_SIMULATE:
            if( TraceSimulate() ) {
                conditions = COND_TRACE;
                break;
            }
            /* fall through */
        case MTRH_STEP:
            /* only updates stack/execution */
            conditions = DoRun( true );
            break;
        default:
            /* only updates stack/execution */
            conditions = DoRun( false  );
            break;
        }
        if( _IsOn( SW_EXECUTE_LONG ) ) {
            if( ScrnState & DBG_SCRN_ACTIVE ) {
                _SwitchOn( SW_MIGHT_HAVE_LOST_DISPLAY );
            }
            _SwitchOff( SW_EXECUTE_LONG );
        }
        SetMemAfter( tracing );
        run_conditions &= ~COND_WATCH;
        run_conditions |= conditions;

        RemoveBPs();
        if( conditions & COND_MESSAGE ) {
            if( !RecordMsgText( &conditions ) ) {
                conditions &= ~COND_MESSAGE;
            }
        }
        conditions = CheckBPs( conditions, run_conditions );
        if( _IsOn( SW_BREAK_ON_DEBUG_MESSAGE ) && ( conditions & COND_MESSAGE ) ) {
            conditions |= COND_STOP;
        }
        if( HaveRemoteAsync() && (conditions & COND_THREAD ) ) {
            conditions |= COND_STOP;
        }
        if( how == MTRH_STEPBREAK && (conditions & COND_BREAK) && DbgTmpBrk.status.b.hit ) {
            conditions &= ~COND_BREAK;
            conditions |= COND_TRACE;
        }
        if( conditions & COND_LIBRARIES ) {
            already_stopping = ( conditions & COND_STOPPERS ) != 0;
            conditions &= ~COND_LIBRARIES;
            force_stop = false;
            if( AddLibInfo( already_stopping, &force_stop ) ) {
                if( force_stop || DLLMatch() ) {
                    conditions |= COND_STOP | COND_LIBRARIES;
                }
            }
            ReMapPoints( NULL );
        }
        if( conditions & COND_SECTIONS ) {
            SectTblRead( DbgRegs );
            InvalidateTblCache();
        }
        if( (es == ES_STEP_ONE) && (conditions & COND_TRACE) ) {
            conditions &= ~COND_TRACE;
        }
        if( tracing ) {
            conditions = TraceCheck( conditions );
        }
        if( !(conditions & COND_STOPPERS) && TBreak() ) {
            conditions |= COND_USER;
            break;
        }
        if( conditions & COND_STOPPERS )
            break;
        switch( es ) {
        case ES_STEP_ONE:
            es = ES_FORCE_BREAK;
            break;
        case ES_FORCE_BREAK:
            es = ES_NORMAL;
            break;
        }
        if( (run_conditions & COND_WATCH) && es == ES_NORMAL ) {
            /*
                We got a spurious watch point indication. Make the
                next instruction single step since we might be
                dealing with a control flow opcode on a machine without
                a T-bit (e.g. Alpha).
            */
            es = ES_STEP_ONE;
        }
    }
    TraceStop( tracing );
    DUIPlayDead( false );
    SetProgState( run_conditions );
    _SwitchOff( SW_KNOW_EMULATOR );
    if( !want_wps )
        --InCall;
    return( conditions );
}
示例#2
0
unsigned CheckBPs( unsigned conditions, unsigned run_conditions )
{
    brkp                *bp;
    item_mach           item;
    bool                hit, bphit, wphit;
    bool                state_set;
    mad_type_info       mti;

    wphit = false;
    state_set = false;
    bphit = false;
    for( bp = BrkList; bp != NULL; bp = bp->next ) {
        if( !bp->status.b.active )
            continue;
        hit = false;
        if( IS_BP_EXECUTE( bp->th ) ) {
            if( HaveHitBP( bp ) ) {
                hit = true;
            }
        } else {
            if( SectIsLoaded( bp->loc.addr.sect_id, OVL_MAP_EXE ) ) {
                MADTypeInfo( bp->th, &mti );
                if( ItemGetMAD( &bp->loc.addr, &item, IT_NIL, bp->th ) ) {
                    
                    /*
                     * If the breakpoint fires here because of a write, but the value hasn't changed then
                     * the breakpoint does not fire off!!!! The SupportsExactBreakpoints actually enables
                     * break on write, not break on change and allocates the exact data space - not plus
                     * or minus a few bytes...
                     *
                     */
                    
                    if( _IsOn( SW_BREAK_ON_WRITE ) && IsExactBreakpointsSupported() ) {

                        bool    drop_hit = false;
                        
                        if( ( UserTmpBrk.status.b.active ) || ( DbgTmpBrk.status.b.active ) ) {
                        
                            if( HaveHitBP( &UserTmpBrk ) ) {
                                drop_hit = true;
                            }
                            if( HaveHitBP( &DbgTmpBrk ) ) {
                                drop_hit = true;
                            }
                            if( ! ( conditions & ( COND_BREAK | COND_WATCH | COND_TRACE | COND_USER | COND_EXCEPTION | COND_STOP ) ) ) {
                                drop_hit = true;
                            }
                        }
                        
                        if( !drop_hit ) 
                            hit = true;
                    } else {
                        if( ( memcmp( &bp->item, &item, mti.b.bits / BITS_PER_BYTE ) != 0 ) || !bp->status.b.has_value ) {
                            hit = true;
                        }
                    }
                } else if( bp->status.b.has_value ) {
                    if( conditions & ( COND_BREAK | COND_WATCH | COND_TRACE | COND_USER | COND_EXCEPTION | COND_STOP ) ) {
                        hit = true;
                    }
                }
            }
        }
        if( hit ) {
            bp->total_hits++;
        }
        if( hit && bp->condition != NULL && bp->status.b.use_condition ) {
            _SwitchOn( SW_ERR_IN_TXTBUFF );
            if( !state_set ) {
                /* gets all the registers updated */
                SetProgState( run_conditions );
                state_set = true;
            }
            if( SpawnP( TestExpression, bp ) == 0 ) {
                if( !bp->status.b.expr_true ) {
                    hit = false;
                } else {
                    bp->status.b.expr_true = false;
                }
            } else {
                bp->status.b.expr_error = true;
                bp->error = DupStr( TxtBuff );
                hit = true;
            }
            _SwitchOff( SW_ERR_IN_TXTBUFF );
        }

        if( hit && bp->status.b.use_countdown && bp->countdown != 0 && !bp->status.b.expr_error ) {
            if( --bp->countdown != 0 ) {
                hit = false;
            }
        }
        if( hit ) {
            if( IS_BP_EXECUTE( bp->th ) ) {
                bphit = true;
            } else {
                wphit = true;
            }
            bp->status.b.hit = true;
        }
    }
    if( state_set ) {
        /* we might have changed a register in eval'ing conditions */
        WriteDbgRegs();
    }
    if( HaveHitBP( &UserTmpBrk ) ) {
        bphit = true;
        UserTmpBrk.status.b.hit = true;
    }
    if( HaveHitBP( &DbgTmpBrk ) ) {
        bphit = true;
        DbgTmpBrk.status.b.hit = true;
    }
    if( bphit )
        return( COND_BREAK | ( conditions & ~COND_STOPPERS ) );
    if( wphit )
        return( COND_WATCH | ( conditions & ~COND_STOPPERS ) );
    if( conditions & COND_BREAK ) {
        unsigned        max = TXT_LEN;

        ReadDbgRegs();
        if( MADUnexpectedBreak( &DbgRegs->mr, TxtBuff, &max ) == MS_OK ) {
            WriteDbgRegs();
            if( max == 0 ) {
                conditions &= ~COND_STOPPERS;
                if( _IsOff( SW_CONTINUE_UNEXPECTED_BREAK ) ) {
                    conditions |= COND_TRACE;
                }
                return( conditions );
            } else if( SetMsgText( TxtBuff, &conditions ) ) {
                DUIMsgBox( TxtBuff );
                return( COND_TRACE | COND_MESSAGE | ( conditions & ~COND_STOPPERS ) );
            } else {
                return( conditions & ~COND_STOPPERS );
            }
        } else {
            return( conditions & ~COND_STOPPERS );
        }
    } else if( conditions & COND_WATCH ) {
        return( conditions & ~COND_STOPPERS );
    }
    return( conditions );
}