* [PATCH 2/3] Test adding and removing a symbol file at runtime.
2013-04-16 11:22 [PATCH 0/3] remove-symbol-file Nicolas Blanc
@ 2013-04-16 11:51 ` Nicolas Blanc
2013-04-24 12:18 ` Tom Tromey
2013-04-16 12:18 ` [PATCH 1/3] Command remove-symbol-file Nicolas Blanc
` (4 subsequent siblings)
5 siblings, 1 reply; 25+ messages in thread
From: Nicolas Blanc @ 2013-04-16 11:51 UTC (permalink / raw)
To: gdb-patches; +Cc: Nicolas Blanc
This test exercises the commands 'add-symbol-file'
and 'remove-symbol-file'.
2013-04-04 Nicolas Blanc <nicolas.blanc@intel.com>
gdb/testsuite
* gdb.base/sym-file-lib.c: New file.
* gdb.base/sym-file-lib.c: New file.
* gdb.base/sym-file.exp: New file.
Signed-off-by: Nicolas Blanc <nicolas.blanc@intel.com>
---
gdb/testsuite/gdb.base/sym-file-lib.c | 21 ++
gdb/testsuite/gdb.base/sym-file-main.c | 369 ++++++++++++++++++++++++++++++++
gdb/testsuite/gdb.base/sym-file.exp | 155 +++++++++++++
3 files changed, 545 insertions(+), 0 deletions(-)
create mode 100644 gdb/testsuite/gdb.base/sym-file-lib.c
create mode 100644 gdb/testsuite/gdb.base/sym-file-main.c
create mode 100644 gdb/testsuite/gdb.base/sym-file.exp
diff --git a/gdb/testsuite/gdb.base/sym-file-lib.c b/gdb/testsuite/gdb.base/sym-file-lib.c
new file mode 100644
index 0000000..32426b9
--- /dev/null
+++ b/gdb/testsuite/gdb.base/sym-file-lib.c
@@ -0,0 +1,21 @@
+/* Copyright 2013 Free Software Foundation, Inc.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+extern int bar () { return 1; } /* gdb break at bar */
+
+
+extern int foo (int a) { return a; } /* gdb break at foo */
+
diff --git a/gdb/testsuite/gdb.base/sym-file-main.c b/gdb/testsuite/gdb.base/sym-file-main.c
new file mode 100644
index 0000000..a42f807
--- /dev/null
+++ b/gdb/testsuite/gdb.base/sym-file-main.c
@@ -0,0 +1,369 @@
+/* Copyright 2013 Free Software Foundation, Inc.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <fcntl.h>
+#include </usr/include/elf.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+
+#ifdef TARGET_LP64
+typedef Elf64_Phdr Elf_Phdr;
+typedef Elf64_Ehdr Elf_Ehdr;
+typedef Elf64_Shdr Elf_Shdr;
+typedef Elf64_Sym Elf_Sym;
+typedef Elf64_Word Elf_Word;
+
+unsigned char inline elf_st_type (unsigned char st_info)
+{
+ return ELF64_ST_TYPE (st_info);
+}
+#elif defined TARGET_ILP32
+typedef Elf32_Phdr Elf_Phdr;
+typedef Elf32_Ehdr Elf_Ehdr;
+typedef Elf32_Shdr Elf_Shdr;
+typedef Elf32_Sym Elf_Sym;
+typedef Elf32_Word Elf_Word;
+
+unsigned char inline elf_st_type (unsigned char st_info)
+{
+ return ELF32_ST_TYPE (st_info);
+}
+#endif
+
+
+void gdb_add_symbol_file (void* addr, const char* file)
+{
+ return;
+}
+
+
+void gdb_remove_symbol_file (void* addr)
+{
+ return;
+}
+
+
+struct segment
+{
+ char* mapped_addr;
+ Elf_Phdr* phdr;
+ struct segment* next;
+};
+
+
+/* Load a program segment. */
+struct segment* load (char * addr, Elf_Phdr* phdr, struct segment* tail_seg)
+{
+ /* For the sake of simplicity all operations are permitted. */
+ unsigned perm = PROT_READ | PROT_WRITE | PROT_EXEC;
+
+ char* mapped_addr = (char*) mmap ((void*) phdr->p_vaddr,
+ phdr->p_memsz, perm,
+ MAP_ANONYMOUS | MAP_PRIVATE,
+ -1, 0);
+
+ void * from = (void*) (addr + phdr->p_offset);
+ void * to = (void*) mapped_addr;
+
+ memcpy (to, from, phdr->p_filesz);
+
+ struct segment* seg = (struct segment*) malloc (sizeof (struct segment));
+
+ if (seg == 0)
+ return 0;
+
+ seg->mapped_addr = mapped_addr;
+ seg->phdr = phdr;
+ seg->next = 0;
+
+ if (tail_seg != 0)
+ tail_seg->next = seg;
+
+ return seg;
+}
+
+/* Load a shared library without calling the standard loader. */
+int load_shlib (const char *file, Elf_Ehdr **ehdr_out, struct segment **seg_out)
+{
+ unsigned i = 0;
+
+ /* Map the lib in memory for reading. */
+ int fd = open (file, O_RDONLY);
+ if (fd < 0)
+ {
+ perror ("fopen failed.");
+ return -1;
+ }
+
+ off_t fsize = lseek (fd, 0, SEEK_END);
+
+ if (fsize < 0)
+ {
+ perror ("lseek failed.");
+ return -1;
+ }
+
+ char* addr = (char*) mmap (NULL, fsize, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (addr == (char*) -1)
+ {
+ perror ("mmap failed.");
+ return -1;
+ }
+
+ /* Check if the lib is an ELF file. */
+ Elf_Ehdr* ehdr = (Elf_Ehdr*) addr;
+ if (ehdr->e_ident[EI_MAG0] != ELFMAG0
+ || ehdr->e_ident[EI_MAG1] != ELFMAG1
+ || ehdr->e_ident[EI_MAG2] != ELFMAG2
+ || ehdr->e_ident[EI_MAG3] != ELFMAG3)
+ {
+ printf ("Not an ELF file: %x\n", ehdr->e_ident[EI_MAG0]);
+ return -1;
+ }
+
+ if (ehdr->e_ident[EI_CLASS] == ELFCLASS32)
+ {
+ if (sizeof (int*) != 4)
+ {
+ printf ("Architecture mismatch.");
+ return -1;
+ }
+ }
+ else if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
+ {
+ if (sizeof (int*) != 8)
+ {
+ printf ("Architecture mismatch.");
+ return -1;
+ }
+ }
+
+
+ /* Load the program segments. For the sake of simplicity
+ assume that no reallocation is needed. */
+ Elf_Phdr* phdr = (Elf_Phdr*) (addr + ehdr->e_phoff);
+ struct segment* head_seg = 0;
+ struct segment* tail_seg = 0;
+ for (i=0; i < ehdr->e_phnum; i++, phdr++)
+ {
+ if (phdr->p_type == PT_LOAD)
+ {
+ struct segment* next_seg = load (addr, phdr, tail_seg);
+ if (next_seg == 0)
+ continue;
+ tail_seg = next_seg;
+ if (head_seg == 0)
+ head_seg = next_seg;
+ }
+ }
+ *ehdr_out = ehdr;
+ *seg_out = head_seg;
+ return 0;
+}
+
+
+/* Return the section-header table. */
+Elf_Shdr* find_shdrtab (Elf_Ehdr *ehdr)
+{
+ return (Elf_Shdr*) (((char*) ehdr) + ehdr->e_shoff);
+}
+
+
+/* Return the string table of the section headers. */
+const char* find_shstrtab (Elf_Ehdr *ehdr, unsigned *size)
+{
+ const Elf_Shdr *shdr = find_shdrtab (ehdr);
+
+ if (ehdr->e_shnum <= ehdr->e_shstrndx)
+ {
+ printf ("The index of the string table is corrupt.");
+ return NULL;
+ }
+ const Elf_Shdr* shstr = &shdr[ehdr->e_shstrndx];
+ *size = shstr->sh_size;
+ return ((const char*) ehdr) + shstr->sh_offset;
+}
+
+
+/* Return the string table named SECTION. */
+const char* find_strtab (Elf_Ehdr *ehdr,
+ const char* shstrtab, unsigned shstrtab_size,
+ const char* section, unsigned *strtab_size)
+{
+ const Elf_Shdr* shdr = find_shdrtab (ehdr);
+ unsigned i = 0;
+ for (i=0; i < ehdr->e_shnum; i++)
+ {
+ Elf_Word name = shdr[i].sh_name;
+ if (shdr[i].sh_type == SHT_STRTAB && name <= shstrtab_size
+ && strcmp ((const char*) &shstrtab[name], section) == 0)
+ {
+ *strtab_size = shdr[i].sh_size;
+ return ((const char*) ehdr) + shdr[i].sh_offset;
+ }
+
+ }
+ return NULL;
+}
+
+
+/* Return the section header named SECTION. */
+Elf_Shdr* find_shdr (Elf_Ehdr* ehdr, const char *section,
+ const char *shstrtab, unsigned shstrtab_size)
+{
+ Elf_Shdr *shdr = find_shdrtab (ehdr);
+ unsigned i = 0;
+ for (i=0; i < ehdr->e_shnum; i++)
+ {
+ Elf_Word name = shdr[i].sh_name;
+ if (name <= shstrtab_size)
+ {
+ if (strcmp ((const char*) &shstrtab[name], section) == 0)
+ return &shdr[i];
+ }
+
+ }
+ return NULL;
+}
+
+/* Return the symbol table. */
+Elf_Sym* find_symtab (Elf_Ehdr* ehdr, unsigned *symtab_size)
+{
+ unsigned i = 0;
+ const Elf_Shdr *shdr = find_shdrtab (ehdr);
+ for (i=0; i < ehdr->e_shnum; i++)
+ {
+ if (shdr[i].sh_type == SHT_SYMTAB)
+ {
+ *symtab_size = shdr[i].sh_size / sizeof (Elf_Sym);
+ return (Elf_Sym*) (((const char*) ehdr) + shdr[i].sh_offset);
+ }
+ }
+ return NULL;
+}
+
+
+/* Lookup the offset of FUNC. */
+int lookup_function (const char *func,
+ Elf_Sym *symtab, unsigned symtab_size,
+ const char *strtab, unsigned strtab_size,
+ unsigned *offset)
+{
+ unsigned i = 0;
+ for (i=0; i < symtab_size; i++)
+ {
+ Elf_Sym* sym = &symtab[i];
+
+ if (elf_st_type (sym->st_info) != STT_FUNC)
+ continue;
+
+ if (sym->st_name < strtab_size)
+ {
+ const char* name = &strtab[sym->st_name];
+ if (strcmp (name, func) == 0)
+ {
+ *offset = (unsigned) sym->st_value;
+ return 0;
+ }
+ }
+ }
+
+ return -1;
+}
+
+
+int main (int argc, const char* argv[])
+{
+ /* Load a shared library without relying on the standard
+ loader to test GDB's commands for adding and removing
+ symbol files at runtime. */
+
+ const char *file = SHLIB_NAME;
+
+ Elf_Ehdr *ehdr = 0;
+ struct segment *head_seg = 0;
+
+ if (load_shlib (file, &ehdr, &head_seg) != 0)
+ return -1;
+
+ /* Get the string table for the section headers. */
+ unsigned shstrtab_size = 0;
+ const char* shstrtab = find_shstrtab (ehdr, &shstrtab_size);
+
+ if (shstrtab == NULL)
+ return -1;
+
+ /* Get the text section. */
+ Elf_Shdr* text = find_shdr (ehdr, ".text", shstrtab, shstrtab_size);
+ if (text == NULL)
+ return -1;
+
+ char* base_addr = head_seg->mapped_addr + text->sh_offset;
+
+ /* Notify GDB to add the symbol file. */
+ gdb_add_symbol_file (base_addr, file);
+
+ /* Get the string table for the symbols. */
+ unsigned strtab_size = 0;
+ const char* strtab = find_strtab (ehdr, shstrtab, shstrtab_size,
+ ".strtab", &strtab_size);
+ if (strtab == NULL)
+ {
+ printf (".strtab not found.");
+ return -1;
+ }
+
+ /* Get the symbol table. */
+ unsigned symtab_size = 0;
+ Elf_Sym* symtab = find_symtab (ehdr, &symtab_size);
+ if (symtab == NULL)
+ {
+ printf ("symtab not found.");
+ return -1;
+ }
+
+ /* Call BAR from SHLIB_NAME. */
+ unsigned bar_offset = 0;
+ if (lookup_function ("bar",
+ symtab, symtab_size,
+ strtab, strtab_size,
+ &bar_offset) != 0)
+ return -1;
+
+ int (*pbar) () = (int (*) ()) (head_seg->mapped_addr + bar_offset);
+
+ int value1 = (*pbar) ();
+
+
+ /* Call FOO from SHLIB_NAME. */
+ unsigned foo_offset = 0;
+ if (lookup_function ("foo",
+ symtab, symtab_size,
+ strtab, strtab_size,
+ &foo_offset) != 0)
+ return -1;
+
+ int (*pfoo) (int) = (int (*) (int)) (head_seg->mapped_addr + foo_offset);
+
+ int value2 = (*pfoo) (2);
+
+ /* Notify GDB to remove the symbol file. */
+ gdb_remove_symbol_file (base_addr);
+
+ return 0;
+}
+
diff --git a/gdb/testsuite/gdb.base/sym-file.exp b/gdb/testsuite/gdb.base/sym-file.exp
new file mode 100644
index 0000000..2c995a4
--- /dev/null
+++ b/gdb/testsuite/gdb.base/sym-file.exp
@@ -0,0 +1,155 @@
+# Copyright 2013 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+
+# Test adding and removing a symbol file dynamically:
+# 1) Load the main executable.
+# 2) Run to GDB_ADD_SYMBOl_FILE in $srcfile.
+# 3) Set a pending breakpoint at BAR in $libsrc.
+# 4) Load $shlib_name using 'add-symbol-file'.
+# 5) Continue to BAR in $libsrc.
+# 6) Set a breakpiont at FOO in $librc.
+# 7) Continue to FOO in $libsrc.
+# 8) Set a breakpoint at GDB_REMOVE_SYMBOL_FILE.
+# 9) Continue to GDB_REMOVE_SYMBOL_FILE in $srcfile.
+# 10) Remove $shlib_name using 'remove-symbol-file'.
+# 11) Check that the breakpoints at FOO and BAR are pending.
+# 12) Check that the execution can continue without error.
+
+
+if [skip_shlib_tests] {
+ return 0
+}
+
+
+if [is_remote target] {
+ return 0
+}
+
+set target_size TARGET_UNKNOWN
+if [is_lp64_target] {
+ set target_size TARGET_LP64
+} elseif [is_ilp32_target] {
+ set target_size TARGET_ILP32
+} else {
+ return 0
+}
+
+set testfile sym-file-main
+set libfile sym-file-lib
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+
+set libsrc "${srcdir}/${subdir}/${libfile}.c"
+set libname "${libfile}.so"
+set shlib_name "${objdir}/${subdir}/${libname}"
+set libobj "${objdir}/${subdir}/${libname}"
+set execsrc "${srcdir}/${subdir}/${srcfile}"
+set exec_opts [list debug "additional_flags=-D$target_size -DSHLIB_NAME\\=\"$shlib_name\""]
+
+remote_exec build "rm -f ${binfile}"
+
+if [get_compiler_info] {
+ return -1
+}
+
+
+if { [gdb_compile_shlib $libsrc $libobj {debug}] != ""
+ || [gdb_compile $execsrc ${binfile} executable $exec_opts] != "" } {
+ untested ${testfile}
+ return
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+# 1) Load the main executable.
+set result [gdb_load ${binfile}]
+if { $result != 0 } then {
+ return
+}
+
+# 2) Run to GDB_ADD_SYMBOl_FILE in $srcfile for adding
+# $shlib_name.
+set result [runto gdb_add_symbol_file]
+if { !$result } then {
+ return
+}
+
+# 3) Set a pending breakpoint at BAR in $libsrc.
+set result [gdb_breakpoint bar allow-pending]
+if { !$result } then {
+ return
+}
+
+# 4) Add $shlib_name using 'add-symbol-file'.
+set result [gdb_test "add-symbol-file ${shlib_name} addr" \
+ "Reading symbols from .*${shlib_name}\\.\\.\\.done\\." \
+ "add-symbol-file ${shlib_name}.*" \
+ "add symbol table from file \".*${shlib_name}\"\
+ at.*\\(y or n\\) " \
+ "y"]
+if { $result != 0 } then {
+ return
+}
+
+# 5) Continue to BAR in $libsrc to ensure that the breakpoint
+# was bound correctly after adding $shilb_name.
+set lnum_bar [gdb_get_line_number "break at bar" $libsrc]
+gdb_continue_to_breakpoint bar ".*$libfile\\.c:$lnum_bar.*"
+
+# 6) Set a breakpoint at FOO in $libsrc.
+set result [gdb_breakpoint foo]
+if { !$result } then {
+ return
+}
+
+# 7) Continue to FOO in $libsrc to ensure that the breakpoint
+# was bound correctly.
+set lnum_foo [gdb_get_line_number "break at foo" $libsrc]
+gdb_continue_to_breakpoint foo ".*$libfile\\.c:$lnum_foo.*"
+
+
+# 8) Set a breakpint at GDB_REMOVE_SYMBOL_FILE in $srcfile for
+# removing $shlib_name.
+set result [gdb_breakpoint gdb_remove_symbol_file]
+if { !$result } then {
+ return
+}
+
+# 9) Continue to GDB_REMOVE_SYMBOL_FILE in $srcfile.
+gdb_continue_to_breakpoint gdb_remove_symbol_file
+
+# 10) Remove $shlib_name using 'remove-symbol-file'.
+set result [gdb_test "remove-symbol-file addr" ""]
+if { $result != 0 } then {
+ return
+}
+
+# 11) Check that the breakpoints at FOO and BAR are pending after removing
+# $shlib_name.
+gdb_test "info breakpoints 2" \
+ ".*PENDING.*" \
+ "check if Breakpoint 2 is pending."
+
+gdb_test "info breakpoints 3" \
+ ".*PENDING.*" \
+ "check if Breakpoint 3 is pending."
+
+# 12) Check that the execution can continue without error.
+gdb_continue_to_end
+
+
--
1.7.6.5
^ permalink raw reply [flat|nested] 25+ messages in thread* Re: [PATCH 2/3] Test adding and removing a symbol file at runtime.
2013-04-16 11:51 ` [PATCH 2/3] Test adding and removing a symbol file at runtime Nicolas Blanc
@ 2013-04-24 12:18 ` Tom Tromey
2013-04-24 12:18 ` Tom Tromey
0 siblings, 1 reply; 25+ messages in thread
From: Tom Tromey @ 2013-04-24 12:18 UTC (permalink / raw)
To: Nicolas Blanc; +Cc: gdb-patches
>>>>> "Nicolas" == Nicolas Blanc <nicolas.blanc@intel.com> writes:
Nicolas> This test exercises the commands 'add-symbol-file'
Nicolas> and 'remove-symbol-file'.
Thank you.
Nicolas> +#include </usr/include/elf.h>
This line seems wrong.
It seems simpler to do the test by using an ordinary .so and then
calling remove-symbol-file on it. Then perhaps it could even work on
some non-ELF systems. Would this not work for some reason?
Nicolas> +# 6) Set a breakpiont at FOO in $librc.
Two typos, "breakpoint" and "$libsrc".
Nicolas> +set testfile sym-file-main
Nicolas> +set libfile sym-file-lib
Nicolas> +set srcfile ${testfile}.c
Nicolas> +set binfile ${objdir}/${subdir}/${testfile}
Nicolas> +
Nicolas> +set libsrc "${srcdir}/${subdir}/${libfile}.c"
Nicolas> +set libname "${libfile}.so"
Nicolas> +set shlib_name "${objdir}/${subdir}/${libname}"
Nicolas> +set libobj "${objdir}/${subdir}/${libname}"
Nicolas> +set execsrc "${srcdir}/${subdir}/${srcfile}"
This should use standard_testfile and standard_output_file.
Nicolas> +gdb_exit
Nicolas> +gdb_start
Nicolas> +gdb_reinitialize_dir $srcdir/$subdir
Nicolas> +
Nicolas> +# 1) Load the main executable.
Nicolas> +set result [gdb_load ${binfile}]
Nicolas> +if { $result != 0 } then {
Nicolas> + return
Nicolas> +}
clean_restart
Nicolas> +# 6) Set a breakpoint at FOO in $libsrc.
Nicolas> +set result [gdb_breakpoint foo]
Nicolas> +if { !$result } then {
Nicolas> + return
I think most .exp files don't bother checking each result like this.
It is enough for one thing to report a fail; the test may limp on.
That said I don't really mind either way.
Tom
^ permalink raw reply [flat|nested] 25+ messages in thread* Re: [PATCH 2/3] Test adding and removing a symbol file at runtime.
2013-04-24 12:18 ` Tom Tromey
@ 2013-04-24 12:18 ` Tom Tromey
0 siblings, 0 replies; 25+ messages in thread
From: Tom Tromey @ 2013-04-24 12:18 UTC (permalink / raw)
To: Nicolas Blanc; +Cc: gdb-patches
>>>>> "Tom" == Tom Tromey <tromey@redhat.com> writes:
Tom> It seems simpler to do the test by using an ordinary .so and then
Tom> calling remove-symbol-file on it. Then perhaps it could even work on
Tom> some non-ELF systems. Would this not work for some reason?
Ok, I see. Patch #1 enforces that the objfile must be OBJF_USERLOADED.
Is this restriction needed? It seems to me that having
remove-symbol-file work as a limited form of "nosharedlibraries" would
be useful at times.
Tom
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 1/3] Command remove-symbol-file.
2013-04-16 11:22 [PATCH 0/3] remove-symbol-file Nicolas Blanc
2013-04-16 11:51 ` [PATCH 2/3] Test adding and removing a symbol file at runtime Nicolas Blanc
@ 2013-04-16 12:18 ` Nicolas Blanc
2013-04-16 13:25 ` [PATCH 1/3] Added command remove-symbol-file Nicolas Blanc
` (3 subsequent siblings)
5 siblings, 0 replies; 25+ messages in thread
From: Nicolas Blanc @ 2013-04-16 12:18 UTC (permalink / raw)
To: gdb-patches; +Cc: Nicolas Blanc
Added command remove-symbol-file for removing
symbol files added via the add-symbol-file command.
2013-18-03 Nicolas Blanc <nicolas.blanc@intel.com>
* breakpoint.c (disable_breakpoints_in_free_objfile): Created
function for disabling breakoints in objfiles upon FREE_OBJFILE
notifications.
* doc/observer.text: Created FREE_OBJFILE event.
* objfiles.c (free_objfile): Notify FREE_OBJFILE.
* 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): Created function for removing
dangling references upon notification of FREE_OBJFILE.
* symfile.c (add_symbol_file_command): Set OBJFILE->LOW_ADDRESS.
(remove_symbol_file_command): Created command for removing symbol files.
(_initialize_symfile): Added remove-symbol-file.
Signed-off-by: Nicolas Blanc <nicolas.blanc@intel.com>
---
gdb/breakpoint.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++--
gdb/doc/observer.texi | 4 +++
gdb/objfiles.c | 3 ++
gdb/printcmd.c | 11 ++++----
gdb/solib.c | 26 +++++++++++++++++++
gdb/symfile.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++-
6 files changed, 163 insertions(+), 9 deletions(-)
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 09933f4..b09049e 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -7430,9 +7430,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)
@@ -7484,6 +7484,64 @@ 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_free_objfile (struct objfile * objfile)
+{
+ struct bp_location *loc, **locp_tmp;
+
+ if (objfile == NULL)
+ return;
+
+ /* If the file is a shared library not loaded by the user then
+ SOLIB_UNLOADED was notified and DISABLE_BREAKPIONTS_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_BP_LOCATIONS (loc, locp_tmp)
+ {
+ struct obj_section *osect;
+ CORE_ADDR loc_addr = loc->address;
+
+ /* ALL_BP_LOCATIONS bp_location has LOC->OWNER always non-NULL. */
+ struct breakpoint *b = loc->owner;
+
+ if (loc->shlib_disabled != 0)
+ continue;
+
+ if (objfile->pspace != loc->pspace)
+ continue;
+
+ if (!is_tracepoint(b))
+ {
+ if (b->type != bp_breakpoint
+ && b->type != bp_jit_event
+ && b->type != bp_hardware_breakpoint)
+ continue;
+
+ if (loc->loc_type != bp_loc_hardware_breakpoint
+ && loc->loc_type != bp_loc_software_breakpoint)
+ continue;
+ }
+
+ ALL_OBJFILE_OSECTIONS (objfile, osect)
+ {
+ if (obj_section_addr (osect) <= loc_addr
+ && loc_addr < obj_section_endaddr (osect))
+ {
+ loc->shlib_disabled = 1;
+ loc->inserted = 0;
+ observer_notify_breakpoint_modified (loc->owner);
+ break;
+ }
+ }
+ }
+}
+
/* FORK & VFORK catchpoints. */
/* An instance of this type is used to represent a fork or vfork
@@ -16030,6 +16088,7 @@ _initialize_breakpoint (void)
initialize_breakpoint_ops ();
observer_attach_solib_unloaded (disable_breakpoints_in_unloaded_shlib);
+ observer_attach_free_objfile (disable_breakpoints_in_free_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..7b420ea 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 symbol 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 93b7ba7..0a0c2c0 100644
--- a/gdb/objfiles.c
+++ b/gdb/objfiles.c
@@ -530,6 +530,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);
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 4f8c9d4..0165487 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -1928,21 +1928,22 @@ 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);
+ 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
@@ -2474,7 +2475,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 8129c0f..c528f87 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -1448,6 +1448,30 @@ gdb_bfd_lookup_symbol (bfd *abfd,
return symaddr;
}
+/* Upon notification of FREE_OBJFILE remove any reference
+ to any user-added file that is about to be freed. */
+static void
+remove_user_added_objfile (struct objfile *objfile)
+{
+ struct so_list *gdb;
+
+ if (!objfile)
+ return;
+
+ if (!(objfile->flags & OBJF_USERLOADED)
+ || !(objfile->flags & OBJF_SHARED))
+ return;
+
+ gdb = so_list_head;
+ while (gdb)
+ {
+ if (gdb->objfile == objfile)
+ gdb->objfile = NULL;
+ gdb = gdb->next;
+ }
+}
+
+
extern initialize_file_ftype _initialize_solib; /* -Wmissing-prototypes */
void
@@ -1455,6 +1479,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 3e66bd1..94013c0 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -91,6 +91,8 @@ static void symbol_file_add_main_1 (char *args, int from_tty, int flags);
static void add_symbol_file_command (char *, int);
+static void remove_symbol_file_command (char *, int);
+
bfd *symfile_bfd_open (char *);
int get_section_index (struct objfile *, char *);
@@ -2219,6 +2221,8 @@ add_symbol_file_command (char *args, int from_tty)
int expecting_sec_name = 0;
int expecting_sec_addr = 0;
char **argv;
+ CORE_ADDR addr_low = 0;
+ struct objfile *objf;
struct sect_opt
{
@@ -2267,6 +2271,7 @@ add_symbol_file_command (char *args, int from_tty)
num_sect_opts
* sizeof (struct sect_opt)));
}
+ addr_low = parse_and_eval_address (arg);
}
else
{
@@ -2354,9 +2359,12 @@ add_symbol_file_command (char *args, int from_tty)
if (from_tty && (!query ("%s", "")))
error (_("Not confirmed."));
- symbol_file_add (filename, from_tty ? SYMFILE_VERBOSE : 0,
+ objf = symbol_file_add (filename, from_tty ? SYMFILE_VERBOSE : 0,
section_addrs, flags);
+ /* Set the low address of the object for identification. */
+ objf->addr_low = addr_low;
+
/* Getting new symbols may change our opinion about what is
frameless. */
reinit_frame_cache ();
@@ -2364,6 +2372,54 @@ add_symbol_file_command (char *args, int from_tty)
}
\f
+
+/* 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;
+ char *arg;
+ int argcnt;
+ struct cleanup *my_cleanups;
+ CORE_ADDR addr = 0;
+ struct objfile* objf;
+
+ dont_repeat ();
+
+ if (args == NULL)
+ error (_("remove-symbol-file takes an address as parameter."));
+
+ my_cleanups = make_cleanup (null_cleanup, NULL);
+
+ argv = gdb_buildargv (args);
+ make_cleanup_freeargv (argv);
+
+ for (arg = argv[0], argcnt = 0; arg != NULL; arg = argv[++argcnt])
+ {
+ if (argcnt == 0)
+ addr = parse_and_eval_address (arg);
+ else
+ error (_("USAGE: remove-symbol-file <text_low_address>"));
+ }
+
+
+ ALL_OBJFILES (objf)
+ {
+ if (objf->flags & OBJF_USERLOADED && objf->addr_low == addr)
+ break;
+ }
+
+ if (!objf)
+ error (_("no user-added symbol file for address 0x%s"),
+ phex_nz(addr, sizeof(addr)));
+
+ free_objfile (objf);
+ clear_symtab_users (0);
+
+ do_cleanups (my_cleanups);
+}
+
+
typedef struct objfile *objfilep;
DEF_VEC_P (objfilep);
@@ -3777,6 +3833,11 @@ 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 loaded via the add-symbol-file command.\n\
+Usage: remove-symbol-file START_ADDR.\nSTART_ADDR is the start address \
+of the module to remove."), &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
^ permalink raw reply [flat|nested] 25+ messages in thread* [PATCH 1/3] Added command remove-symbol-file.
2013-04-16 11:22 [PATCH 0/3] remove-symbol-file Nicolas Blanc
2013-04-16 11:51 ` [PATCH 2/3] Test adding and removing a symbol file at runtime Nicolas Blanc
2013-04-16 12:18 ` [PATCH 1/3] Command remove-symbol-file Nicolas Blanc
@ 2013-04-16 13:25 ` Nicolas Blanc
2013-04-22 13:32 ` Yao Qi
` (2 more replies)
2013-04-16 14:18 ` [PATCH 3/3] Documentation for the remove-symbol-file command Nicolas Blanc
` (2 subsequent siblings)
5 siblings, 3 replies; 25+ messages in thread
From: Nicolas Blanc @ 2013-04-16 13:25 UTC (permalink / raw)
To: gdb-patches; +Cc: Nicolas Blanc
Added command remove-symbol-file for removing
symbol files added via the add-symbol-file command.
2013-18-03 Nicolas Blanc <nicolas.blanc@intel.com>
* breakpoint.c (disable_breakpoints_in_free_objfile): Created
function for disabling breakoints in objfiles upon FREE_OBJFILE
notifications.
* doc/observer.text: Created FREE_OBJFILE event.
* objfiles.c (free_objfile): Notify FREE_OBJFILE.
* 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): Created function for removing
dangling references upon notification of FREE_OBJFILE.
* symfile.c (add_symbol_file_command): Set OBJFILE->LOW_ADDRESS.
(remove_symbol_file_command): Created command for removing symbol files.
(_initialize_symfile): Added remove-symbol-file.
Change-Id: I91dad7d3306823b01c4023b4d63f6910ed858f69
Signed-off-by: Nicolas Blanc <nicolas.blanc@intel.com>
---
gdb/breakpoint.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++--
gdb/doc/observer.texi | 4 +++
gdb/objfiles.c | 3 ++
gdb/printcmd.c | 11 ++++----
gdb/solib.c | 26 +++++++++++++++++++
gdb/symfile.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++-
6 files changed, 165 insertions(+), 9 deletions(-)
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index f374368..d5c7b21 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -7430,9 +7430,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)
@@ -7484,6 +7484,64 @@ 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_free_objfile (struct objfile * objfile)
+{
+ struct bp_location *loc, **locp_tmp;
+
+ if (objfile == NULL)
+ return;
+
+ /* If the file is a shared library not loaded by the user then
+ SOLIB_UNLOADED was notified and DISABLE_BREAKPIONTS_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_BP_LOCATIONS (loc, locp_tmp)
+ {
+ struct obj_section *osect;
+ CORE_ADDR loc_addr = loc->address;
+
+ /* ALL_BP_LOCATIONS bp_location has LOC->OWNER always non-NULL. */
+ struct breakpoint *b = loc->owner;
+
+ if (loc->shlib_disabled != 0)
+ continue;
+
+ if (objfile->pspace != loc->pspace)
+ continue;
+
+ if (!is_tracepoint(b))
+ {
+ if (b->type != bp_breakpoint
+ && b->type != bp_jit_event
+ && b->type != bp_hardware_breakpoint)
+ continue;
+
+ if (loc->loc_type != bp_loc_hardware_breakpoint
+ && loc->loc_type != bp_loc_software_breakpoint)
+ continue;
+ }
+
+ ALL_OBJFILE_OSECTIONS (objfile, osect)
+ {
+ if (obj_section_addr (osect) <= loc_addr
+ && loc_addr < obj_section_endaddr (osect))
+ {
+ loc->shlib_disabled = 1;
+ loc->inserted = 0;
+ observer_notify_breakpoint_modified (loc->owner);
+ break;
+ }
+ }
+ }
+}
+
/* FORK & VFORK catchpoints. */
/* An instance of this type is used to represent a fork or vfork
@@ -16059,6 +16117,7 @@ _initialize_breakpoint (void)
initialize_breakpoint_ops ();
observer_attach_solib_unloaded (disable_breakpoints_in_unloaded_shlib);
+ observer_attach_free_objfile (disable_breakpoints_in_free_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..7b420ea 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 symbol 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 93b7ba7..0a0c2c0 100644
--- a/gdb/objfiles.c
+++ b/gdb/objfiles.c
@@ -530,6 +530,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);
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 2cc33d0..e6f62ba 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -1928,21 +1928,22 @@ 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);
+ 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
@@ -2474,7 +2475,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 6978677..b0c2f04 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -1442,6 +1442,30 @@ gdb_bfd_lookup_symbol (bfd *abfd,
return symaddr;
}
+/* Upon notification of FREE_OBJFILE remove any reference
+ to any user-added file that is about to be freed. */
+static void
+remove_user_added_objfile (struct objfile *objfile)
+{
+ struct so_list *gdb;
+
+ if (!objfile)
+ return;
+
+ if (!(objfile->flags & OBJF_USERLOADED)
+ || !(objfile->flags & OBJF_SHARED))
+ return;
+
+ gdb = so_list_head;
+ while (gdb)
+ {
+ if (gdb->objfile == objfile)
+ gdb->objfile = NULL;
+ gdb = gdb->next;
+ }
+}
+
+
extern initialize_file_ftype _initialize_solib; /* -Wmissing-prototypes */
void
@@ -1449,6 +1473,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 3e66bd1..273c07a 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -91,6 +91,8 @@ static void symbol_file_add_main_1 (char *args, int from_tty, int flags);
static void add_symbol_file_command (char *, int);
+static void remove_symbol_file_command (char *, int);
+
bfd *symfile_bfd_open (char *);
int get_section_index (struct objfile *, char *);
@@ -2219,6 +2221,8 @@ add_symbol_file_command (char *args, int from_tty)
int expecting_sec_name = 0;
int expecting_sec_addr = 0;
char **argv;
+ CORE_ADDR addr_low;
+ struct objfile *objf;
struct sect_opt
{
@@ -2267,6 +2271,7 @@ add_symbol_file_command (char *args, int from_tty)
num_sect_opts
* sizeof (struct sect_opt)));
}
+ addr_low = parse_and_eval_address (arg);
}
else
{
@@ -2354,9 +2359,12 @@ add_symbol_file_command (char *args, int from_tty)
if (from_tty && (!query ("%s", "")))
error (_("Not confirmed."));
- symbol_file_add (filename, from_tty ? SYMFILE_VERBOSE : 0,
+ objf = symbol_file_add (filename, from_tty ? SYMFILE_VERBOSE : 0,
section_addrs, flags);
+ /* Set the low address of the object for identification. */
+ objf->addr_low = addr_low;
+
/* Getting new symbols may change our opinion about what is
frameless. */
reinit_frame_cache ();
@@ -2364,6 +2372,56 @@ add_symbol_file_command (char *args, int from_tty)
}
\f
+
+/* 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;
+ char *arg;
+ int argcnt;
+ struct cleanup *my_cleanups;
+ CORE_ADDR addr;
+ struct objfile* objf;
+ struct so_list * so;
+ int found = 0;
+
+ dont_repeat ();
+
+ if (args == NULL)
+ error (_("remove-symbol-file takes an address as parameter."));
+
+ my_cleanups = make_cleanup (null_cleanup, NULL);
+
+ argv = gdb_buildargv (args);
+ make_cleanup_freeargv (argv);
+
+ for (arg = argv[0], argcnt = 0; arg != NULL; arg = argv[++argcnt])
+ {
+ if (argcnt == 0)
+ addr = parse_and_eval_address (arg);
+ else
+ error (_("USAGE: remove-symbol-file <text_low_address>"));
+ }
+
+
+ ALL_OBJFILES (objf)
+ {
+ if (objf->flags & OBJF_USERLOADED && objf->addr_low == addr)
+ break;
+ }
+
+ if (!objf)
+ error (_("no user-added symbol file for address 0x%s"),
+ phex_nz(addr, sizeof(addr)));
+
+ free_objfile (objf);
+ clear_symtab_users (0);
+
+ do_cleanups (my_cleanups);
+}
+
+
typedef struct objfile *objfilep;
DEF_VEC_P (objfilep);
@@ -3777,6 +3835,11 @@ 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 loaded via the add-symbol-file command.\n\
+Usage: remove-symbol-file START_ADDR.\nSTART_ADDR is the start address \
+of the module to remove."), &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
^ permalink raw reply [flat|nested] 25+ messages in thread* Re: [PATCH 1/3] Added command remove-symbol-file.
2013-04-16 13:25 ` [PATCH 1/3] Added command remove-symbol-file Nicolas Blanc
@ 2013-04-22 13:32 ` Yao Qi
2013-04-24 18:54 ` Tom Tromey
2013-04-26 20:23 ` Pedro Alves
2 siblings, 0 replies; 25+ messages in thread
From: Yao Qi @ 2013-04-22 13:32 UTC (permalink / raw)
To: Nicolas Blanc; +Cc: gdb-patches
On 04/16/2013 03:51 PM, Nicolas Blanc wrote:
> Added command remove-symbol-file for removing
> symbol files added via the add-symbol-file command.
>
Nicolas,
The patch looks good to me, but I am not the people to approve it. Some
nits below,
> 2013-18-03 Nicolas Blanc <nicolas.blanc@intel.com>
>
> * breakpoint.c (disable_breakpoints_in_free_objfile): Created
> function for disabling breakoints in objfiles upon FREE_OBJFILE
> notifications.
> * doc/observer.text: Created FREE_OBJFILE event.
Change to doc/observer.texi should be moved to a separate changelog entry.
> diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
> index f374368..d5c7b21 100644
> --- a/gdb/breakpoint.c
> +++ b/gdb/breakpoint.c
>
> +/* Disable any breakpoints and tracepoints in OBJFILE upon
> + notification of FREE_OBJFILE. Only apply to enabled breakpoints,
^^ Miss one space after period.
> + disabled ones can just stay disabled. */
> +
> +static void
> +disable_breakpoints_in_free_objfile (struct objfile * objfile)
> +{
> + struct bp_location *loc, **locp_tmp;
> +
> + if (objfile == NULL)
> + return;
> +
> + /* If the file is a shared library not loaded by the user then
> + SOLIB_UNLOADED was notified and DISABLE_BREAKPIONTS_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_BP_LOCATIONS (loc, locp_tmp)
> + {
> + struct obj_section *osect;
> + CORE_ADDR loc_addr = loc->address;
> +
> + /* ALL_BP_LOCATIONS bp_location has LOC->OWNER always non-NULL. */
> + struct breakpoint *b = loc->owner;
> +
> + if (loc->shlib_disabled != 0)
> + continue;
> +
> + if (objfile->pspace != loc->pspace)
> + continue;
> +
> + if (!is_tracepoint(b))
> + {
> + if (b->type != bp_breakpoint
> + && b->type != bp_jit_event
> + && b->type != bp_hardware_breakpoint)
> + continue;
> +
> + if (loc->loc_type != bp_loc_hardware_breakpoint
> + && loc->loc_type != bp_loc_software_breakpoint)
> + continue;
> + }
> +
> + ALL_OBJFILE_OSECTIONS (objfile, osect)
> + {
> + if (obj_section_addr (osect) <= loc_addr
> + && loc_addr < obj_section_endaddr (osect))
> + {
> + loc->shlib_disabled = 1;
> + loc->inserted = 0;
> + observer_notify_breakpoint_modified (loc->owner);
Nit: this observer will be called multiple times for a single breakpoint
LOC->owner, if it has multiple breakpoint locations in this objfile. It
is ideal to call observer only once for a breakpoint. Your patch is OK
to me as well.
> diff --git a/gdb/doc/observer.texi b/gdb/doc/observer.texi
> index adb7085..7b420ea 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 symbol file specified by @var{objfile} is about to be freed.
I feel that "symbol file" is not accurate. Maybe "object file"?
> +@end deftypefun
> +
> @deftypefun void new_thread (struct thread_info *@var{t})
> The thread specified by @var{t} has been created.
> @end deftypefun
> index 2cc33d0..e6f62ba 100644
> --- a/gdb/printcmd.c
> +++ b/gdb/printcmd.c
> @@ -1928,21 +1928,22 @@ 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);
> + gdb_assert (objfile->pspace == pspace);
>
This assert is always true. Probably, we need to move this assert to
the callers of "free_objfile" when argument is solib->objfile.
> 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
> @@ -2474,7 +2475,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 6978677..b0c2f04 100644
> --- a/gdb/solib.c
> +++ b/gdb/solib.c
> @@ -1442,6 +1442,30 @@ gdb_bfd_lookup_symbol (bfd *abfd,
> return symaddr;
> }
>
> +/* Upon notification of FREE_OBJFILE remove any reference
> + to any user-added file that is about to be freed. */
A blank line is needed here.
> +static void
> +remove_user_added_objfile (struct objfile *objfile)
> +{
> + struct so_list *gdb;
> +
> + if (!objfile)
> + return;
> +
> + if (!(objfile->flags & OBJF_USERLOADED)
> + || !(objfile->flags & OBJF_SHARED))
> + return;
> +
> + gdb = so_list_head;
> + while (gdb)
> + {
> + if (gdb->objfile == objfile)
> + gdb->objfile = NULL;
> + gdb = gdb->next;
> + }
> +}
> +
> diff --git a/gdb/symfile.c b/gdb/symfile.c
> index 3e66bd1..273c07a 100644
> --- a/gdb/symfile.c
> +++ b/gdb/symfile.c
> @@ -2364,6 +2372,56 @@ add_symbol_file_command (char *args, int from_tty)
> }
> \f
>
> +
> +/* This function removes a symbol file that was added via add-symbol-file. */
A blank line is needed here.
> +static void
> +remove_symbol_file_command (char *args, int from_tty)
> +{
--
Yao (é½å°§)
^ permalink raw reply [flat|nested] 25+ messages in thread* Re: [PATCH 1/3] Added command remove-symbol-file.
2013-04-16 13:25 ` [PATCH 1/3] Added command remove-symbol-file Nicolas Blanc
2013-04-22 13:32 ` Yao Qi
@ 2013-04-24 18:54 ` Tom Tromey
2013-04-25 19:24 ` Blanc, Nicolas
2013-04-26 20:23 ` Pedro Alves
2 siblings, 1 reply; 25+ messages in thread
From: Tom Tromey @ 2013-04-24 18:54 UTC (permalink / raw)
To: Nicolas Blanc; +Cc: gdb-patches
>>>>> "Nicolas" == Nicolas Blanc <nicolas.blanc@intel.com> writes:
Nicolas> +/* Disable any breakpoints and tracepoints that are in SOLIB upon
Nicolas> + notification of UNLOADED_SHLIB. Only apply to enabled breakpoints,
Two periods after space -- Yao pointed out one instance of this, but
there are a couple.
Nicolas> + ALL_OBJFILE_OSECTIONS (objfile, osect)
Nicolas> + {
Nicolas> + if (obj_section_addr (osect) <= loc_addr
Nicolas> + && loc_addr < obj_section_endaddr (osect))
Nicolas> + {
Nicolas> + loc->shlib_disabled = 1;
Nicolas> + loc->inserted = 0;
Nicolas> + observer_notify_breakpoint_modified (loc->owner);
Nicolas> + break;
Nicolas> + }
I liked Yao's comment about notifying just once per breakpoint. It
doesn't seem difficult to do that.
It's curious that this new function and breakpoint_free_objfile don't
overlap at all.
Nicolas> - observer_attach_solib_unloaded (clear_dangling_display_expressions);
Nicolas> + observer_attach_free_objfile (clear_dangling_display_expressions);
It isn't totally clear to me that these are equivalent.
From browsing solib.c it seems that an solib can be freed without the
objfiles being purged.
I am not sure but I think maybe the path core_close -> clear_solib can
do this. If so, maybe this is simply a bug there; I am not sure.
Nicolas> +static void remove_symbol_file_command (char *, int);
I don't think you really need this declaration. It's better to leave
them out unless they are needed for something specific, like mutual
recursion. (There are lots of leftover ones, which I've always imagined
to be from a time when GCC's prototype warnings worked differently.)
Nicolas> + addr_low = parse_and_eval_address (arg);
It seems like this parses and evaluates this argument twice.
I think it would be better to take another approach, so that it is just
evaluated once.
Nicolas> + /* Set the low address of the object for identification. */
Nicolas> + objf->addr_low = addr_low;
Is there any way to display this information?
Otherwise, how should users find it?
Nicolas> +static void
Nicolas> +remove_symbol_file_command (char *args, int from_tty)
[...]
Nicolas> + argv = gdb_buildargv (args);
Nicolas> + make_cleanup_freeargv (argv);
If the syntax is really just an expression as an argument, then don't
bother with gdb_buildargv. Using gdb_buildargv means that complicated
expressions will have to be quoted unusually.
I realize this is how add-symbol-file works, but I think it is a bad
approach.
Nicolas> + if (!objf)
We recently decided to use the wordier "objf != NULL" style.
Nicolas> + c = add_cmd ("remove-symbol-file", class_files, remove_symbol_file_command, _("\
I think this line is too long.
Tom
^ permalink raw reply [flat|nested] 25+ messages in thread* RE: [PATCH 1/3] Added command remove-symbol-file.
2013-04-24 18:54 ` Tom Tromey
@ 2013-04-25 19:24 ` Blanc, Nicolas
2013-04-25 20:07 ` Tom Tromey
2013-04-26 14:13 ` Yao Qi
0 siblings, 2 replies; 25+ messages in thread
From: Blanc, Nicolas @ 2013-04-25 19:24 UTC (permalink / raw)
To: gdb-patches; +Cc: Tom Tromey, Pedro Alves
> Nicolas> +/* Disable any breakpoints and tracepoints that are in SOLIB upon
> Nicolas> + notification of UNLOADED_SHLIB. Only apply to enabled
> Nicolas> +breakpoints,
Tom> Two periods after space -- Yao pointed out one instance of this, but there are a couple.
Nicolas> I'll fixed those.
> Nicolas> + ALL_OBJFILE_OSECTIONS (objfile, osect)
> Nicolas> + {
> Nicolas> + if (obj_section_addr (osect) <= loc_addr
> Nicolas> + && loc_addr < obj_section_endaddr (osect))
> Nicolas> + {
> Nicolas> + loc->shlib_disabled = 1;
> Nicolas> + loc->inserted = 0;
> Nicolas> + observer_notify_breakpoint_modified (loc->owner);
> Nicolas> + break;
> Nicolas> + }
Tom> I liked Yao's comment about notifying just once per breakpoint. It doesn't seem difficult to do that.
Nicolas> Ok I'll use a list of breakpoints to collect first the breakpoints to notify.
Tom> It's curious that this new function and breakpoint_free_objfile don't overlap at all.
Nicolas> First disable_breakpoints_in_free_objfile() is called and then breakpoint_free_objfile() from free_objfile().
Nicolas> Now I could test moving the code from breakpoint_free_objfile() to disable_breakpionts_in_free_objfile() and delete breakpoint_free_objfile().
> Nicolas> - observer_attach_solib_unloaded
> Nicolas> (clear_dangling_display_expressions);
> Nicolas> + observer_attach_free_objfile
> Nicolas> + (clear_dangling_display_expressions);
> Tom> It isn't totally clear to me that these are equivalent.
> Tom> From browsing solib.c it seems that an solib can be freed without the objfiles being purged.
> Tom> I am not sure but I think maybe the path core_close -> clear_solib can do this. If so, maybe this is simply a bug there; I am not sure.
Nicolas> Indeed, an object file is shared with another SO or it was loaded by the user then free_so() will be called but not free_objfile().
Nicolas> In that case clear_dangling_disaplay_expression() won't be called. I think it's ok because the dangling reference that needs
Nicolas> to be cleaned-up is the object file not the SO.
> Nicolas> +static void remove_symbol_file_command (char *, int);
Tom >I don't think you really need this declaration. It's better to leave them out unless they are needed for something specific, like mutual recursion. (There are lots of leftover ones, which I've always imagined to be from a time when GCC's prototype warnings worked differently.)
Nicolas> Ok, I'll see what happens when I remove it.
> Nicolas> + addr_low = parse_and_eval_address (arg);
Tom> It seems like this parses and evaluates this argument twice.
Tom> I think it would be better to take another approach, so that it is just evaluated once.
Nicolas> You're right. I can take the value later on from the subsequent loop.
> Nicolas> + /* Set the low address of the object for identification. */
> Nicolas> + objf->addr_low = addr_low;
Tom> Is there any way to display this information?
Nicolas> Unfortunately the answer no. "info files" does not list user-added files. GDB is currently lacking commands to show user-added files.
Tom> Otherwise, how should users find it?
Nicolas> The user knows the address because he typed it in for adding the file. Note that when the user needs adding a file manually then he has a way outside GDB to learn about the memory mapping.
> Nicolas> +static void
> Nicolas> +remove_symbol_file_command (char *args, int from_tty)
> [...]
> Nicolas> + argv = gdb_buildargv (args); make_cleanup_freeargv (argv);
Tom> If the syntax is really just an expression as an argument, then don't bother with gdb_buildargv. Using gdb_buildargv means that complicated expressions will have to be quoted unusually.
Tom>I realize this is how add-symbol-file works, but I think it is a bad approach.
Nicolas> Ok, I'll do that.
> Nicolas> + if (!objf)
Tom> We recently decided to use the wordier "objf != NULL" style.
Nicolas> Ok.
> Nicolas> + c = add_cmd ("remove-symbol-file", class_files,
> Nicolas> + remove_symbol_file_command, _("\
Tom> I think this line is too long.
Nicolas> Will be fixed.
Thanks for your feedback. It's much appreciated.
Nicolas
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Christian Lamprechter, Hannes Schwaderer, Douglas Lusk
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 25+ messages in thread* Re: [PATCH 1/3] Added command remove-symbol-file.
2013-04-25 19:24 ` Blanc, Nicolas
@ 2013-04-25 20:07 ` Tom Tromey
2013-04-26 14:13 ` Yao Qi
1 sibling, 0 replies; 25+ messages in thread
From: Tom Tromey @ 2013-04-25 20:07 UTC (permalink / raw)
To: Blanc, Nicolas; +Cc: gdb-patches, Pedro Alves
Tom> I liked Yao's comment about notifying just once per breakpoint.
Tom> It doesn't seem difficult to do that.
Nicolas> Ok I'll use a list of breakpoints to collect first the
Nicolas> breakpoints to notify.
I think another way is to loop over all breakpoints and then examine
their locations. That way you don't have to keep a separate list of
breakpoints to notify -- you can just decide about the current
breakpoint after the inner loop.
Tom
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 1/3] Added command remove-symbol-file.
2013-04-25 19:24 ` Blanc, Nicolas
2013-04-25 20:07 ` Tom Tromey
@ 2013-04-26 14:13 ` Yao Qi
1 sibling, 0 replies; 25+ messages in thread
From: Yao Qi @ 2013-04-26 14:13 UTC (permalink / raw)
To: Blanc, Nicolas; +Cc: gdb-patches, Tom Tromey, Pedro Alves
On 04/25/2013 08:48 PM, Blanc, Nicolas wrote:
> Tom> I liked Yao's comment about notifying just once per breakpoint. It doesn't seem difficult to do that.
> Nicolas> Ok I'll use a list of breakpoints to collect first the breakpoints to notify.
You may have a look at tracepoint.c:merge_uploaded_tracepoints, and see
how to notify once for one breakpoint. We use a vector 'modified_tp'
there to save the modified breakpoint uniquely, iterate over it, and
call observer_notify_breakpoint_modified. Hope it helps.
--
Yao (é½å°§)
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 1/3] Added command remove-symbol-file.
2013-04-16 13:25 ` [PATCH 1/3] Added command remove-symbol-file Nicolas Blanc
2013-04-22 13:32 ` Yao Qi
2013-04-24 18:54 ` Tom Tromey
@ 2013-04-26 20:23 ` Pedro Alves
2013-04-30 7:30 ` Blanc, Nicolas
2 siblings, 1 reply; 25+ messages in thread
From: Pedro Alves @ 2013-04-26 20:23 UTC (permalink / raw)
To: Nicolas Blanc; +Cc: gdb-patches
On 04/16/2013 08:51 AM, Nicolas Blanc wrote:
> 2013-18-03 Nicolas Blanc <nicolas.blanc@intel.com>
>
> * breakpoint.c (disable_breakpoints_in_free_objfile): Created
> function for disabling breakoints in objfiles upon FREE_OBJFILE
> notifications.
Present tense "create", etc. (throughout the log entry).
Typo breakoints.
> * doc/observer.text: Created FREE_OBJFILE event.
> * objfiles.c (free_objfile): Notify FREE_OBJFILE.
> * 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): Created function for removing
> dangling references upon notification of FREE_OBJFILE.
> * symfile.c (add_symbol_file_command): Set OBJFILE->LOW_ADDRESS.
LOW_ADDR.
> (remove_symbol_file_command): Created command for removing symbol files.
> (_initialize_symfile): Added remove-symbol-file.
> +/* Upon notification of FREE_OBJFILE remove any reference
> + to any user-added file that is about to be freed. */
Why only user-added files?
> +static void
> +remove_user_added_objfile (struct objfile *objfile)
> +{
> + struct so_list *gdb;
> +
> + if (!objfile)
> + return;
> +
> + if (!(objfile->flags & OBJF_USERLOADED)
> + || !(objfile->flags & OBJF_SHARED))
> + return;
> +
> +
> + gdb = so_list_head;
> + while (gdb)
> + {
> + if (gdb->objfile == objfile)
> + gdb->objfile = NULL;
> + gdb = gdb->next;
> + }
Or rather/also, this looks a bit weird to me.
Can we ever really ever find a user-loaded file in the
so_list_head list? What would that mean?
IIRC, the only way to get a OBJF_USERLOADED|OBJF_SHARED
objfile is through "dll-symbols" (dll_symbol_command),
but that doesn't create any entry in the shared library list.
BTW, calling the variable "gdb" was probably copied from
solib.c:update_solib_list. It makes sense to call it
that to contrast with "inferior", but not here. Just call
it something like "so". That while loop can be written
simpler as a for loop:
for (so = so_list_head; so != NULL; so = so->next)
if (so->objfile == objfile)
so->objfile = NULL;
> +static void
> +disable_breakpoints_in_free_objfile (struct objfile * objfile)
This is clearly mirroring the naming of
disable_breakpoints_in_unloaded_shlib. Should be "in freed objfile".
"in free objfile" would mean something else.
> + /* If the file is a shared library not loaded by the user then
> + SOLIB_UNLOADED was notified and DISABLE_BREAKPIONTS_IN_UNLOADED_SHLIB
Typo BREAKPIONTS. Actually, uppercase is used when referring to
a value of a variable (see GNU coding standards), which is not the
case here.
> + error (_("USAGE: remove-symbol-file <text_low_address>"));
I'd s/low// here. text_address is clear and common enough that
having "low" there makes me go "what does low mean here?" Or just
<address> even.
> + if (objf->flags & OBJF_USERLOADED && objf->addr_low == addr)
As I mentioned, the .text address may not be the lower address
in the object at all, so this "addr_low" confused me.
I'd be happier with naming the field for what ig really is, something
like "add_symbol_file_addr", with a comment indicating this is related
to "add-symbol-file", but I see you're reusing an existing variable. At
the very least, the variable's definition should gain a comment explaining
its overloading for add-symbol-file.
--
Pedro Alves
^ permalink raw reply [flat|nested] 25+ messages in thread* RE: [PATCH 1/3] Added command remove-symbol-file.
2013-04-26 20:23 ` Pedro Alves
@ 2013-04-30 7:30 ` Blanc, Nicolas
2013-04-30 9:28 ` Pedro Alves
0 siblings, 1 reply; 25+ messages in thread
From: Blanc, Nicolas @ 2013-04-30 7:30 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches
Hi Pedro,
>> +/* Upon notification of FREE_OBJFILE remove any reference
>> + to any user-added file that is about to be freed. */
>
> Why only user-added files?
I choose to restrict the scope of the command to user-added files in order to
limit potential unforeseen side-effects in a first time. This restriction
can be lifted in the future if needed.
>> +static void
>> +remove_user_added_objfile (struct objfile *objfile) {
>> + struct so_list *gdb;
>> +
>> + if (!objfile)
>> + return;
>> +
>> + if (!(objfile->flags & OBJF_USERLOADED)
>> + || !(objfile->flags & OBJF_SHARED))
>> + return;
>> +
>> +
>> + gdb = so_list_head;
>> + while (gdb)
>> + {
>> + if (gdb->objfile == objfile)
>> + gdb->objfile = NULL;
>> + gdb = gdb->next;
>> + }
>
> Or rather/also, this looks a bit weird to me.
> Can we ever really ever find a user-loaded file in the so_list_head list? What would that mean?
> IIRC, the only way to get a OBJF_USERLOADED|OBJF_SHARED objfile is through "dll-symbols" (dll_symbol_command), but that doesn't create any entry in the shared library list.
This is a good question. I added this function because update_solib_list handles the case of user-added files:
/* Unless the user loaded it explicitly, free SO's objfile. */
if (gdb->objfile && ! (gdb->objfile->flags & OBJF_USERLOADED)
&& !solib_used (gdb))
free_objfile (gdb->objfile);
If the user-loaded check above is needed then remove_user_added_objfile() is also needed.
But I don't think it is currently possible that user-loaded files end up in so_list_head either.
>> +static void
>> +disable_breakpoints_in_free_objfile (struct objfile * objfile)
>
> This is clearly mirroring the naming of
> disable_breakpoints_in_unloaded_shlib. Should be "in freed objfile".
> "in free objfile" would mean something else.
Ok
> + error (_("USAGE: remove-symbol-file <text_low_address>"));
> I'd s/low// here. text_address is clear and common enough that having "low" there makes me go "what does low mean here?" Or just <address> even.
Ok, I am using text_addr now.
> + if (objf->flags & OBJF_USERLOADED && objf->addr_low == addr)
> As I mentioned, the .text address may not be the lower address in the object at all, so this "addr_low" confused me.
> I'd be happier with naming the field for what ig really is, something like "add_symbol_file_addr", with a comment indicating this is related to "add-symbol-file", but I see you're reusing an existing variable. At the very least,
> the variable's definition should gain a comment explaining its overloading for add-symbol-file.
I understand your point. GDB's implementation\doc assume that addr_low is the text address.
It' not only the case for add-symbol-file but also for info shared.
So I've added the following comment to struct objfile for clarification:
/* The base address of the object file, which by default is assumed to be
the address of the text section. The remove-symbol-file command uses
this field to identify the object file to remove. */
CORE_ADDR addr_low;
I hope this helps.
Thanks,
Nicolas
--
Pedro Alves
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Christian Lamprechter, Hannes Schwaderer, Douglas Lusk
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 25+ messages in thread* Re: [PATCH 1/3] Added command remove-symbol-file.
2013-04-30 7:30 ` Blanc, Nicolas
@ 2013-04-30 9:28 ` Pedro Alves
2013-04-30 16:53 ` Blanc, Nicolas
0 siblings, 1 reply; 25+ messages in thread
From: Pedro Alves @ 2013-04-30 9:28 UTC (permalink / raw)
To: Blanc, Nicolas; +Cc: gdb-patches
On 04/29/2013 06:30 PM, Blanc, Nicolas wrote:
> Hi Pedro,
>
>>> +/* Upon notification of FREE_OBJFILE remove any reference
>>> + to any user-added file that is about to be freed. */
>>
>> Why only user-added files?
>
> I choose to restrict the scope of the command to user-added files in order to
> limit potential unforeseen side-effects in a first time. This restriction
> can be lifted in the future if needed.
That's not what I meant. I agree with restrict the scope of the
command to user-added files, and I'd probably voice against it if
the patch did otherwise. The question is why does this piece of code
need to be aware of this? As in, the "free_objfile" notification is called
irrespective of the objfile being a user loaded objfile or not.
So a reader seeing this has to wonder "okay, then if a !userloaded
objfile is freed, what is making sure we don't end up with stale
references to that freed objfile, if not this function?" We need at
least a comment clarifying this.
>
>>> +static void
>>> +remove_user_added_objfile (struct objfile *objfile) {
>>> + struct so_list *gdb;
>>> +
>>> + if (!objfile)
>>> + return;
>>> +
>>> + if (!(objfile->flags & OBJF_USERLOADED)
>>> + || !(objfile->flags & OBJF_SHARED))
>>> + return;
>>> +
>>> +
>>> + gdb = so_list_head;
>>> + while (gdb)
>>> + {
>>> + if (gdb->objfile == objfile)
>>> + gdb->objfile = NULL;
>>> + gdb = gdb->next;
>>> + }
>>
>> Or rather/also, this looks a bit weird to me.
>> Can we ever really ever find a user-loaded file in the so_list_head list? What would that mean?
>> IIRC, the only way to get a OBJF_USERLOADED|OBJF_SHARED objfile is through "dll-symbols" (dll_symbol_command), but that doesn't create any entry in the shared library list.
>
> This is a good question. I added this function because update_solib_list handles the case of user-added files:
>
> /* Unless the user loaded it explicitly, free SO's objfile. */
> if (gdb->objfile && ! (gdb->objfile->flags & OBJF_USERLOADED)
> && !solib_used (gdb))
> free_objfile (gdb->objfile);
>
> If the user-loaded check above is needed then remove_user_added_objfile() is also needed.
> But I don't think it is currently possible that user-loaded files end up in so_list_head either.
git blame points at this:
http://sourceware.org/ml/gdb-patches/2000-03/msg00273.html
Which seems to be the initial implementation for dlclose support,
very early shared library support code. There's lots of discussion
around that patch, including several different implementations of the support:
In both
http://sourceware.org/ml/gdb-patches/2000-03/
and:
http://sourceware.org/ml/gdb/2000-03/
(look for dlclose and unloading shared objects).
An earlier version of the patch didn't have that bit, but I didn't
find the rationale for adding it in the final version.
The reason I can think of, is that the user may do:
(gdb) add-symbol-file /foo/bar.so ADDR
and if the program itself later loads /foo/bar.so,
then the code that loads the objfile for the DSO finds
that an objfile for bar.so has already been loaded, and
reuses it. At the time of that initial patch in 2000,
the code that checked whether the objfile was already
loaded just compared names:
/* Have we already loaded this shared object? */
ALL_OBJFILES (so->objfile)
{
if (strcmp (so->objfile->name, so->so_name) == 0)
return 1;
}
So that seems likely to be the rationale to me.
The current code hasn't changed that much. It's in
solib_read_symbols:
/* Have we already loaded this shared object? */
ALL_OBJFILES (so->objfile)
{
if (filename_cmp (so->objfile->name, so->so_name) == 0
&& so->objfile->addr_low == so->addr_low)
break;
}
if (so->objfile != NULL)
break;
...
so->objfile = symbol_file_add_from_bfd (so->abfd,
flags, sap, OBJF_SHARED,
NULL);
so->objfile->addr_low = so->addr_low;
We just gained the addr_low extra check. However, it still seems
possible the solib code reuses a user added objfile...
I think we should define precisely what does it mean when
the user does add-symbol-file and then the program loads the
same file.
Sorry, I haven't thought on this as much as I wanted, but I
have to go now. I'll possibly respond more tomorrow.
>
>>> +static void
>>> +disable_breakpoints_in_free_objfile (struct objfile * objfile)
>>
>> This is clearly mirroring the naming of
>> disable_breakpoints_in_unloaded_shlib. Should be "in freed objfile".
>> "in free objfile" would mean something else.
>
> Ok
>
>> + error (_("USAGE: remove-symbol-file <text_low_address>"));
>
>> I'd s/low// here. text_address is clear and common enough that having "low" there makes me go "what does low mean here?" Or just <address> even.
>
> Ok, I am using text_addr now.
>
>> + if (objf->flags & OBJF_USERLOADED && objf->addr_low == addr)
>
>> As I mentioned, the .text address may not be the lower address in the object at all, so this "addr_low" confused me.
>> I'd be happier with naming the field for what ig really is, something like "add_symbol_file_addr", with a comment indicating this is related to "add-symbol-file", but I see you're reusing an existing variable. At the very least,
>> the variable's definition should gain a comment explaining its overloading for add-symbol-file.
>
> I understand your point. GDB's implementation\doc assume that addr_low is the text address.
> It' not only the case for add-symbol-file but also for info shared.
>
> So I've added the following comment to struct objfile for clarification:
>
> /* The base address of the object file, which by default is assumed to be
> the address of the text section. The remove-symbol-file command uses
> this field to identify the object file to remove. */
>
> CORE_ADDR addr_low;
>
> I hope this helps.
>
> Thanks,
>
> Nicolas
>
> --
> Pedro Alves
>
> Intel GmbH
> Dornacher Strasse 1
> 85622 Feldkirchen/Muenchen, Deutschland
> Sitz der Gesellschaft: Feldkirchen bei Muenchen
> Geschaeftsfuehrer: Christian Lamprechter, Hannes Schwaderer, Douglas Lusk
> Registergericht: Muenchen HRB 47456
> Ust.-IdNr./VAT Registration No.: DE129385895
> Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
>
--
Pedro Alves
^ permalink raw reply [flat|nested] 25+ messages in thread* RE: [PATCH 1/3] Added command remove-symbol-file.
2013-04-30 9:28 ` Pedro Alves
@ 2013-04-30 16:53 ` Blanc, Nicolas
2013-05-08 17:56 ` Pedro Alves
0 siblings, 1 reply; 25+ messages in thread
From: Blanc, Nicolas @ 2013-04-30 16:53 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches
Hi Pedro,
I tested adding a file manually in gdb before the debuggee, as you suggested, and indeed
the user-added file appeared in so_list_head. There was a glitch in my function because
"objfile->flags & OBJF_SHARED" was not set by GDB. So the dangling reference was not removed
from the list. I fixed that and now the new code for remove_user_added_file is:
/* 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
any reference 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)
return;
if (objfile->flags & OBJF_USERLOADED)
{
for (so = so_list_head; so != NULL; so = so->next)
if (so->objfile == objfile)
so->objfile = NULL;
}
}
If this is function is ok for you then I'll send a new version of the patch.
Thanks again for your feedback,
Nicolas
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Christian Lamprechter, Hannes Schwaderer, Douglas Lusk
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 25+ messages in thread* Re: [PATCH 1/3] Added command remove-symbol-file.
2013-04-30 16:53 ` Blanc, Nicolas
@ 2013-05-08 17:56 ` Pedro Alves
2013-05-28 11:25 ` Blanc, Nicolas
0 siblings, 1 reply; 25+ messages in thread
From: Pedro Alves @ 2013-05-08 17:56 UTC (permalink / raw)
To: Blanc, Nicolas; +Cc: Pedro Alves, gdb-patches
So what is the desirable behavior for when the user does
add-symbol-file and then the program loads the same file,
and then the user removes the file she added. GDB drops
symbols until the next DSO event or next "sharedlibrary"
command invocation? The fact that GDB reuses the same file
when the addr_low happens to match looks quite brittle (it
doesn't check the section offsets (passed to add-symbol-file)
are the same, for instance). I wonder whether this sharing is
supposed to be a valid use case, and whether it wouldn't be better
and simpler to disable it, that is,
/* Have we already loaded this shared object? */
ALL_OBJFILES (so->objfile)
{
if (filename_cmp (so->objfile->name, so->so_name) == 0
&& so->objfile->addr_low == so->addr_low
- && so->objfile->addr_low == so->addr_low)
+ && !(so->objfile->flags & OBJF_USERLOADED))
break;
}
...
- /* Unless the user loaded it explicitly, free SO's objfile. */
- if (gdb->objfile && ! (gdb->objfile->flags & OBJF_USERLOADED)
- && !solib_used (gdb))
- free_objfile (gdb->objfile);
In a way, treat manually added objfiles list and the dynamic SO list
separate lists.
--
Pedro Alves
^ permalink raw reply [flat|nested] 25+ messages in thread* RE: [PATCH 1/3] Added command remove-symbol-file.
2013-05-08 17:56 ` Pedro Alves
@ 2013-05-28 11:25 ` Blanc, Nicolas
0 siblings, 0 replies; 25+ messages in thread
From: Blanc, Nicolas @ 2013-05-28 11:25 UTC (permalink / raw)
To: Pedro Alves; +Cc: gdb-patches
Hi Pedro,
I just returned from vacations. Sorry for the delay.
Just comparing addr_low for re-using object-files when loading a new SO might indeed be incorrect.
But one may consider the current behavior of GDB as a feature, e.g.: the user knows something additional
and want to overwrite the default mapping. So I would not change GDB.
To me, the remove-symbol-file command should remove the file even if it is currently
shared because the user might have a good reason for doing this.
Regards,
Nicolas
> So what is the desirable behavior for when the user does add-symbol-file and then the program loads the same file, and then the user removes the file she added. GDB drops symbols until the next DSO > event or next "sharedlibrary"
> command invocation? The fact that GDB reuses the same file when the addr_low happens to match looks quite brittle (it doesn't check the section offsets (passed to add-symbol-file) are the same, for > instance). I wonder whether this sharing is supposed to be a valid use case, and whether it wouldn't be better and simpler to disable it, that is,
>
> /* Have we already loaded this shared object? */
> ALL_OBJFILES (so->objfile)
> {
> if (filename_cmp (so->objfile->name, so->so_name) == 0
> && so->objfile->addr_low == so->addr_low
>- && so->objfile->addr_low == so->addr_low)
>+ && !(so->objfile->flags & OBJF_USERLOADED))
> break;
> }
>
>...
>
>- /* Unless the user loaded it explicitly, free SO's objfile. */
>- if (gdb->objfile && ! (gdb->objfile->flags & OBJF_USERLOADED)
>- && !solib_used (gdb))
>- free_objfile (gdb->objfile);
>
>
>In a way, treat manually added objfiles list and the dynamic SO list separate lists.
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Christian Lamprechter, Hannes Schwaderer, Douglas Lusk
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 3/3] Documentation for the remove-symbol-file command.
2013-04-16 11:22 [PATCH 0/3] remove-symbol-file Nicolas Blanc
` (2 preceding siblings ...)
2013-04-16 13:25 ` [PATCH 1/3] Added command remove-symbol-file Nicolas Blanc
@ 2013-04-16 14:18 ` Nicolas Blanc
2013-04-16 15:12 ` Eli Zaretskii
2013-04-24 9:22 ` [PATCH 0/3] remove-symbol-file Tom Tromey
2013-04-24 17:46 ` Pedro Alves
5 siblings, 1 reply; 25+ messages in thread
From: Nicolas Blanc @ 2013-04-16 14:18 UTC (permalink / raw)
To: gdb-patches; +Cc: Nicolas Blanc
2013-04-05 Nicolas Blanc <nicolas.blanc@intel.com>
gdb/doc:
* gdb.texinfo (Commands to Specify Files): Added description
of the remove-symbol-file command.
Signed-off-by: Nicolas Blanc <nicolas.blanc@intel.com>
---
gdb/doc/gdb.texinfo | 15 +++++++++++++--
1 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index bf7e25e..296b7d1 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -16248,8 +16248,10 @@ section name and base address for that section. You can specify any
The symbol table of the file @var{filename} is added to the symbol table
originally read with the @code{symbol-file} command. You can use the
@code{add-symbol-file} command any number of times; the new symbol data
-thus read keeps adding to the old. To discard all old symbol data
-instead, use the @code{symbol-file} command without any arguments.
+thus read keeps adding to the old.
+
+Changes can be reverted using the command @code{remove-symbol-file},
+which takes as parameter the load address of the file to remove.
@cindex relocatable object files, reading symbols from
@cindex object files, relocatable, reading symbols from
@@ -16287,6 +16289,15 @@ way.
@code{add-symbol-file} does not repeat if you press @key{RET} after using it.
+@kindex remove-symbol-file
+@item remove-symbol-file @var{address}
+The @code{remove-symbol-file} command removes all symbol information about
+the file loaded at @var{address}. @var{address} must be an expression that
+represents the load address of a file added by the user via the
+@code{add-symbol-file} command.
+
+@code{remove-symbol-file} does not repeat if you press @key{RET} after using it.
+
@kindex add-symbol-file-from-memory
@cindex @code{syscall DSO}
@cindex load symbols from memory
--
1.7.6.5
^ permalink raw reply [flat|nested] 25+ messages in thread* Re: [PATCH 3/3] Documentation for the remove-symbol-file command.
2013-04-16 14:18 ` [PATCH 3/3] Documentation for the remove-symbol-file command Nicolas Blanc
@ 2013-04-16 15:12 ` Eli Zaretskii
0 siblings, 0 replies; 25+ messages in thread
From: Eli Zaretskii @ 2013-04-16 15:12 UTC (permalink / raw)
To: Nicolas Blanc; +Cc: gdb-patches, nicolas.blanc
> From: Nicolas Blanc <nicolas.blanc@intel.com>
> Cc: Nicolas Blanc <nicolas.blanc@intel.com>
> Date: Tue, 16 Apr 2013 09:52:01 +0200
>
> 2013-04-05 Nicolas Blanc <nicolas.blanc@intel.com>
>
> gdb/doc:
> * gdb.texinfo (Commands to Specify Files): Added description
> of the remove-symbol-file command.
Thanks.
> +@kindex remove-symbol-file
> +@item remove-symbol-file @var{address}
> +The @code{remove-symbol-file} command removes all symbol information about
> +the file loaded at @var{address}. @var{address} must be an expression that
^^
Two spaces here.
The documentation patch is OK with this change.
Please also add an entry in NEWS for this new command.
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 0/3] remove-symbol-file
2013-04-16 11:22 [PATCH 0/3] remove-symbol-file Nicolas Blanc
` (3 preceding siblings ...)
2013-04-16 14:18 ` [PATCH 3/3] Documentation for the remove-symbol-file command Nicolas Blanc
@ 2013-04-24 9:22 ` Tom Tromey
2013-04-24 20:40 ` Blanc, Nicolas
2013-04-24 17:46 ` Pedro Alves
5 siblings, 1 reply; 25+ messages in thread
From: Tom Tromey @ 2013-04-24 9:22 UTC (permalink / raw)
To: Nicolas Blanc; +Cc: gdb-patches
>>>>> "Nicolas" == Nicolas Blanc <nicolas.blanc@intel.com> writes:
Nicolas> 1) The remove-symbol-file command from Apple takes as parameter
Nicolas> the file to remove whereas this implementation requires the load
Nicolas> address of the file. Hence, this command is able to unload
Nicolas> symbol for files that have been loaded multiple times.
Nicolas> 2) This implementation sends a notification when an object file is
Nicolas> deleted. The notification mechanism simplifies the implementation of
Nicolas> the command because it is then the responsibility of the observers
Nicolas> to clean dangling references. GDB removes shared libraries in this
Nicolas> way already.
This sounds reasonable to me.
I wonder if it would be advisable to design the syntax so that we can
have remove-symbol-file also accept a file name, perhaps later if we
decide we want that.
Tom
^ permalink raw reply [flat|nested] 25+ messages in thread* RE: [PATCH 0/3] remove-symbol-file
2013-04-24 9:22 ` [PATCH 0/3] remove-symbol-file Tom Tromey
@ 2013-04-24 20:40 ` Blanc, Nicolas
2013-04-24 20:49 ` Pedro Alves
0 siblings, 1 reply; 25+ messages in thread
From: Blanc, Nicolas @ 2013-04-24 20:40 UTC (permalink / raw)
To: Pedro Alves, Tom Tromey; +Cc: gdb-patches
Thanks Tom, Pedro for your feedback.
I'll try to respond to both of you in this email.
This implementation only removes files that were added via the add-symbol-file command.
The add-symbol-file command takes as parameter the address of the text session. In this
context I think the text address is the most appropriate way to remove a file because:
1) the user knows exactly where the .text section was loaded,
2) an application can load shared libraries several times at different addresses (it's a requirement for me), and
3) I can't think of a good reason why someone would add a second symbol file at the same address.
Most likely this is a user error that should have been reported by add-symbol-file.
Note that currently in Option 4 below ADDR is in fact "objf->addr_low", but the command could be more generous
by searching first which file corresponds to ADDR and then removing it. This would be more flexible and an
alternative to Option 3, for instance.
1) remove-symbol-file FILE
2) remove-symbol-file FILE ADDR
3) remove-symbol-file -s .data DATA_ADDR
4) remove-symbol-file ADDR
As a matter of taste I prefer the options where FILE is not mandatory because this can easily be more
ambiguous.
Now as suggested by Tom, the scope of the command could also be broaden to allow removing any
symbol file. I could try to lift this restriction if you think there is more general need for removing
arbitrary symbol files.
What are your preferences?
Best Regards,
Nicolas
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Christian Lamprechter, Hannes Schwaderer, Douglas Lusk
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 25+ messages in thread* Re: [PATCH 0/3] remove-symbol-file
2013-04-24 20:40 ` Blanc, Nicolas
@ 2013-04-24 20:49 ` Pedro Alves
2013-04-25 17:25 ` Blanc, Nicolas
0 siblings, 1 reply; 25+ messages in thread
From: Pedro Alves @ 2013-04-24 20:49 UTC (permalink / raw)
To: Blanc, Nicolas; +Cc: Tom Tromey, gdb-patches
On 04/24/2013 06:30 PM, Blanc, Nicolas wrote:
> Thanks Tom, Pedro for your feedback.
>
> I'll try to respond to both of you in this email.
>
> This implementation only removes files that were added via the add-symbol-file command.
> The add-symbol-file command takes as parameter the address of the text session. In this
> context I think the text address is the most appropriate way to remove a file because:
> 1) the user knows exactly where the .text section was loaded,
So how do you handle the case of there being no .text section at all?
> 2) an application can load shared libraries several times at different addresses (it's a requirement for me), and
> 3) I can't think of a good reason why someone would add a second symbol file at the same address.
> Most likely this is a user error that should have been reported by add-symbol-file.
>
> Note that currently in Option 4 below ADDR is in fact "objf->addr_low", but the command could be more generous
> by searching first which file corresponds to ADDR and then removing it. This would be more flexible and an
> alternative to Option 3, for instance.
You lost me here.
>
> 1) remove-symbol-file FILE
> 2) remove-symbol-file FILE ADDR
> 3) remove-symbol-file -s .data DATA_ADDR
> 4) remove-symbol-file ADDR
--
Pedro Alves
^ permalink raw reply [flat|nested] 25+ messages in thread
* RE: [PATCH 0/3] remove-symbol-file
2013-04-24 20:49 ` Pedro Alves
@ 2013-04-25 17:25 ` Blanc, Nicolas
2013-04-26 19:13 ` Pedro Alves
0 siblings, 1 reply; 25+ messages in thread
From: Blanc, Nicolas @ 2013-04-25 17:25 UTC (permalink / raw)
To: Pedro Alves; +Cc: Tom Tromey, gdb-patches
>> session. In this context I think the text address is the most appropriate way to remove a file because:
>> 1) the user knows exactly where the .text section was loaded,
>
> So how do you handle the case of there being no .text section at all?
It's a requirement of the add-symbol-file command [1]. The existing implementation of add-symbol-file assumes
that the *mandatory* load-address argument (terminology from GDB's manual) is the address of the text section.
See the implementation of add-symbol-file:
if (argcnt == 1)
{
/* The second argument is always the text address at which
to load the program. */
sect_opts[section_index].name = ".text";
The second argument is not optional. The add-symbol-file command returns an error if no address is specified.
>> Note that currently in Option 4 below ADDR is in fact
>> "objf->addr_low", but the command could be more generous by searching
>> first which file corresponds to ADDR and then removing it. This would be more flexible and an alternative to Option 3, for instance.
>You lost me here.
It's an idea that you and Tom gave me. Given an arbitrary address, remove-symbol-file could figure out the file that
corresponds to this address and remove it. This could make the command more flexible. But thinking twice I think that the current
implementation of remove-symbol-file does the right thing by identifying the file to remove using the address from the
add-symbol-file command. The user knows what address he passed to add-symbol-file.
>>
>> 1) remove-symbol-file FILE
>> 2) remove-symbol-file FILE ADDR
>> 3) remove-symbol-file -s .data DATA_ADDR
>> 4) remove-symbol-file ADDR
[1]
add-symbol-file filename address
add-symbol-file filename address [ -readnow ]
add-symbol-file filename address -s section address ...
The add-symbol-file command reads additional symbol table information from the file filename. You would use this command when filename has been dynamically loaded (by some other means) into the program that is running. address should be the memory address at which the file has been loaded; gdb cannot figure this out for itself.
Nicolas
Intel GmbH
Dornacher Strasse 1
85622 Feldkirchen/Muenchen, Deutschland
Sitz der Gesellschaft: Feldkirchen bei Muenchen
Geschaeftsfuehrer: Christian Lamprechter, Hannes Schwaderer, Douglas Lusk
Registergericht: Muenchen HRB 47456
Ust.-IdNr./VAT Registration No.: DE129385895
Citibank Frankfurt a.M. (BLZ 502 109 00) 600119052
^ permalink raw reply [flat|nested] 25+ messages in thread* Re: [PATCH 0/3] remove-symbol-file
2013-04-25 17:25 ` Blanc, Nicolas
@ 2013-04-26 19:13 ` Pedro Alves
0 siblings, 0 replies; 25+ messages in thread
From: Pedro Alves @ 2013-04-26 19:13 UTC (permalink / raw)
To: Blanc, Nicolas; +Cc: Tom Tromey, gdb-patches
On 04/25/2013 09:38 AM, Blanc, Nicolas wrote:
>
>
>>> session. In this context I think the text address is the most appropriate way to remove a file because:
>>> 1) the user knows exactly where the .text section was loaded,
>>
>> So how do you handle the case of there being no .text section at all?
>
> It's a requirement of the add-symbol-file command [1]. The existing implementation of add-symbol-file assumes
> that the *mandatory* load-address argument (terminology from GDB's manual) is the address of the text section.
> See the implementation of add-symbol-file:
>
> if (argcnt == 1)
> {
> /* The second argument is always the text address at which
> to load the program. */
> sect_opts[section_index].name = ".text";
>
> The second argument is not optional. The add-symbol-file command returns an error if no address is specified.
As I mentioned before, in the add case, you can just pass in a
random ADDR, I think gdb copes:
(gdb) add-symbol-file ~/data.o 0x111 -s .data 0x2000
add symbol table from file "/home/pedro/data.o" at
.text_addr = 0x111
.data_addr = 0x2000
(y or n) y
Reading symbols from /home/pedro/data.o...warning: section .text not found in /home/pedro/data.o
>>> Note that currently in Option 4 below ADDR is in fact
>>> "objf->addr_low", but the command could be more generous by searching
>>> first which file corresponds to ADDR and then removing it. This would be more flexible and an alternative to Option 3, for instance.
>> You lost me here.
>
> It's an idea that you and Tom gave me. Given an arbitrary address, remove-symbol-file could figure out the file that
> corresponds to this address and remove it. This could make the command more flexible.
Hmm, how is that different from what the command is currently
doing? /me looks
> But thinking twice I think that the current
> implementation of remove-symbol-file does the right thing by identifying the file to remove using the address from the
> add-symbol-file command. The user knows what address he passed to add-symbol-file.
Ah, so the current implementation stores the ADDR the user specified
with add-symbol-file. Why didn't you say so? ;-)
Okay, I guess that's good enough. We can add support for "-s" too
to remove- if ever necessary.
>>> 1) remove-symbol-file FILE
>>> 2) remove-symbol-file FILE ADDR
>>> 3) remove-symbol-file -s .data DATA_ADDR
>>> 4) remove-symbol-file ADDR
--
Pedro Alves
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 0/3] remove-symbol-file
2013-04-16 11:22 [PATCH 0/3] remove-symbol-file Nicolas Blanc
` (4 preceding siblings ...)
2013-04-24 9:22 ` [PATCH 0/3] remove-symbol-file Tom Tromey
@ 2013-04-24 17:46 ` Pedro Alves
5 siblings, 0 replies; 25+ messages in thread
From: Pedro Alves @ 2013-04-24 17:46 UTC (permalink / raw)
To: Nicolas Blanc; +Cc: gdb-patches
On 04/16/2013 08:51 AM, Nicolas Blanc wrote:
> This patch adds a command for removing individual symbol files.
>
> The symbol-file command without parameter can be used to clear
> all symbol-file information. This command is not practical if
> the user needs to remove just one file, however.
>
> Apple provides its own remove-symbol-file command but the code
> was not upstreamed [1]. I provide here my own implementation.
> There are two main differences between the command from Apple and
> mine:
>
> 1) The remove-symbol-file command from Apple takes as parameter
> the file to remove whereas this implementation requires the load
> address of the file. Hence, this command is able to unload
> symbol for files that have been loaded multiple times.
Some points to consider on the interface/spec/requirements, before
the user interface is carved in stone.
Doesn't it also make it more complicated to use for the more common
case of not loading files multiple times? For the case of multiple
symbol files with the same file, we could warn/query the user to
remove all with the same file.
I believe one can actually load overlapping files with add-symbol-file.
So "load address" is not a unique identifier, though in practice it'll
work most of the time.
Also, "load address" is not clear here. With "add-symbol-file",
the specified addresses is actually the ".text" section's address.
(gdb) help add-symbol-file
Load symbols from FILE, assuming FILE has been dynamically loaded.
Usage: add-symbol-file FILE ADDR [-s <SECT> <SECT_ADDR> -s <SECT> <SECT_ADDR> ...]
ADDR is the starting address of the file's text.
...
if (argcnt == 1)
{
/* The second argument is always the text address at which
to load the program. */
sect_opts[section_index].name = ".text";
sect_opts[section_index].value = arg;
...
This actually looks a bit problematic for the remove case, because
there may not be a .text segment at all, or the .text section may
not be the lowest section loaded in the text segment, or the text
segment may not be the lowest loaded segment. In the add case,
if there's no .text, you pass in a random ADDR, I believe.
So should we consider mirroring the add-symbol-file syntax?
remove-symbol-file FILE
remove-symbol-file FILE ADDR
remove-symbol-file -s .data DATA_ADDR
And in all cases, if there are overlapping symbol files,
warn/remove all that match?
How are manually added symbol files listed, BTW?
Should we have a new "info symbol-files" command listing manually
added symbol files?
Maybe we should have a unique number to each symbol file? Then the user
could list and remove them by number (like e.g., breakpoints) instead.
Or maybe even generalize that into "info objfiles". Dunno.
> I would appreciate feedback from the maintainers of GDB at Apple to
> help upstream a command that satisfies the community at large.
There are none. Apple stopped caring about upstream GDB long ago.
--
Pedro Alves
^ permalink raw reply [flat|nested] 25+ messages in thread