dbgbrk.c

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

C
1,847
字号
                p = StrVal( LIT( NewVal ), bp, p );
                *p = NULLCHAR;
            } else {
                p = GetBPAddrText( bp, TxtBuff );
            }
            DUIInfoBox( TxtBuff );
        }
        if( stack_cmds && bp->status.b.resume ) {
            cmds = AllocCmdList( "go/keep", sizeof( "go/keep" ) );
            PushCmdList( cmds );
            TypeInpStack( INP_HOOK );
            FreeCmdList( cmds );
            ret = TRUE;
        }
        if( stack_cmds && (bp->cmds != NULL) && bp->status.b.use_cmds ) {
            bp->status.b.cmds_pushed = TRUE;
            PushCmdList( bp->cmds );
            TypeInpStack( INP_BREAK_POINT );
            ret = TRUE;
        }
    }
    for( bp = BrkList; bp != NULL; bp = next ) {
        next = bp->next;
        if( bp->status.b.autodestruct ) {
            DUIRemoveBreak( bp );
        }
    }
    if( UserTmpBrk.status.b.hit ) {
        p = Format( TxtBuff, LIT( Break_on_execute ) );
        Format( p, BrkFmt(), UserTmpBrk.loc.addr );
        DUIDlgTxt( TxtBuff );
    }
    return( ret );
}


static char *GetBPCmd( brk *bp, char *p, brk_event event )
{
    char        *cmds;
    char        *cond;

    cmds = cond = LIT( Empty );
    if( bp != NULL ) {
        if( bp->cmds != NULL ) cmds = bp->cmds->buff;
        if( bp->condition != NULL ) cond = bp->condition;
    }
    p = Format( p, "%s", GetCmdName( CMD_BREAK ) );
    switch( event ) {
    case B_SET:
        *p++ = '/';
        if( bp->th == MAD_NIL_TYPE_HANDLE ) {
            p = GetCmdEntry( PointNameTab, B_SET, p );
        } else {
            p += GetMADTypeNameForCmd( bp->th, ~0, p );
            *p++ = ' ';
        }
        if( bp->status.b.resume ) {
            *p++ = '/';
            p = GetCmdEntry( PointNameTab, B_RESUME, p );
        }
        if( !bp->status.b.active ) {
            *p++ = '/';
            p = GetCmdEntry( PointNameTab, B_DEACTIVATE, p );
        }
        *p++ = ' ';
        *p++ = '/';
        p = GetCmdEntry( PointNameTab, B_INDEX, p );
        p = Format( p, " %d, ", bp->index );
        if( bp->loc.image_name != NULL ) {
            *p++ = '/';
            p = GetCmdEntry( PointNameTab, B_UNMAPPED, p );
            *p++ = ' ';
            *p++ = '/';
            p = GetCmdEntry( PointNameTab, B_MAPADDRESS, p );
            *p++ = ' ';
            p = StrCopy( bp->loc.image_name, p );
            *p++ = ' ';
            p = AddHexSpec( p );
            p = CnvULongHex( bp->loc.addr.mach.segment, p );
            *p++ = ' ';
            p = AddHexSpec( p );
            p = CnvULongHex( bp->loc.addr.mach.offset, p );
            *p++ = ',';
        } else if( bp->image_name != NULL && bp->mod_name != NULL ) {
            *p++ = '/';
            p = GetCmdEntry( PointNameTab, B_UNMAPPED, p );
            *p++ = ' ';
            *p++ = '/';
            p = GetCmdEntry( PointNameTab, B_SYMADDRESS, p );
            *p++ = ' ';
            p = StrCopy( bp->image_name, p );
            *p++ = ' ';
            p = StrCopy( bp->mod_name, p );
            *p++ = ' ';
            p = StrCopy( bp->sym_name, p );
            *p++ = ' ';
            p = AddHexSpec( p );
            p = CnvULongHex( bp->cue_diff, p );
            *p++ = ' ';
            p = AddHexSpec( p );
            p = CnvULongHex( bp->addr_diff, p );
            *p++ = ',';
        } else {
            p = AddrToString( &bp->loc.addr, MAF_FULL, p, TXT_LEN );
//          p = Format( p, " %A", bp->loc.addr );
        }
        p = Format( p, " {%s} {%s}", cmds, cond );
        if( bp->initial_countdown != 0 ) {
            p = StrCopy( " ", p );
            p = AddHexSpec( p );
            p = CnvULongHex( bp->initial_countdown, p );
        }
        return( p );
    case B_CLEAR:
    case B_ACTIVATE:
    case B_DEACTIVATE:
    case B_RESUME:
    case B_UNRESUME:
        *p++ = '/';
        p = GetCmdEntry( PointNameTab, event, p );
        if( bp == NULL ) {
            p = StrCopy( "*", p );
        } else {
            p = AddrToString( &bp->loc.addr, MAF_FULL, p, TXT_LEN );
//          p = Format( p, " %A", bp->loc.addr );
        }
        return( p );
    }
    return( NULL );
}


