Added ability to defer breakpoint setting for breakpoint defined by an

absolute address.
This commit is contained in:
Eric Pouech 2002-07-30 00:06:34 +00:00 committed by Alexandre Julliard
parent 6f129541d1
commit 72a7369ebc
6 changed files with 136 additions and 76 deletions

View file

@ -274,7 +274,7 @@ static int DEBUG_FindBreakpoint( const DBG_ADDR *addr, int type )
* *
* Find an empty slot in BP table to add a new break/watch point * Find an empty slot in BP table to add a new break/watch point
*/ */
static int DEBUG_InitXPoint(int type, DBG_ADDR* addr) static int DEBUG_InitXPoint(int type, const DBG_ADDR* addr)
{ {
int num; int num;
@ -336,13 +336,48 @@ static BOOL DEBUG_GetWatchedValue( int num, LPDWORD val )
* *
* Add a breakpoint. * Add a breakpoint.
*/ */
void DEBUG_AddBreakpoint( const DBG_VALUE *_value, BOOL (*func)(void) ) BOOL DEBUG_AddBreakpoint( const DBG_VALUE *value, BOOL (*func)(void), BOOL verbose )
{ {
DBG_VALUE value = *_value;
int num; int num;
BYTE ch; BYTE ch;
if( value.type != NULL && value.type == DEBUG_GetBasicType(DT_BASIC_CONST_INT) ) if ((num = DEBUG_FindBreakpoint(&value->addr, DBG_BREAK)) >= 1)
{
breakpoints[num].refcount++;
return TRUE;
}
if (!DEBUG_READ_MEM((void*)DEBUG_ToLinear( &value->addr ), &ch, sizeof(ch)))
{
if (verbose)
DEBUG_Printf( DBG_CHN_MESG, "Invalid address, can't set breakpoint\n");
return FALSE;
}
if ((num = DEBUG_InitXPoint(DBG_BREAK, &value->addr)) == -1)
return FALSE;
breakpoints[num].u.b.opcode = ch;
breakpoints[num].u.b.func = func;
DEBUG_Printf( DBG_CHN_MESG, "Breakpoint %d at ", num );
DEBUG_PrintAddress( &breakpoints[num].addr, breakpoints[num].is32 ? MODE_32 : MODE_16,
TRUE );
DEBUG_Printf( DBG_CHN_MESG, "\n" );
return FALSE;
}
/***********************************************************************
* DEBUG_AddBreakpointFromValue
*
* Add a breakpoint.
*/
BOOL DEBUG_AddBreakpointFromValue( const DBG_VALUE *_value )
{
DBG_VALUE value = *_value;
if (value.type != NULL && value.type == DEBUG_GetBasicType(DT_BASIC_CONST_INT) && value.cookie == DV_HOST)
{ {
/* /*
* We know that we have the actual offset stored somewhere * We know that we have the actual offset stored somewhere
@ -353,30 +388,27 @@ void DEBUG_AddBreakpoint( const DBG_VALUE *_value, BOOL (*func)(void) )
value.addr.seg = 0; value.addr.seg = 0;
value.addr.off = DEBUG_GetExprValue(&value, NULL); value.addr.off = DEBUG_GetExprValue(&value, NULL);
value.addr.seg = seg2; value.addr.seg = seg2;
value.cookie = DV_TARGET;
} }
if ((num = DEBUG_FindBreakpoint(&value.addr, DBG_BREAK)) >= 1) if (!DEBUG_AddBreakpoint( &value, NULL, TRUE ))
{ {
breakpoints[num].refcount++; if (!DBG_IVAR(CanDeferOnBPByAddr))
return; {
DEBUG_Printf( DBG_CHN_MESG, "Invalid address, can't set breakpoint\n"
"You can turn on deferring breakpoints by address by setting $CanDeferOnBPByAddr to 1\n");
return FALSE;
}
DEBUG_Printf(DBG_CHN_MESG, "Unable to add breakpoint, will check again any time a new DLL is loaded\n");
DEBUG_CurrProcess->delayed_bp = DBG_realloc(DEBUG_CurrProcess->delayed_bp,
sizeof(DBG_DELAYED_BP) * ++DEBUG_CurrProcess->num_delayed_bp);
DEBUG_CurrProcess->delayed_bp[DEBUG_CurrProcess->num_delayed_bp - 1].is_symbol = FALSE;
DEBUG_CurrProcess->delayed_bp[DEBUG_CurrProcess->num_delayed_bp - 1].u.value = value;
return TRUE;
} }
if (!DEBUG_READ_MEM_VERBOSE((void*)DEBUG_ToLinear( &value.addr ), &ch, sizeof(ch))) return TRUE;
{
DEBUG_Printf( DBG_CHN_MESG, "Invalid address, can't set breakpoint\n");
return;
}
if ((num = DEBUG_InitXPoint(DBG_BREAK, &value.addr)) == -1)
return;
breakpoints[num].u.b.opcode = ch;
breakpoints[num].u.b.func = func;
DEBUG_Printf( DBG_CHN_MESG, "Breakpoint %d at ", num );
DEBUG_PrintAddress( &breakpoints[num].addr, breakpoints[num].is32 ? MODE_32 : MODE_16,
TRUE );
DEBUG_Printf( DBG_CHN_MESG, "\n" );
} }
/*********************************************************************** /***********************************************************************
@ -386,26 +418,29 @@ void DEBUG_AddBreakpoint( const DBG_VALUE *_value, BOOL (*func)(void) )
*/ */
void DEBUG_AddBreakpointFromId(const char *name, int lineno) void DEBUG_AddBreakpointFromId(const char *name, int lineno)
{ {
DBG_VALUE value; DBG_VALUE value;
int i; int i;
if (DEBUG_GetSymbolValue(name, lineno, &value, TRUE)) { if (DEBUG_GetSymbolValue(name, lineno, &value, TRUE))
DEBUG_AddBreakpoint(&value, NULL); {
return; DEBUG_AddBreakpoint(&value, NULL, TRUE);
} return;
}
DEBUG_Printf(DBG_CHN_MESG, "Unable to add breakpoint, will check again when a new DLL is loaded\n"); DEBUG_Printf(DBG_CHN_MESG, "Unable to add breakpoint, will check again when a new DLL is loaded\n");
for (i = 0; i < DEBUG_CurrProcess->num_delayed_bp; i++) { for (i = 0; i < DEBUG_CurrProcess->num_delayed_bp; i++)
if (!strcmp(name, DEBUG_CurrProcess->delayed_bp[i].name) && {
lineno == DEBUG_CurrProcess->delayed_bp[i].lineno) { if (DEBUG_CurrProcess->delayed_bp[i].is_symbol &&
return; !strcmp(name, DEBUG_CurrProcess->delayed_bp[i].u.symbol.name) &&
} lineno == DEBUG_CurrProcess->delayed_bp[i].u.symbol.lineno)
} return;
DEBUG_CurrProcess->delayed_bp = DBG_realloc(DEBUG_CurrProcess->delayed_bp, }
sizeof(DBG_DELAYED_BP) * ++DEBUG_CurrProcess->num_delayed_bp); DEBUG_CurrProcess->delayed_bp = DBG_realloc(DEBUG_CurrProcess->delayed_bp,
sizeof(DBG_DELAYED_BP) * ++DEBUG_CurrProcess->num_delayed_bp);
DEBUG_CurrProcess->delayed_bp[DEBUG_CurrProcess->num_delayed_bp - 1].name = strcpy(DBG_alloc(strlen(name) + 1), name); DEBUG_CurrProcess->delayed_bp[DEBUG_CurrProcess->num_delayed_bp - 1].is_symbol = TRUE;
DEBUG_CurrProcess->delayed_bp[DEBUG_CurrProcess->num_delayed_bp - 1].lineno = lineno; DEBUG_CurrProcess->delayed_bp[DEBUG_CurrProcess->num_delayed_bp - 1].u.symbol.name = strcpy(DBG_alloc(strlen(name) + 1), name);
DEBUG_CurrProcess->delayed_bp[DEBUG_CurrProcess->num_delayed_bp - 1].u.symbol.lineno = lineno;
} }
/*********************************************************************** /***********************************************************************
@ -415,24 +450,26 @@ void DEBUG_AddBreakpointFromId(const char *name, int lineno)
*/ */
void DEBUG_AddBreakpointFromLineno(int lineno) void DEBUG_AddBreakpointFromLineno(int lineno)
{ {
DBG_VALUE value; DBG_VALUE value;
DEBUG_GetCurrentAddress(&value.addr); DEBUG_GetCurrentAddress(&value.addr);
if (lineno != -1) { if (lineno != -1)
struct name_hash* nh; {
struct name_hash* nh;
DEBUG_FindNearestSymbol(&value.addr, TRUE, &nh, 0, NULL); DEBUG_FindNearestSymbol(&value.addr, TRUE, &nh, 0, NULL);
if (nh == NULL) { if (nh == NULL)
DEBUG_Printf(DBG_CHN_MESG, "Unable to add breakpoint\n"); {
return; DEBUG_Printf(DBG_CHN_MESG, "Unable to add breakpoint\n");
} return;
DEBUG_GetLineNumberAddr(nh, lineno, &value.addr, TRUE); }
} DEBUG_GetLineNumberAddr(nh, lineno, &value.addr, TRUE);
}
value.type = NULL; value.type = NULL;
value.cookie = DV_TARGET; value.cookie = DV_TARGET;
DEBUG_AddBreakpoint( &value, NULL ); DEBUG_AddBreakpoint( &value,NULL, TRUE );
} }
/*********************************************************************** /***********************************************************************
@ -442,18 +479,32 @@ void DEBUG_AddBreakpointFromLineno(int lineno)
*/ */
void DEBUG_CheckDelayedBP(void) void DEBUG_CheckDelayedBP(void)
{ {
DBG_VALUE value; DBG_VALUE value;
int i = 0; int i;
DBG_DELAYED_BP* dbp = DEBUG_CurrProcess->delayed_bp; DBG_DELAYED_BP* dbp = DEBUG_CurrProcess->delayed_bp;
while (i < DEBUG_CurrProcess->num_delayed_bp) { for (i = 0; i < DEBUG_CurrProcess->num_delayed_bp; i++)
if (DEBUG_GetSymbolValue(dbp[i].name, dbp[i].lineno, &value, TRUE)) { {
DEBUG_AddBreakpoint(&value, NULL); if (dbp[i].is_symbol)
memmove(&dbp[i], &dbp[i+1], (--DEBUG_CurrProcess->num_delayed_bp - i) * sizeof(*dbp)); {
} else { if (!DEBUG_GetSymbolValue(dbp[i].u.symbol.name, dbp[i].u.symbol.lineno, &value, TRUE))
i++; continue;
} }
} else
value = dbp[i].u.value;
DEBUG_Printf(DBG_CHN_MESG, "trying to add delayed %s-bp\n", dbp[i].is_symbol ? "S" : "A");
if (!dbp[i].is_symbol)
DEBUG_Printf(DBG_CHN_MESG, "\t%04x %04lx:%08lx\n",
dbp[i].u.value.cookie,
dbp[i].u.value.addr.seg,
dbp[i].u.value.addr.off);
else
DEBUG_Printf(DBG_CHN_MESG, "\t'%s' @ %d\n",
dbp[i].u.symbol.name, dbp[i].u.symbol.lineno);
if (DEBUG_AddBreakpoint(&value, NULL, FALSE))
memmove(&dbp[i], &dbp[i+1], (--DEBUG_CurrProcess->num_delayed_bp - i) * sizeof(*dbp));
}
} }
/*********************************************************************** /***********************************************************************

View file

@ -164,7 +164,7 @@ command:
; ;
set_command: set_command:
tSET lval_addr '=' expr_value tEOL { DEBUG_WriteMemory(&$2,$4); DEBUG_FreeExprMem(); } tSET lval_addr '=' expr_value tEOL { DEBUG_WriteMemory(&$2, $4); DEBUG_FreeExprMem(); }
| tSET '+' tIDENTIFIER tEOL {DEBUG_DbgChannel(TRUE, NULL, $3);} | tSET '+' tIDENTIFIER tEOL {DEBUG_DbgChannel(TRUE, NULL, $3);}
| tSET '-' tIDENTIFIER tEOL {DEBUG_DbgChannel(FALSE, NULL, $3);} | tSET '-' tIDENTIFIER tEOL {DEBUG_DbgChannel(FALSE, NULL, $3);}
| tSET tIDENTIFIER '+' tIDENTIFIER tEOL {DEBUG_DbgChannel(TRUE, $2, $4);} | tSET tIDENTIFIER '+' tIDENTIFIER tEOL {DEBUG_DbgChannel(TRUE, $2, $4);}
@ -212,7 +212,7 @@ print_command:
; ;
break_command: break_command:
tBREAK '*' expr_addr tEOL{ DEBUG_AddBreakpoint( &$3, NULL ); DEBUG_FreeExprMem(); } tBREAK '*' expr_addr tEOL{ DEBUG_AddBreakpointFromValue( &$3 ); DEBUG_FreeExprMem(); }
| tBREAK identifier tEOL { DEBUG_AddBreakpointFromId($2, -1); } | tBREAK identifier tEOL { DEBUG_AddBreakpointFromId($2, -1); }
| tBREAK identifier ':' tNUM tEOL { DEBUG_AddBreakpointFromId($2, $4); } | tBREAK identifier ':' tNUM tEOL { DEBUG_AddBreakpointFromId($2, $4); }
| tBREAK tNUM tEOL { DEBUG_AddBreakpointFromLineno($2); } | tBREAK tNUM tEOL { DEBUG_AddBreakpointFromLineno($2); }

View file

@ -209,8 +209,14 @@ typedef struct tagDBG_THREAD {
} DBG_THREAD; } DBG_THREAD;
typedef struct tagDBG_DELAYED_BP { typedef struct tagDBG_DELAYED_BP {
int lineno; BOOL is_symbol;
char* name; union {
struct {
int lineno;
char* name;
} symbol;
DBG_VALUE value;
} u;
} DBG_DELAYED_BP; } DBG_DELAYED_BP;
typedef struct tagDBG_PROCESS { typedef struct tagDBG_PROCESS {
@ -227,7 +233,7 @@ typedef struct tagDBG_PROCESS {
int num_delayed_bp; int num_delayed_bp;
/* /*
* This is an index we use to keep track of the debug information * This is an index we use to keep track of the debug information
* when we have multiple sources. We use the same database to also * when we have multiple sources. We use the same database to also
* allow us to do an 'info shared' type of deal, and we use the index * allow us to do an 'info shared' type of deal, and we use the index
* to eliminate duplicates. * to eliminate duplicates.
*/ */
@ -288,7 +294,8 @@ extern void DEBUG_ExternalDebugger(void);
/* debugger/break.c */ /* debugger/break.c */
extern void DEBUG_SetBreakpoints( BOOL set ); extern void DEBUG_SetBreakpoints( BOOL set );
extern void DEBUG_AddBreakpoint( const DBG_VALUE *addr, BOOL (*func)(void) ); extern BOOL DEBUG_AddBreakpoint( const DBG_VALUE *addr, BOOL (*func)(void), BOOL verbose );
extern BOOL DEBUG_AddBreakpointFromValue( const DBG_VALUE *addr );
extern void DEBUG_AddBreakpointFromId( const char *name, int lineno ); extern void DEBUG_AddBreakpointFromId( const char *name, int lineno );
extern void DEBUG_AddBreakpointFromLineno( int lineno ); extern void DEBUG_AddBreakpointFromLineno( int lineno );
extern void DEBUG_AddWatchpoint( const DBG_VALUE *addr, int is_write ); extern void DEBUG_AddWatchpoint( const DBG_VALUE *addr, int is_write );

View file

@ -25,6 +25,7 @@ INTERNAL_VAR(BreakOnCritSectTimeOut, FALSE, NULL, DT_BASIC_CONST
INTERNAL_VAR(BreakOnAttach, FALSE, NULL, DT_BASIC_CONST_INT) INTERNAL_VAR(BreakOnAttach, FALSE, NULL, DT_BASIC_CONST_INT)
INTERNAL_VAR(BreakOnFirstChance, TRUE, NULL, DT_BASIC_CONST_INT) INTERNAL_VAR(BreakOnFirstChance, TRUE, NULL, DT_BASIC_CONST_INT)
INTERNAL_VAR(BreakOnDllLoad, FALSE, NULL, DT_BASIC_CONST_INT) INTERNAL_VAR(BreakOnDllLoad, FALSE, NULL, DT_BASIC_CONST_INT)
INTERNAL_VAR(CanDeferOnBPByAddr, FALSE, NULL, DT_BASIC_CONST_INT)
/* output handling */ /* output handling */
INTERNAL_VAR(ConChannelMask, DBG_CHN_MESG, NULL, DT_BASIC_CONST_INT) INTERNAL_VAR(ConChannelMask, DBG_CHN_MESG, NULL, DT_BASIC_CONST_INT)

View file

@ -1453,7 +1453,7 @@ enum DbgInfoLoad DEBUG_ReadExecutableDbgInfo(const char* exe_name)
value.cookie = DV_TARGET; value.cookie = DV_TARGET;
value.addr.seg = 0; value.addr.seg = 0;
value.addr.off = (DWORD)dbg_hdr.r_brk; value.addr.off = (DWORD)dbg_hdr.r_brk;
DEBUG_AddBreakpoint(&value, DEBUG_RescanElf); DEBUG_AddBreakpoint(&value, DEBUG_RescanElf, TRUE);
DEBUG_SetBreakpoints(TRUE); DEBUG_SetBreakpoints(TRUE);
} }

View file

@ -196,9 +196,10 @@ void DEBUG_DelProcess(DBG_PROCESS* p)
while (p->threads) DEBUG_DelThread(p->threads); while (p->threads) DEBUG_DelThread(p->threads);
for (i = 0; i < p->num_delayed_bp; i++) { for (i = 0; i < p->num_delayed_bp; i++)
DBG_free(p->delayed_bp[i].name); if (p->delayed_bp[i].is_symbol)
} DBG_free(p->delayed_bp[i].u.symbol.name);
DBG_free(p->delayed_bp); DBG_free(p->delayed_bp);
if (p->prev) p->prev->next = p->next; if (p->prev) p->prev->next = p->next;
if (p->next) p->next->prev = p->prev; if (p->next) p->next->prev = p->prev;
@ -283,7 +284,7 @@ static void DEBUG_InitCurrThread(void)
value.cookie = DV_TARGET; value.cookie = DV_TARGET;
value.addr.seg = 0; value.addr.seg = 0;
value.addr.off = (DWORD)DEBUG_CurrThread->start; value.addr.off = (DWORD)DEBUG_CurrThread->start;
DEBUG_AddBreakpoint(&value, NULL); DEBUG_AddBreakpointFromValue(&value);
DEBUG_SetBreakpoints(TRUE); DEBUG_SetBreakpoints(TRUE);
} }
} else { } else {