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:
parent
487ad57ccf
commit
63644780ba
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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. */
|
||||
|
@ -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."));
|
||||
|
19
gdb/solib.c
19
gdb/solib.c
@ -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,
|
||||
|
@ -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\
|
||||
|
Loading…
Reference in New Issue
Block a user