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
5 changed files with 60 additions and 7 deletions
|
@ -372,12 +372,26 @@ 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;
|
||||||
if (DEBUG_GetSymbolValue(name, lineno, &value, TRUE))
|
|
||||||
|
if (DEBUG_GetSymbolValue(name, lineno, &value, TRUE)) {
|
||||||
DEBUG_AddBreakpoint(&value, NULL);
|
DEBUG_AddBreakpoint(&value, NULL);
|
||||||
else
|
return;
|
||||||
DEBUG_Printf(DBG_CHN_MESG, "Unable to add breakpoint\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++) {
|
||||||
|
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);
|
DEBUG_FindNearestSymbol(&value.addr, TRUE, &nh, 0, NULL);
|
||||||
if (nh == 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;
|
return;
|
||||||
}
|
}
|
||||||
DEBUG_GetLineNumberAddr(nh, lineno, &value.addr, TRUE);
|
DEBUG_GetLineNumberAddr(nh, lineno, &value.addr, TRUE);
|
||||||
|
@ -407,6 +421,27 @@ void DEBUG_AddBreakpointFromLineno(int lineno)
|
||||||
DEBUG_AddBreakpoint( &value, NULL );
|
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
|
* DEBUG_AddWatchpoint
|
||||||
*
|
*
|
||||||
|
|
|
@ -183,6 +183,11 @@ typedef struct tagDBG_THREAD {
|
||||||
struct tagDBG_THREAD* prev;
|
struct tagDBG_THREAD* prev;
|
||||||
} DBG_THREAD;
|
} DBG_THREAD;
|
||||||
|
|
||||||
|
typedef struct tagDBG_DELAYED_BP {
|
||||||
|
int lineno;
|
||||||
|
char* name;
|
||||||
|
} DBG_DELAYED_BP;
|
||||||
|
|
||||||
typedef struct tagDBG_PROCESS {
|
typedef struct tagDBG_PROCESS {
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
DWORD pid;
|
DWORD pid;
|
||||||
|
@ -192,6 +197,8 @@ typedef struct tagDBG_PROCESS {
|
||||||
struct tagDBG_MODULE** modules;
|
struct tagDBG_MODULE** modules;
|
||||||
int num_modules;
|
int num_modules;
|
||||||
unsigned long dbg_hdr_addr;
|
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
|
* 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
|
||||||
|
@ -257,6 +264,7 @@ 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 );
|
||||||
extern void DEBUG_AddWatchpointFromId( const char *name );
|
extern void DEBUG_AddWatchpointFromId( const char *name );
|
||||||
|
extern void DEBUG_CheckDelayedBP( void );
|
||||||
extern void DEBUG_DelBreakpoint( int num );
|
extern void DEBUG_DelBreakpoint( int num );
|
||||||
extern void DEBUG_EnableBreakpoint( int num, BOOL enable );
|
extern void DEBUG_EnableBreakpoint( int num, BOOL enable );
|
||||||
extern void DEBUG_InfoBreakpoints(void);
|
extern void DEBUG_InfoBreakpoints(void);
|
||||||
|
|
|
@ -69,7 +69,7 @@ void DEBUG_PrintBasic( const DBG_VALUE* value, int count, char format )
|
||||||
if (strstr(default_format, "%S") == NULL)
|
if (strstr(default_format, "%S") == NULL)
|
||||||
{
|
{
|
||||||
DEBUG_nchar += DEBUG_Printf( DBG_CHN_MESG, default_format, res );
|
DEBUG_nchar += DEBUG_Printf( DBG_CHN_MESG, default_format, res );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char* ptr;
|
char* ptr;
|
||||||
|
|
|
@ -1308,6 +1308,7 @@ static BOOL DEBUG_RescanElf(void)
|
||||||
switch (dbg_hdr.r_state) {
|
switch (dbg_hdr.r_state) {
|
||||||
case RT_CONSISTENT:
|
case RT_CONSISTENT:
|
||||||
DEBUG_WalkList(&dbg_hdr);
|
DEBUG_WalkList(&dbg_hdr);
|
||||||
|
DEBUG_CheckDelayedBP();
|
||||||
break;
|
break;
|
||||||
case RT_ADD:
|
case RT_ADD:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -150,6 +150,8 @@ static DBG_PROCESS* DEBUG_AddProcess(DWORD pid, HANDLE h)
|
||||||
p->num_modules = 0;
|
p->num_modules = 0;
|
||||||
p->next_index = 0;
|
p->next_index = 0;
|
||||||
p->dbg_hdr_addr = 0;
|
p->dbg_hdr_addr = 0;
|
||||||
|
p->delayed_bp = NULL;
|
||||||
|
p->num_delayed_bp = 0;
|
||||||
|
|
||||||
p->next = DEBUG_ProcessList;
|
p->next = DEBUG_ProcessList;
|
||||||
p->prev = NULL;
|
p->prev = NULL;
|
||||||
|
@ -162,10 +164,16 @@ static void DEBUG_DelThread(DBG_THREAD* p);
|
||||||
|
|
||||||
static void DEBUG_DelProcess(DBG_PROCESS* p)
|
static void DEBUG_DelProcess(DBG_PROCESS* p)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
if (p->threads != NULL) {
|
if (p->threads != NULL) {
|
||||||
DEBUG_Printf(DBG_CHN_ERR, "Shouldn't happen\n");
|
DEBUG_Printf(DBG_CHN_ERR, "Shouldn't happen\n");
|
||||||
while (p->threads) DEBUG_DelThread(p->threads);
|
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->prev) p->prev->next = p->next;
|
||||||
if (p->next) p->next->prev = p->prev;
|
if (p->next) p->next->prev = p->prev;
|
||||||
if (p == DEBUG_ProcessList) DEBUG_ProcessList = p->next;
|
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);
|
de->u.LoadDll.nDebugInfoSize);
|
||||||
_strupr(buffer);
|
_strupr(buffer);
|
||||||
DEBUG_LoadModule32(buffer, de->u.LoadDll.hFile, (DWORD)de->u.LoadDll.lpBaseOfDll);
|
DEBUG_LoadModule32(buffer, de->u.LoadDll.hFile, (DWORD)de->u.LoadDll.lpBaseOfDll);
|
||||||
|
DEBUG_CheckDelayedBP();
|
||||||
if (DBG_IVAR(BreakOnDllLoad)) {
|
if (DBG_IVAR(BreakOnDllLoad)) {
|
||||||
DEBUG_Printf(DBG_CHN_MESG, "Stopping on DLL %s loading at %08lx\n",
|
DEBUG_Printf(DBG_CHN_MESG, "Stopping on DLL %s loading at %08lx\n",
|
||||||
buffer, (unsigned long)de->u.LoadDll.lpBaseOfDll);
|
buffer, (unsigned long)de->u.LoadDll.lpBaseOfDll);
|
||||||
|
|
Loading…
Add table
Reference in a new issue