dbgbrk.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,847 行 · 第 1/4 页
C
1,847 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Breakpoint and watchpoint management.
*
****************************************************************************/
#include <string.h>
#include "dbgdefn.h"
#include "dbgtoken.h"
#include "dbgerr.h"
#include "dbginfo.h"
#include "dbgbreak.h"
#include "dbgitem.h"
#include "dbglit.h"
#include "dbgmem.h"
#include "dbgtoggl.h"
#include "dbginp.h"
#include "namelist.h"
#include "dbgstk.h"
#include "dbgrep.h"
#include "dbgreg.h"
#include "dbgio.h"
#include "trpcore.h"
#include "mad.h"
#include "dui.h"
#include "spawn.h"
#include "enterdb.h"
extern cue_file_id CueFileId( cue_handle * );
extern unsigned CueFile( cue_handle *ch, char *file, unsigned max );
extern unsigned long CueLine( cue_handle *ch );
extern unsigned long ReqLongExpr( void );
extern unsigned int ReqExpr( void );
extern char *ReScan( char * );
extern void ReqMemAddr( memory_expr, address * );
extern bool ScanQuote( char **, unsigned int * );
extern bool ScanEOC( void );
extern int AddrComp( address, address );
extern unsigned int ScanCmd( char * );
extern void ReqEOC( void );
extern void Scan( void );
extern cmd_list *AllocCmdList( char *, unsigned int );
extern void FreeCmdList( cmd_list * );
extern void PushCmdList( cmd_list * );
extern address GetRegIP( void );
extern int SectIsLoaded( unsigned int, int );
extern dword RemoteSetBreak( address );
extern void RemoteRestoreBreak( address, dword );
OVL_EXTERN brk *TypePoint( memory_expr );
OVL_EXTERN brk *BadPoint( memory_expr );
OVL_EXTERN brk *ImageBreak( memory_expr );
OVL_EXTERN brk *ActivatePoint( memory_expr );
OVL_EXTERN brk *ClearPoint( memory_expr );
OVL_EXTERN brk *TogglePoint( memory_expr );
OVL_EXTERN brk *ResumePoint( memory_expr );
OVL_EXTERN brk *UnResumePoint( memory_expr );
OVL_EXTERN brk *DeactivatePoint( memory_expr );
OVL_EXTERN brk *SetBreak( memory_expr );
OVL_EXTERN brk *SetWatch( memory_expr );
OVL_EXTERN brk *SetPoint( memory_expr def_seg, mad_type_handle );
extern bool RemoteSetWatch( address, unsigned, unsigned long * );
extern void RemoteRestoreWatch( address, unsigned );
extern void ErrorBox( char * );
extern bool DlgBreak( address );
extern void SetProgState( unsigned );
extern void TypeInpStack( input_type );
extern char *DupStr( char * );
extern char *DupStrLen( char const *str, unsigned len );
extern bool CheckBPIns( void );
extern char *GetCmdEntry( char *, int, char * );
extern char *Format( char *buff, char *fmt, ... );
extern void InvokeAFile( char * );
extern void CreateInvokeFile( char *name, void (*rtn)( void ) );
extern void UnAsm( address addr, unsigned, char *buff );
extern char *AddHexSpec( char * );
extern char *GetCmdName( int );
extern bool DlgAreYouNuts( unsigned long );
extern inspect_type WndGetExprSPInspectType( address *paddr );
extern char *StrCopy( char *, char * );
extern void RecordEvent( char *p );
extern void SetRecord( bool on );
extern unsigned DefaultSize( default_kind );
extern void ReadDbgRegs( void );
extern void WriteDbgRegs( void );
extern bool SetMsgText( char *, unsigned * );
extern unsigned GetMADTypeNameForCmd( mad_type_handle th, unsigned max, char *p );
extern mad_type_handle ScanType( mad_type_kind, mad_type_kind * );
extern mad_type_handle FindMADTypeHandle( mad_type_kind tk, unsigned size );
extern char *CnvULongHex( unsigned long value, char *p );
extern unsigned NewCurrRadix( unsigned );
extern void WriteDbgRegs( void );
extern void BreakOnImageLoad( char *name, unsigned len, bool clear );
extern bool ScanItem( bool blank_delim, char **start, unsigned *len );
extern void InitMappableAddr( mappable_addr *loc );
extern void FiniMappableAddr( mappable_addr *loc );
extern void UnMapPoints( image_entry * );
extern void ReMapPoints( image_entry * );
extern char *StrAddr( address *addr, char *buff, unsigned max );
extern image_entry *ImageEntry( mod_handle mh );
extern char *AddrToString( address *a, mad_address_format af, char *p, unsigned );
extern bool DlgScanCodeAddr( char *str, address *value );
extern void DoInput( void );
extern char *CnvNearestAddr( address, char *, unsigned );
extern void DbgUpdate( update_list );
extern bool DUIGetSourceLine( cue_handle *ch, char *buff, unsigned len );
extern void DUIRemoveBreak( brk *bp );
extern void CheckForNewThreads( bool );
extern void LValue(stack_entry *);
extern char_ring *DLLList;
extern unsigned char CurrRadix;
extern brk UserTmpBrk;
extern brk DbgTmpBrk;
extern char *TxtBuff;
extern tokens CurrToken;
extern debug_level DbgLevel;
extern brk *BrkList;
extern address NilAddr;
extern stack_entry *ExprSP;
extern mod_handle CodeAddrMod;
extern machine_state *DbgRegs;
extern system_config SysConfig;
static char PointNameTab[] = {
"Activate\0"
"Clear\0"
"Deactivate\0"
"Set\0"
"Modify\0"
"Toggle\0"
"Resume\0"
"UNResume\0"
"INdex\0"
"IMage\0"
"Unmapped\0"
"MAPaddress\0"
"SYMaddress\0"
};
typedef enum {
B_ACTIVATE = 1,
B_CLEAR,
B_DEACTIVATE,
B_SET,
B_MODIFY,
B_TOGGLE,
B_RESUME,
B_UNRESUME,
B_INDEX,
B_IMAGE,
B_UNMAPPED,
B_MAPADDRESS,
B_SYMADDRESS,
} brk_event;
typedef struct {
brk *(* rtn)(memory_expr);
memory_expr type;
} bpjmptab_type;
static bpjmptab_type BPJmpTab[] = {
{ &TypePoint, EXPR_DATA },
{ &ActivatePoint, EXPR_CODE },
{ &ClearPoint, EXPR_CODE },
{ &DeactivatePoint, EXPR_CODE },
{ &SetBreak, EXPR_CODE },
{ &SetWatch, EXPR_DATA },
{ &TogglePoint, EXPR_CODE },
{ &ResumePoint, EXPR_CODE },
{ &UnResumePoint, EXPR_CODE },
{ &BadPoint, EXPR_DATA },
{ &ImageBreak, EXPR_DATA },
};
static char *BrkFmt( void )
{
return( (DbgLevel != ASM) ? "%l" : "%a" );
}
/*
* InitBPs -- initialize breakpoints
*/
void InitBPs( void )
{
NullStatus( &UserTmpBrk );
NullStatus( &DbgTmpBrk );
BrkList = NULL;
}
/*
* InsertOneBP -- insert one break point into memory
*/
static bool InsertOneBP( brk *bp, bool force )
{
bool at_ip;
at_ip = FALSE;
if( bp->status.b.active ) {
if( !force && AddrComp( bp->loc.addr, GetRegIP() ) == 0 ) {
at_ip = TRUE;
} else if( SectIsLoaded( bp->loc.addr.sect_id, OVL_MAP_EXE ) ) {
bp->status.b.in_place = TRUE;
bp->item.ud = RemoteSetBreak( bp->loc.addr );
}
}
return( at_ip );
}
/*
* InsertBPs -- put break points into memory
*/
bool InsertBPs( bool force )
{
brk *bp;
bool at_ip;
at_ip = FALSE;
for( bp = BrkList; bp != NULL; bp = bp->next ) {
bp->status.b.cmds_pushed = FALSE;
if( bp->th != MAD_NIL_TYPE_HANDLE ) continue;
bp->status.b.in_place = FALSE;
bp->status.b.hit = FALSE;
if( (UserTmpBrk.status.b.active)
&& (AddrComp( UserTmpBrk.loc.addr, bp->loc.addr ) == 0) ) continue;
if( (DbgTmpBrk.status.b.active)
&& (AddrComp( DbgTmpBrk.loc.addr, bp->loc.addr ) == 0) ) continue;
at_ip |= InsertOneBP( bp, force );
}
UserTmpBrk.status.b.hit = FALSE;
UserTmpBrk.status.b.in_place = FALSE;
DbgTmpBrk.status.b.hit = FALSE;
DbgTmpBrk.status.b.in_place = FALSE;
if( UserTmpBrk.status.b.active ) {
at_ip |= InsertOneBP( &UserTmpBrk, force );
}
if( DbgTmpBrk.status.b.active
&& ( !UserTmpBrk.status.b.active
|| ( AddrComp( UserTmpBrk.loc.addr, DbgTmpBrk.loc.addr ) != 0 ) ) ) {
at_ip |= InsertOneBP( &DbgTmpBrk, force );
}
return( at_ip );
}
/*
* RemoveOneBP -- remove one breakpoint from memory
*/
static void RemoveOneBP( brk *bp )
{
if( (bp->status.b.in_place) && SectIsLoaded( bp->loc.addr.sect_id, OVL_MAP_EXE ) ) {
RemoteRestoreBreak( bp->loc.addr, bp->item.ud );
}
}
static void RemoveOneWP( brk *bp )
{
mad_type_info mti;
if( (bp->status.b.in_place) && SectIsLoaded(bp->loc.addr.sect_id,OVL_MAP_EXE) ) {
bp->status.b.in_place = FALSE;
MADTypeInfo( bp->th, &mti );
RemoteRestoreWatch( bp->loc.addr, mti.b.bits / BITS_PER_BYTE );
}
}
/*
* RemoveBPs -- remove breakpoints from memory
*/
void RemoveBPs( void )
{
brk *bp;
for( bp = BrkList; bp != NULL; bp = bp->next ) {
if( bp->th != MAD_NIL_TYPE_HANDLE ) {
RemoveOneWP( bp );
} else {
RemoveOneBP( bp );
}
}
if( UserTmpBrk.status.b.active ) {
RemoveOneBP( &UserTmpBrk );
}
if( DbgTmpBrk.status.b.active ) {
RemoveOneBP( &DbgTmpBrk );
}
}
void GetBPAddr( brk *bp, char *buff )
{
char *p;
if( bp->status.b.unmapped ) {
p = StrCopy( LIT( Image_Not_Loaded ), buff );
if( bp->image_name != NULL ) {
*p++ = '(';
p = StrCopy( bp->image_name, p );
*p++ = ')';
}
} else if( bp->th != MAD_NIL_TYPE_HANDLE && bp->source_line != NULL ) {
p = StrCopy( bp->source_line, buff );
} else {
p = CnvNearestAddr( bp->loc.addr, buff, TXT_LEN );
}
StrCopy( ":", p );
}
void GetBPText( brk *bp, char *buff )
{
unsigned max;
//MAD: might be a different mad then when break set
max = ~0;
if( bp->th == MAD_NIL_TYPE_HANDLE ) {
if( bp->source_line != NULL ) {
strcpy( buff, bp->source_line );
} else {
if( IS_NIL_ADDR( bp->loc.addr ) ) {
strcpy( buff, LIT( Quest_Marks ) );
} else {
UnAsm( bp->loc.addr, max, buff );
}
}
} else {
MADTypeHandleToString( CurrRadix, bp->th, &bp->item, &max, buff );
}
}
extern brk *FindBreakByLine( mod_handle mod, cue_file_id id, unsigned line )
{
brk *bp;
mod_handle brk_mod;
DIPHDL( cue, ch );
for( bp = BrkList; bp != NULL; bp = bp->next ) {
if( DeAliasAddrMod( bp->loc.addr, &brk_mod ) == SR_NONE )continue;
if( brk_mod != mod )continue;
if( DeAliasAddrCue( brk_mod, bp->loc.addr, ch ) == SR_NONE ) continue;
if( CueFileId( ch ) != id ) continue;
if( CueLine( ch ) != line ) continue;
return( bp );
}
return( NULL );
}
extern brk *FindBreak( address addr )
{
brk *bp;
if( IS_NIL_ADDR( addr ) ) return( NULL );
for( bp = BrkList; bp != NULL; bp = bp->next ) {
if( ( AddrComp( bp->loc.addr, addr ) == 0 ) ) {
return( bp );
}
}
return( NULL );
}
/*
* DispBPMsg -- display breakpoints that were hit
*/
static char *StrVal( char *which, brk *wp, char *p )
{
unsigned max;
for( *p++ = ' '; *which != NULLCHAR; *p++ = *which++ ) {}
*p++ = '=';
max = ~0;
MADTypeHandleToString( CurrRadix, wp->th, &wp->item, &max, p );
p += max;
return( p );
}
static char *GetBPAddrText( brk *bp, char *p )
{
if( bp->th != MAD_NIL_TYPE_HANDLE ) {
p = StrCopy( LIT( Break_on_write ), p );
if( bp->source_line != NULL ) {
p = StrCopy( bp->source_line, p );
} else {
p = Format( p, "%a", bp->loc.addr );
}
} else {
p = Format( p, LIT( Break_on_execute ) );
p = Format( p, BrkFmt(), bp->loc.addr );
}
return( p );
}
static void GetWPVal( brk *wp )
{
wp->status.b.has_value = FALSE;
if( ItemGetMAD( &wp->loc.addr, &wp->item, IT_NIL, wp->th ) ) {
wp->status.b.has_value = TRUE;
}
}
bool DispBPMsg( bool stack_cmds )
{
brk *bp, *next;
char *p;
bool ret;
cmd_list *cmds;
ret = FALSE;
for( bp = BrkList; bp != NULL; bp = bp->next ) {
if( !bp->status.b.hit ) continue;
if( !bp->status.b.silent ) {
if( bp->th != MAD_NIL_TYPE_HANDLE ) {
p = GetBPAddrText( bp, TxtBuff );
p = StrCopy( " - ", p );
p = StrVal( LIT( OldVal ), bp, p );
GetWPVal( bp );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?