New remove-symbol-file command.

New command for removing symbol files added via
the add-symbol-file command.

2013-10-29  Nicolas Blanc  <nicolas.blanc@intel.com>

	* breakpoint.c (disable_breakpoints_in_freed_objfile): New function.
	* objfiles.c (free_objfile): Notify free_objfile.
	(is_addr_in_objfile): New function.
	* objfiles.h (is_addr_in_objfile): New declaration.
	* printcmd.c (clear_dangling_display_expressions): Act upon free_objfile
	events instead of solib_unloaded events.
	(_initialize_printcmd): Register observer for free_objfile instead
	of solib_unloaded notifications.
	* solib.c (remove_user_added_objfile): New function.
	* symfile.c (remove_symbol_file_command): New command.
	(_initialize_symfile): Add remove-symbol-file.
gdb/doc
	* observer.texi: New free_objfile event.

Signed-off-by: Nicolas Blanc <nicolas.blanc@intel.com>
This commit is contained in:
Nicolas Blanc 2013-03-12 11:10:18 +01:00
parent 487ad57ccf
commit 63644780ba
7 changed files with 209 additions and 9 deletions

View File

@ -7475,9 +7475,9 @@ disable_breakpoints_in_shlibs (void)
}
}
/* Disable any breakpoints and tracepoints that are in an unloaded shared
library. Only apply to enabled breakpoints, disabled ones can just stay
disabled. */
/* Disable any breakpoints and tracepoints that are in SOLIB upon
notification of unloaded_shlib. Only apply to enabled breakpoints,
disabled ones can just stay disabled. */
static void
disable_breakpoints_in_unloaded_shlib (struct so_list *solib)
@ -7529,6 +7529,66 @@ disable_breakpoints_in_unloaded_shlib (struct so_list *solib)
}
}
/* Disable any breakpoints and tracepoints in OBJFILE upon
notification of free_objfile. Only apply to enabled breakpoints,
disabled ones can just stay disabled. */
static void
disable_breakpoints_in_freed_objfile (struct objfile *objfile)
{
struct breakpoint *b;
if (objfile == NULL)
return;
/* If the file is a shared library not loaded by the user then
solib_unloaded was notified and disable_breakpoints_in_unloaded_shlib
was called. In that case there is no need to take action again. */
if ((objfile->flags & OBJF_SHARED) && !(objfile->flags & OBJF_USERLOADED))
return;
ALL_BREAKPOINTS (b)
{
struct bp_location *loc;
int bp_modified = 0;
if (!is_breakpoint (b) && !is_tracepoint (b))
continue;
for (loc = b->loc; loc != NULL; loc = loc->next)
{
CORE_ADDR loc_addr = loc->address;
if (loc->loc_type != bp_loc_hardware_breakpoint
&& loc->loc_type != bp_loc_software_breakpoint)
continue;
if (loc->shlib_disabled != 0)
continue;
if (objfile->pspace != loc->pspace)
continue;
if (loc->loc_type != bp_loc_hardware_breakpoint
&& loc->loc_type != bp_loc_software_breakpoint)
continue;
if (is_addr_in_objfile (loc_addr, objfile))
{
loc->shlib_disabled = 1;
loc->inserted = 0;
mark_breakpoint_location_modified (loc);
bp_modified = 1;
}
}
if (bp_modified)
observer_notify_breakpoint_modified (b);
}
}
/* FORK & VFORK catchpoints. */
/* An instance of this type is used to represent a fork or vfork
@ -16007,6 +16067,7 @@ _initialize_breakpoint (void)
initialize_breakpoint_ops ();
observer_attach_solib_unloaded (disable_breakpoints_in_unloaded_shlib);
observer_attach_free_objfile (disable_breakpoints_in_freed_objfile);
observer_attach_inferior_exit (clear_syscall_counts);
observer_attach_memory_changed (invalidate_bp_value_on_memory_change);

View File

@ -138,6 +138,10 @@ Called with @var{objfile} equal to @code{NULL} to indicate
previously loaded symbol table data has now been invalidated.
@end deftypefun
@deftypefun void free_objfile (struct objfile *@var{objfile})
The object file specified by @var{objfile} is about to be freed.
@end deftypefun
@deftypefun void new_thread (struct thread_info *@var{t})
The thread specified by @var{t} has been created.
@end deftypefun

View File

@ -548,6 +548,9 @@ free_objfile_separate_debug (struct objfile *objfile)
void
free_objfile (struct objfile *objfile)
{
/* First notify observers that this objfile is about to be freed. */
observer_notify_free_objfile (objfile);
/* Free all separate debug objfiles. */
free_objfile_separate_debug (objfile);
@ -1464,6 +1467,29 @@ resume_section_map_updates_cleanup (void *arg)
resume_section_map_updates (arg);
}
/* Return 1 if ADDR maps into one of the sections of OBJFILE and 0
otherwise. */
int
is_addr_in_objfile (CORE_ADDR addr, const struct objfile *objfile)
{
struct obj_section *osect;
if (objfile == NULL)
return 0;
ALL_OBJFILE_OSECTIONS (objfile, osect)
{
if (section_is_overlay (osect) && !section_is_mapped (osect))
continue;
if (obj_section_addr (osect) <= addr
&& addr < obj_section_endaddr (osect))
return 1;
}
return 0;
}
/* The default implementation for the "iterate_over_objfiles_in_search_order"
gdbarch method. It is equivalent to use the ALL_OBJFILES macro,
searching the objfiles in the order they are stored internally,

View File

@ -485,6 +485,8 @@ extern void objfile_set_sym_fns (struct objfile *objfile,
extern void objfiles_changed (void);
extern int is_addr_in_objfile (CORE_ADDR addr, const struct objfile *objfile);
/* This operation deletes all objfile entries that represent solibs that
weren't explicitly loaded by the user, via e.g., the add-symbol-file
command. */

