2011-02-15 Paul Pluzhnikov <ppluzhnikov@google.com>

* breakpoint.c (longjmp_names): New variable.
	(struct breakpoint_objfile_data): New type.
	(breakpoint_objfile_key): New variable.
	(msym_not_found): New variable.
	(msym_not_found_p): New predicate.
	(get_breakpoint_objfile_data): New function.
	(create_overlay_event_breakpoint): Check per-objfile cache for
	symbols first.
	(create_longjmp_master_breakpoint): Likewise.
	(create_std_terminate_master_breakpoint): Likewise.
	(create_exception_master_breakpoint): Likewise.
	(_initialize_breakpoint): Register per-objfile data key.
This commit is contained in:
Paul Pluzhnikov 2011-02-15 21:43:25 +00:00
parent cdf99611e7
commit 17450429ce
2 changed files with 175 additions and 38 deletions

View File

@ -1,3 +1,18 @@
2011-02-15 Paul Pluzhnikov <ppluzhnikov@google.com>
* breakpoint.c (longjmp_names): New variable.
(struct breakpoint_objfile_data): New type.
(breakpoint_objfile_key): New variable.
(msym_not_found): New variable.
(msym_not_found_p): New predicate.
(get_breakpoint_objfile_data): New function.
(create_overlay_event_breakpoint): Check per-objfile cache for
symbols first.
(create_longjmp_master_breakpoint): Likewise.
(create_std_terminate_master_breakpoint): Likewise.
(create_exception_master_breakpoint): Likewise.
(_initialize_breakpoint): Register per-objfile data key.
2011-02-15 Paul Pluzhnikov <ppluzhnikov@google.com>
* breakpoint.c ((create_overlay_event_breakpoint): Const-propagate

View File

@ -2217,6 +2217,61 @@ create_internal_breakpoint (struct gdbarch *gdbarch,
return b;
}
static const char *const longjmp_names[] =
{
"longjmp", "_longjmp", "siglongjmp", "_siglongjmp"
};
#define NUM_LONGJMP_NAMES ARRAY_SIZE(longjmp_names)
/* Per-objfile data private to breakpoint.c. */
struct breakpoint_objfile_data
{
/* Minimal symbol for "_ovly_debug_event" (if any). */
struct minimal_symbol *overlay_msym;
/* Minimal symbol(s) for "longjmp", "siglongjmp", etc. (if any). */
struct minimal_symbol *longjmp_msym[NUM_LONGJMP_NAMES];
/* Minimal symbol for "std::terminate()" (if any). */
struct minimal_symbol *terminate_msym;
/* Minimal symbol for "_Unwind_DebugHook" (if any). */
struct minimal_symbol *exception_msym;
};
static const struct objfile_data *breakpoint_objfile_key;
/* Minimal symbol not found sentinel. */
static struct minimal_symbol msym_not_found;
/* Returns TRUE if MSYM point to the "not found" sentinel. */
static int
msym_not_found_p (const struct minimal_symbol *msym)
{
return msym == &msym_not_found;
}
/* Return per-objfile data needed by breakpoint.c.
Allocate the data if necessary. */
static struct breakpoint_objfile_data *
get_breakpoint_objfile_data (struct objfile *objfile)
{
struct breakpoint_objfile_data *bp_objfile_data;
bp_objfile_data = objfile_data (objfile, breakpoint_objfile_key);
if (bp_objfile_data == NULL)
{
bp_objfile_data = obstack_alloc (&objfile->objfile_obstack,
sizeof (*bp_objfile_data));
memset (bp_objfile_data, 0, sizeof (*bp_objfile_data));
set_objfile_data (objfile, breakpoint_objfile_key, bp_objfile_data);
}
return bp_objfile_data;
}
static void
create_overlay_event_breakpoint (void)
{
@ -2226,14 +2281,30 @@ create_overlay_event_breakpoint (void)
ALL_OBJFILES (objfile)
{
struct breakpoint *b;
struct minimal_symbol *m;
struct breakpoint_objfile_data *bp_objfile_data;
CORE_ADDR addr;
m = lookup_minimal_symbol_text (func_name, objfile);
if (m == NULL)
continue;
bp_objfile_data = get_breakpoint_objfile_data (objfile);
b = create_internal_breakpoint (get_objfile_arch (objfile),
SYMBOL_VALUE_ADDRESS (m),
if (msym_not_found_p (bp_objfile_data->overlay_msym))
continue;
if (bp_objfile_data->overlay_msym == NULL)
{
struct minimal_symbol *m;
m = lookup_minimal_symbol_text (func_name, objfile);
if (m == NULL)
{
/* Avoid future lookups in this objfile. */
bp_objfile_data->overlay_msym = &msym_not_found;
continue;
}
bp_objfile_data->overlay_msym = m;
}
addr = SYMBOL_VALUE_ADDRESS (bp_objfile_data->overlay_msym);
b = create_internal_breakpoint (get_objfile_arch (objfile), addr,
bp_overlay_event);
b->addr_string = xstrdup (func_name);
@ -2267,31 +2338,42 @@ create_longjmp_master_breakpoint (void)
ALL_OBJFILES (objfile)
{
const char *const longjmp_names[]
= { "longjmp", "_longjmp", "siglongjmp", "_siglongjmp" };
const int num_longjmp_names
= sizeof (longjmp_names) / sizeof (longjmp_names[0]);
int i;
struct gdbarch *gdbarch;
struct breakpoint_objfile_data *bp_objfile_data;
gdbarch = get_objfile_arch (objfile);
if (!gdbarch_get_longjmp_target_p (gdbarch))
continue;
for (i = 0; i < num_longjmp_names; i++)
bp_objfile_data = get_breakpoint_objfile_data (objfile);
for (i = 0; i < NUM_LONGJMP_NAMES; i++)
{
struct breakpoint *b;
struct minimal_symbol *m;
const char *func_name;
CORE_ADDR addr;
func_name = longjmp_names[i];
m = lookup_minimal_symbol_text (func_name, objfile);
if (m == NULL)
if (msym_not_found_p (bp_objfile_data->longjmp_msym[i]))
continue;
b = create_internal_breakpoint (gdbarch,
SYMBOL_VALUE_ADDRESS (m),
bp_longjmp_master);
func_name = longjmp_names[i];
if (bp_objfile_data->longjmp_msym[i] == NULL)
{
struct minimal_symbol *m;
m = lookup_minimal_symbol_text (func_name, objfile);
if (m == NULL)
{
/* Prevent future lookups in this objfile. */
bp_objfile_data->longjmp_msym[i] = &msym_not_found;
continue;
}
bp_objfile_data->longjmp_msym[i] = m;
}
addr = SYMBOL_VALUE_ADDRESS (bp_objfile_data->longjmp_msym[i]);
b = create_internal_breakpoint (gdbarch, addr, bp_longjmp_master);
b->addr_string = xstrdup (func_name);
b->enable_state = bp_disabled;
}
@ -2307,31 +2389,51 @@ static void
create_std_terminate_master_breakpoint (void)
{
struct program_space *pspace;
struct objfile *objfile;
struct cleanup *old_chain;
const char *const func_name = "std::terminate()";
old_chain = save_current_program_space ();
ALL_PSPACES (pspace)
{
struct objfile *objfile;
CORE_ADDR addr;
set_current_program_space (pspace);
ALL_OBJFILES (objfile)
{
struct breakpoint *b;
struct minimal_symbol *m;
struct breakpoint_objfile_data *bp_objfile_data;
set_current_program_space (pspace);
bp_objfile_data = get_breakpoint_objfile_data (objfile);
m = lookup_minimal_symbol (func_name, NULL, objfile);
if (m == NULL || (MSYMBOL_TYPE (m) != mst_text
&& MSYMBOL_TYPE (m) != mst_file_text))
continue;
if (msym_not_found_p (bp_objfile_data->terminate_msym))
continue;
b = create_internal_breakpoint (get_objfile_arch (objfile),
SYMBOL_VALUE_ADDRESS (m),
if (bp_objfile_data->terminate_msym == NULL)
{
struct minimal_symbol *m;
m = lookup_minimal_symbol (func_name, NULL, objfile);
if (m == NULL || (MSYMBOL_TYPE (m) != mst_text
&& MSYMBOL_TYPE (m) != mst_file_text))
{
/* Prevent future lookups in this objfile. */
bp_objfile_data->terminate_msym = &msym_not_found;
continue;
}
bp_objfile_data->terminate_msym = m;
}
addr = SYMBOL_VALUE_ADDRESS (bp_objfile_data->terminate_msym);
b = create_internal_breakpoint (get_objfile_arch (objfile), addr,
bp_std_terminate_master);
b->addr_string = xstrdup (func_name);
b->enable_state = bp_disabled;
}
}
update_global_location_list (1);
do_cleanups (old_chain);
@ -2343,24 +2445,42 @@ void
create_exception_master_breakpoint (void)
{
struct objfile *objfile;
const char *const func_name = "_Unwind_DebugHook";
ALL_OBJFILES (objfile)
{
struct minimal_symbol *debug_hook;
struct breakpoint *b;
struct gdbarch *gdbarch;
struct breakpoint_objfile_data *bp_objfile_data;
CORE_ADDR addr;
debug_hook = lookup_minimal_symbol ("_Unwind_DebugHook", NULL, objfile);
if (debug_hook != NULL)
bp_objfile_data = get_breakpoint_objfile_data (objfile);
if (msym_not_found_p (bp_objfile_data->exception_msym))
continue;
gdbarch = get_objfile_arch (objfile);
if (bp_objfile_data->exception_msym == NULL)
{
struct breakpoint *b;
CORE_ADDR addr = SYMBOL_VALUE_ADDRESS (debug_hook);
struct gdbarch *gdbarch = get_objfile_arch (objfile);
struct minimal_symbol *debug_hook;
addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr,
&current_target);
b = create_internal_breakpoint (gdbarch, addr, bp_exception_master);
b->addr_string = xstrdup ("_Unwind_DebugHook");
b->enable_state = bp_disabled;
debug_hook = lookup_minimal_symbol (func_name, NULL, objfile);
if (debug_hook == NULL)
{
bp_objfile_data->exception_msym = &msym_not_found;
continue;
}
bp_objfile_data->exception_msym = debug_hook;
}
addr = SYMBOL_VALUE_ADDRESS (bp_objfile_data->exception_msym);
addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr,
&current_target);
b = create_internal_breakpoint (gdbarch, addr, bp_exception_master);
b->addr_string = xstrdup (func_name);
b->enable_state = bp_disabled;
}
update_global_location_list (1);
@ -12074,6 +12194,8 @@ _initialize_breakpoint (void)
observer_attach_inferior_exit (clear_syscall_counts);
observer_attach_memory_changed (invalidate_bp_value_on_memory_change);
breakpoint_objfile_key = register_objfile_data ();
breakpoint_chain = 0;
/* Don't bother to call set_breakpoint_count. $bpnum isn't useful
before a breakpoint is set. */