static void RecordBreakEvent( brk *bp, brk_event event )
{
    GetBPCmd( bp, TxtBuff, event );
    RecordEvent( TxtBuff );
    if( event == B_SET && !IS_NIL_ADDR( bp->loc.addr ) ) {
        GetBPAddrText( bp, TxtBuff );
        DUIStatusText( TxtBuff );
    }
}


static void DoActPoint( brk *bp, bool act )
{
    bp->status.b.active = act;
    RecordBreakEvent( bp, act ? B_ACTIVATE : B_DEACTIVATE );
    if( act && bp->th != MAD_NIL_TYPE_HANDLE ) {
        GetWPVal( bp );
    }
}

void ActPoint( brk *bp, bool act )
{
    if( act && bp->status.b.unmapped ) return;
    DoActPoint( bp, act );
    DbgUpdate( UP_BREAK_CHANGE );
}

void BrkEnableAll( void )
{
    brk         *bp;

    for( bp = BrkList; bp != NULL; bp = bp->next ) {
        DoActPoint( bp, TRUE );
    }
    DbgUpdate( UP_BREAK_CHANGE );
}


void BrkDisableAll( void )
{
    brk     *bp;

    for( bp = BrkList; bp != NULL; bp = bp->next ) {
        DoActPoint( bp, FALSE );
    }
    DbgUpdate( UP_BREAK_CHANGE );
}


void RemovePoint( brk *bp )
{
    brk         **owner;

    for( owner = &BrkList; ; owner = &(*owner)->next ) {
        if( (*owner) == bp ) {
            RecordBreakEvent( bp, B_CLEAR );
            FreeCmdList( bp->cmds );
            _Free( bp->condition );
            _Free( bp->source_line );
            _Free( bp->image_name );
            _Free( bp->mod_name );
            _Free( bp->sym_name );
            *owner = bp->next;
            DbgUpdate( UP_BREAK_CHANGE );
            FiniMappableAddr( &bp->loc );
            _Free( bp );
            break;
        }
    }
}


bool RemoveBreak( address addr )
{
    brk         *bp;

    bp = FindBreak( addr );
    if( bp == NULL ) return( FALSE );
    RemovePoint( bp );
    return( TRUE );
}


void BrkClearAll( void )
{
    while( BrkList != NULL ) {
        RemoveBreak( BrkList->loc.addr );
    }
}


/*
 * BPsDeac -- deactivate all breakpoints
 */

void BPsDeac( void )
{
    brk     *bp;

    for( bp = BrkList; bp != NULL; bp = bp->next ) {
        DoActPoint( bp, FALSE );
    }
    DbgUpdate( UP_BREAK_CHANGE );
    NullStatus( &UserTmpBrk );
    NullStatus( &DbgTmpBrk );
}


/*
 * BPsUnHit -- turn off all BP_HIT indicators
 */

void BPsUnHit( void )
{
    brk     *bp;

    for( bp = BrkList; bp != NULL; bp = bp->next ) {
        bp->status.b.hit = FALSE;
    }
    NullStatus( &UserTmpBrk );
    NullStatus( &DbgTmpBrk );
}


void RecordNewPoint( brk *bp )
{
    SetRecord( TRUE );
    RecordBreakEvent( bp, B_SET );
}


void RecordPointStart( void )
{
    brk *bp;

    for( bp = BrkList; bp != NULL; bp = bp->next ) {
        RecordNewPoint( bp );
    }
}


void RecordClearPoint( brk *bp )
{
    SetRecord( TRUE );
    RecordBreakEvent( bp, B_CLEAR );
}


void GetBreakOnImageCmd( char *name, char *buff, bool clear )
{
    char        *p;

    p = Format( buff, "%s", GetCmdName( CMD_BREAK ) );
    *p++ = '/';
    p = GetCmdEntry( PointNameTab, B_IMAGE, p );
    if( clear ) {
        *p++ = '/';
        p = GetCmdEntry( PointNameTab, B_CLEAR, p );
    }
    *p++ = ' ';
    p = StrCopy( name, p );
}