View File

@ -1940,21 +1940,24 @@ disable_display_command (char *args, int from_tty)
an item by re-parsing .exp_string field in the new execution context. */
static void
clear_dangling_display_expressions (struct so_list *solib)
clear_dangling_display_expressions (struct objfile *objfile)
{
struct objfile *objfile = solib->objfile;
struct display *d;
struct program_space *pspace;
/* With no symbol file we cannot have a block or expression from it. */
if (objfile == NULL)
return;
pspace = objfile->pspace;
if (objfile->separate_debug_objfile_backlink)
objfile = objfile->separate_debug_objfile_backlink;
gdb_assert (objfile->pspace == solib->pspace);
{
objfile = objfile->separate_debug_objfile_backlink;
gdb_assert (objfile->pspace == pspace);
}
for (d = display_chain; d != NULL; d = d->next)
{
if (d->pspace != solib->pspace)
if (d->pspace != pspace)
continue;
if (lookup_objfile_from_block (d->block) == objfile
@ -2487,7 +2490,7 @@ _initialize_printcmd (void)
current_display_number = -1;
observer_attach_solib_unloaded (clear_dangling_display_expressions);
observer_attach_free_objfile (clear_dangling_display_expressions);
add_info ("address", address_info,
_("Describe where symbol SYM is stored."));

View File

@ -1496,6 +1496,23 @@ gdb_bfd_lookup_symbol (bfd *abfd,
return symaddr;
}
/* SO_LIST_HEAD may contain user-loaded object files that can be removed
out-of-band by the user. So upon notification of free_objfile remove
all references to any user-loaded file that is about to be freed. */
static void
remove_user_added_objfile (struct objfile *objfile)
{
struct so_list *so;
if (objfile != 0 && objfile->flags & OBJF_USERLOADED)
{
for (so = so_list_head; so != NULL; so = so->next)
if (so->objfile == objfile)
so->objfile = NULL;
}
}
extern initialize_file_ftype _initialize_solib; /* -Wmissing-prototypes */
void
@ -1503,6 +1520,8 @@ _initialize_solib (void)
{
solib_data = gdbarch_data_register_pre_init (solib_init);
observer_attach_free_objfile (remove_user_added_objfile);
add_com ("sharedlibrary", class_files, sharedlibrary_command,
_("Load shared object library symbols for files matching REGEXP."));
add_info ("sharedlibrary", info_sharedlibrary_command,

View File

@ -2342,6 +2342,82 @@ add_symbol_file_command (char *args, int from_tty)
}
/* This function removes a symbol file that was added via add-symbol-file. */
static void
remove_symbol_file_command (char *args, int from_tty)
{
char **argv;
struct objfile *objf = NULL;
struct cleanup *my_cleanups;
struct program_space *pspace = current_program_space;
struct gdbarch *gdbarch = get_current_arch ();
dont_repeat ();
if (args == NULL)
error (_("remove-symbol-file: no symbol file provided"));
my_cleanups = make_cleanup (null_cleanup, NULL);
argv = gdb_buildargv (args);
if (strcmp (argv[0], "-a") == 0)
{
/* Interpret the next argument as an address. */
CORE_ADDR addr;
if (argv[1] == NULL)
error (_("Missing address argument"));
if (argv[2] != NULL)
error (_("Junk after %s"), argv[1]);
addr = parse_and_eval_address (argv[1]);
ALL_OBJFILES (objf)
{
if (objf != 0
&& objf->flags & OBJF_USERLOADED
&& objf->pspace == pspace && is_addr_in_objfile (addr, objf))
break;
}
}
else if (argv[0] != NULL)
{
/* Interpret the current argument as a file name. */
char *filename;
if (argv[1] != NULL)
error (_("Junk after %s"), argv[0]);
filename = tilde_expand (argv[0]);
make_cleanup (xfree, filename);
ALL_OBJFILES (objf)
{
if (objf != 0
&& objf->flags & OBJF_USERLOADED
&& objf->pspace == pspace
&& filename_cmp (filename, objfile_name (objf)) == 0)
break;
}
}
if (objf == NULL)
error (_("No symbol file found"));
if (from_tty
&& !query (_("Remove symbol table from file \"%s\"? "),
objfile_name (objf)))
error (_("Not confirmed."));
free_objfile (objf);
clear_symtab_users (0);
do_cleanups (my_cleanups);
}
typedef struct objfile *objfilep;
DEF_VEC_P (objfilep);
@ -3764,6 +3840,15 @@ with the text. SECT is a section name to be loaded at SECT_ADDR."),
&cmdlist);
set_cmd_completer (c, filename_completer);
c = add_cmd ("remove-symbol-file", class_files,
remove_symbol_file_command, _("\
Remove a symbol file added via the add-symbol-file command.\n\
Usage: remove-symbol-file FILENAME\n\
remove-symbol-file -a ADDRESS\n\
The file to remove can be identified by its filename or by an address\n\
that lies within the boundaries of this symbol file in memory."),
&cmdlist);
c = add_cmd ("load", class_files, load_command, _("\
Dynamically load FILE into the running program, and record its symbols\n\
for access from GDB.\n\