Added the notion of delayed breakpoint (when a function is not loaded
yet, the name will be tried again for each new loaded module).
This commit is contained in:
parent
e459e60b6a
commit
eaafb73cd5
|
@ -373,11 +373,25 @@ void DEBUG_AddBreakpoint( const DBG_VALUE *_value, BOOL (*func)(void) )
|
|||
void DEBUG_AddBreakpointFromId(const char *name, int lineno)
|
||||
{
|
||||
DBG_VALUE value;
|
||||
int i;
|
||||
|
||||
if (DEBUG_GetSymbolValue(name, lineno, &value, TRUE))
|
||||
if (DEBUG_GetSymbolValue(name, lineno, &value, TRUE)) {
|
||||
DEBUG_AddBreakpoint(&value, NULL);
|
||||
else
|
||||
DEBUG_Printf(DBG_CHN_MESG, "Unable to add breakpoint\n");
|
||||
return;
|
||||
}
|
||||
|
||||
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++) {
|
||||
if (!strcmp(name, DEBUG_CurrProcess->delayed_bp[i].name) &&
|
||||
lineno == DEBUG_CurrProcess->delayed_bp[i].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[DEBUG_CurrProcess->num_delayed_bp - 1].name = strcpy(DBG_alloc(strlen(name) + 1), name);
|
||||
DEBUG_CurrProcess->delayed_bp[DEBUG_CurrProcess->num_delayed_bp - 1].lineno = lineno;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -396,7 +410,7 @@ void DEBUG_AddBreakpointFromLineno(int lineno)
|
|||
|
||||
DEBUG_FindNearestSymbol(&value.addr, TRUE, &nh, 0, NULL);
|
||||
if (nh == NULL) {
|
||||
DEBUG_Printf(DBG_CHN_MESG,"Unable to add breakpoint\n");
|
||||
DEBUG_Printf(DBG_CHN_MESG, "Unable to add breakpoint\n");
|
||||
return;
|
||||
}
|
||||
DEBUG_GetLineNumberAddr(nh, lineno, &value.addr, TRUE);
|
||||
|
@ -407,6 +421,27 @@ void DEBUG_AddBreakpointFromLineno(int lineno)
|
|||
DEBUG_AddBreakpoint( &value, NULL );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DEBUG_CheckDelayedBP
|
||||
*
|
||||
* Check is a registered delayed BP is now available.
|
||||
*/
|
||||
void DEBUG_CheckDelayedBP(void)
|
||||
{
|
||||
DBG_VALUE value;
|
||||
int i = 0;
|
||||
DBG_DELAYED_BP* dbp = DEBUG_CurrProcess->delayed_bp;
|
||||
|
||||
while (i < DEBUG_CurrProcess->num_delayed_bp) {
|
||||
if (DEBUG_GetSymbolValue(dbp[i].name, dbp[i].lineno, &value, TRUE)) {
|
||||
DEBUG_AddBreakpoint(&value, NULL);
|
||||
memmove(&dbp[i], &dbp[i+1], (--DEBUG_CurrProcess->num_delayed_bp - i) * sizeof(*dbp));
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DEBUG_AddWatchpoint
|
||||
*
|
||||
|
|
|
@ -183,6 +183,11 @@ typedef struct tagDBG_THREAD {
|
|||
struct tagDBG_THREAD* prev;
|
||||
} DBG_THREAD;
|
||||
|
||||
typedef struct tagDBG_DELAYED_BP {
|
||||
int lineno;
|
||||
char* name;
|
||||
} DBG_DELAYED_BP;
|
||||
|
||||
typedef struct tagDBG_PROCESS {
|
||||
HANDLE handle;
|
||||
DWORD pid;
|
||||
|
@ -192,6 +197,8 @@ typedef struct tagDBG_PROCESS {
|
|||
struct tagDBG_MODULE** modules;
|
||||
int num_modules;
|
||||
unsigned long dbg_hdr_addr;
|
||||
DBG_DELAYED_BP* delayed_bp;
|
||||
int num_delayed_bp;
|
||||
/*
|
||||
* 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
|
||||
|
@ -257,6 +264,7 @@ extern void DEBUG_AddBreakpointFromId( const char *name, int lineno );
|
|||
extern void DEBUG_AddBreakpointFromLineno( int lineno );
|
||||
extern void DEBUG_AddWatchpoint( const DBG_VALUE *addr, int is_write );
|
||||
extern void DEBUG_AddWatchpointFromId( const char *name );
|
||||
extern void DEBUG_CheckDelayedBP( void );
|
||||
extern void DEBUG_DelBreakpoint( int num );
|
||||
extern void DEBUG_EnableBreakpoint( int num, BOOL enable );
|
||||
extern void DEBUG_InfoBreakpoints(void);
|
||||
|
|
|
@ -1308,6 +1308,7 @@ static BOOL DEBUG_RescanElf(void)
|
|||
switch (dbg_hdr.r_state) {
|
||||
case RT_CONSISTENT:
|
||||
DEBUG_WalkList(&dbg_hdr);
|
||||
DEBUG_CheckDelayedBP();
|
||||
break;
|
||||
case RT_ADD:
|
||||
break;
|
||||
|
|
|
@ -150,6 +150,8 @@ static DBG_PROCESS* DEBUG_AddProcess(DWORD pid, HANDLE h)
|
|||
p->num_modules = 0;
|
||||
p->next_index = 0;
|
||||
p->dbg_hdr_addr = 0;
|
||||
p->delayed_bp = NULL;
|
||||
p->num_delayed_bp = 0;
|
||||
|
||||
p->next = DEBUG_ProcessList;
|
||||
p->prev = NULL;
|
||||
|
@ -162,10 +164,16 @@ static void DEBUG_DelThread(DBG_THREAD* p);
|
|||
|
||||
static void DEBUG_DelProcess(DBG_PROCESS* p)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (p->threads != NULL) {
|
||||
DEBUG_Printf(DBG_CHN_ERR, "Shouldn't happen\n");
|
||||
while (p->threads) DEBUG_DelThread(p->threads);
|
||||
}
|
||||
for (i = 0; i < p->num_delayed_bp; i++) {
|
||||
DBG_free(p->delayed_bp[i].name);
|
||||
}
|
||||
DBG_free(p->delayed_bp);
|
||||
if (p->prev) p->prev->next = p->next;
|
||||
if (p->next) p->next->prev = p->prev;
|
||||
if (p == DEBUG_ProcessList) DEBUG_ProcessList = p->next;
|
||||
|
@ -730,6 +738,7 @@ static BOOL DEBUG_HandleDebugEvent(DEBUG_EVENT* de, LPDWORD cont)
|
|||
de->u.LoadDll.nDebugInfoSize);
|
||||
_strupr(buffer);
|
||||
DEBUG_LoadModule32(buffer, de->u.LoadDll.hFile, (DWORD)de->u.LoadDll.lpBaseOfDll);
|
||||
DEBUG_CheckDelayedBP();
|
||||
if (DBG_IVAR(BreakOnDllLoad)) {
|
||||
DEBUG_Printf(DBG_CHN_MESG, "Stopping on DLL %s loading at %08lx\n",
|
||||
buffer, (unsigned long)de->u.LoadDll.lpBaseOfDll);
|
||||
|
|
Loading…
Reference in New Issue