void ShowBPs( void )
{
    brk         *bp;
    char_ring   *dll;

    for( bp = BrkList; bp != NULL; bp = bp->next ) {
        GetBPCmd( bp, TxtBuff, B_SET );
        DUIDlgTxt( TxtBuff );
    }
    for( dll = DLLList; dll != NULL; dll = dll->next ) {
        GetBreakOnImageCmd( dll->name, TxtBuff, FALSE );
        DUIDlgTxt( TxtBuff );
    }
}


/*
 * ProcBreak -- process break command
 */

static void DoProcBreak( void )
{
    int         cmd;

    if( CurrToken == T_DIV ) {
        Scan();
        cmd = ScanCmd( &PointNameTab );
        BPJmpTab[ cmd ].rtn( BPJmpTab[ cmd ].type );
    } else if( ScanEOC() ) {
        ShowBPs();
    } else {
        SetBreak( EXPR_CODE );
    }
}

void ProcBreak( void )
{
    DoProcBreak();
}

/*
 * SetBreak -- set a break point
 */

OVL_EXTERN brk *SetBreak( memory_expr def_seg )
{
    return( SetPoint( def_seg, MAD_NIL_TYPE_HANDLE ) );
}

OVL_EXTERN brk *TypePoint( memory_expr def_seg )
{
    mad_type_handle     th;

    th = ScanType( MAS_MEMORY | MTK_ALL, NULL );
    if( th == MAD_NIL_TYPE_HANDLE ) {
        BadPoint( def_seg );
    }
    return( SetPoint( def_seg, th ) );
}


OVL_EXTERN brk *SetWatch( memory_expr def_seg )
{
    return( SetPoint( def_seg, MADTypeDefault( MTK_INTEGER, 0, &DbgRegs->mr, NULL ) ) );
}


/*
 * BadPoint -- handle bad break point command
 */

OVL_EXTERN brk *BadPoint( memory_expr def_seg )
{
    def_seg=def_seg;
    Error( ERR_LOC, LIT( ERR_BAD_OPTION ), GetCmdName( CMD_BREAK ) );
    return( NULL );
}


/*
 * ImageBreak -- break on image loaded
 */

OVL_EXTERN brk *ImageBreak( memory_expr def_seg )
{
    char        *start;
    unsigned    len;
    bool        clear = FALSE;

    def_seg=def_seg;
    while( CurrToken == T_DIV ) {
        Scan();
        switch( ScanCmd( &PointNameTab ) ) {
        case 0:
            goto done;
        case B_CLEAR:
            clear = TRUE;
            break;
        default:
            Error( ERR_LOC, LIT( ERR_BAD_OPTION ), GetCmdName( CMD_BREAK ) );
            break;
        }
    }
done:;
    if( !ScanItem( TRUE, &start, &len ) ) {
        BadPoint( def_seg );
    }
    BreakOnImageLoad( start, len, clear );
    Scan();
    ReqEOC();
    return( NULL );
}


/*
 * PointBreak -- get 'brk *' from command line
 */

static brk *PointBreak( memory_expr def_seg, address *addr )
{
    unsigned   index;
    brk         *bp;
    unsigned    old;

    if( addr != NULL ) {
        *addr = NilAddr;
    }
    if( CurrToken == T_SHARP ) {
        Scan();
        old = NewCurrRadix( 10 );
        index = ReqExpr(); // always decimal
        NewCurrRadix( old );
        for( bp = BrkList; bp != NULL; bp = bp->next ) {
            if( bp->index == index ) break;
        }
    } else {
        ReqMemAddr( def_seg, addr );
        for( bp = BrkList; bp != NULL; bp = bp->next ) {
            if( AddrComp( bp->loc.addr, *addr ) == 0 ) break;
        }
    }
    ReqEOC();
    if( bp != NULL && addr != NULL ) {
        *addr = bp->loc.addr;
    }
    return( bp );
}


static brk *BPNotNull( brk *bp )
{
    if( bp == NULL ) {
        Error( ERR_NONE, LIT( ERR_NO_SUCH_POINT ) );
    }
    return( bp );
}

static void ResPoint( brk *bp, bool res )
{
    bp->status.b.resume = res;
    RecordBreakEvent( bp, res ? B_RESUME : B_UNRESUME );
}

/*
 * Ac_DeacPoint -- (un)resume (de)activate specified break point
 */

⌨️ 快捷键说明

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