From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28268 invoked by alias); 18 Oct 2013 13:41:03 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 28222 invoked by uid 89); 18 Oct 2013 13:41:03 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.4 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mga02.intel.com Received: from mga02.intel.com (HELO mga02.intel.com) (134.134.136.20) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 18 Oct 2013 13:41:00 +0000 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP; 18 Oct 2013 06:40:58 -0700 X-ExtLoop1: 1 Received: from irvmail001.ir.intel.com ([163.33.26.43]) by orsmga001.jf.intel.com with ESMTP; 18 Oct 2013 06:40:39 -0700 Received: from ulvlx001.iul.intel.com (ulvlx001.iul.intel.com [172.28.207.17]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id r9IDec9E020863; Fri, 18 Oct 2013 14:40:38 +0100 Received: from ulvlx001.iul.intel.com (localhost [127.0.0.1]) by ulvlx001.iul.intel.com with ESMTP id r9IDebuP015348; Fri, 18 Oct 2013 15:40:38 +0200 Received: (from nblanc@localhost) by ulvlx001.iul.intel.com with œ id r9IDebT0015344; Fri, 18 Oct 2013 15:40:37 +0200 From: Nicolas Blanc To: tromey@redhat.com Cc: gdb-patches@sourceware.org, Nicolas Blanc Subject: [PATCH v17 1/5] New remove-symbol-file command. Date: Fri, 18 Oct 2013 13:41:00 -0000 Message-Id: <1382103635-15300-2-git-send-email-nicolas.blanc@intel.com> In-Reply-To: <1382103635-15300-1-git-send-email-nicolas.blanc@intel.com> References: <1382103635-15300-1-git-send-email-nicolas.blanc@intel.com> X-IsSubscribed: yes X-SW-Source: 2013-10/txt/msg00559.txt.bz2 New command for removing symbol files added via the add-symbol-file command. 2013-14-10 Nicolas Blanc * 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 --- gdb/breakpoint.c | 67 +++++++++++++++++++++++++++++++++++++-- gdb/doc/observer.texi | 4 ++ gdb/objfiles.c | 26 +++++++++++++++ gdb/objfiles.h | 2 + gdb/printcmd.c | 15 +++++--- gdb/solib.c | 19 +++++++++++ gdb/symfile.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 209 insertions(+), 9 deletions(-) diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 5ce50de..f480c5b 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -7468,9 +7468,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) @@ -7522,6 +7522,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 @@ -15997,6 +16057,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); diff --git a/gdb/doc/observer.texi b/gdb/doc/observer.texi index adb7085..f753965 100644 --- a/gdb/doc/observer.texi +++ b/gdb/doc/observer.texi @@ -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 diff --git a/gdb/objfiles.c b/gdb/objfiles.c index d1f3121..079b0fe 100644 --- a/gdb/objfiles.c +++ b/gdb/objfiles.c @@ -552,6 +552,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); @@ -1468,6 +1471,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, diff --git a/gdb/objfiles.h b/gdb/objfiles.h index 08771d0..9bca812 100644 --- a/gdb/objfiles.h +++ b/gdb/objfiles.h @@ -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. */ diff --git a/gdb/printcmd.c b/gdb/printcmd.c index 9bca6dd..7354474 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -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.")); diff --git a/gdb/solib.c b/gdb/solib.c index 8ed492a..06e0b16 100644 --- a/gdb/solib.c +++ b/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, diff --git a/gdb/symfile.c b/gdb/symfile.c index d260ff9..0318466 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -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\ -- 1.7.6.5