Re: [RFA] new set/show multiple-choice-auto-select commands

Markus Deuling
2008-01-15T09:29:00Z

[-- Attachment #1: Type: text/plain, Size: 2456 bytes --]

Joel Brobecker schrieb:

>
> (gdb) set multiple-choice-auto-select all
>
> (gdb) b normal_menu
> Breakpoint 5 at 0x8049517: file pck.adb, line 6.
> Breakpoint 6 at 0x804951d: file pck.adb, line 11.
> warning: Multiple breakpoints were set.
> Use the "delete" command to delete unwanted breakpoints.
>

Hi Joel,

I noticed you're working on a multiple symbol (thats how I call it ;-) ), too. I'm currently also working
on s.th. very similar. In 2007 I added a patch which prefers a symbol definition in a shared lib GDB currently
stands in (if built with -Bsymbolic) instead of a symbol for example found in the main executable.

I attached a patch which introduces a new command "set symbol-user-choice on" which is off per default. If set to on a symbol lookup finding
>1 appropriate symbol (for example break foo, with foo in main and in a shared lib) a user choice (decode_line_2) is invoked.

Here is a sample session using the multiply defined symbol testcase from gdb.base/solib-symbol.exp:

(gdb) br foo
Function "foo" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y

Breakpoint 1 (foo) pending.
(gdb) r
Starting program: /home/deuling/gdb/dev/build/gdb/testsuite/gdb.base/solib-symbol-main
in main

Breakpoint 1, foo ()
at /home/deuling/gdb/dev/gdb/testsuite/gdb.base/solib-symbol-lib.c:22
22 printf ("foo in lib\n");
(gdb) set symbol-user-choice on
(gdb) br foo2
[0] cancel
[1] all
[2] foo2 at /home/deuling/gdb/dev/gdb/testsuite/gdb.base/solib-symbol-main.c:39
[3] foo2 at /home/deuling/gdb/dev/gdb/testsuite/gdb.base/solib-symbol-lib.c:29
> 2 3
Breakpoint 2 at 0x8048523: file /home/deuling/gdb/dev/gdb/testsuite/gdb.base/solib-symbol-main.c, line 39.
Breakpoint 3 at 0xd03444: file /home/deuling/gdb/dev/gdb/testsuite/gdb.base/solib-symbol-lib.c, line 29.
warning: Multiple breakpoints were set.
Use the "delete" command to delete unwanted breakpoints.
(gdb)

So if >1 symbol is found the user can exactly choose which of these are meant.

Maybe we can merge the patches? I'd like to see the "set symbol-user-choice on|off" command rather in a language-undependent place
like linespec.c as in a language-specific file like ada. What do you think? Do you see the possibility for that?

Btw, I'd really appreciate your feedback on that patch. Would this be ok for mainline?

Regards,
Markus

--
Markus Deuling
GNU Toolchain for Linux on Cell BE
deuling@de.ibm.com

[-- Attachment #2: diff-user-choice-symbols --]
[-- Type: text/plain, Size: 4415 bytes --]

diff -urpN src/gdb/linespec.c dev/gdb/linespec.c
--- src/gdb/linespec.c 2008-01-01 23:53:11.000000000 +0100
+++ dev/gdb/linespec.c 2008-01-08 15:33:48.000000000 +0100
@@ -36,6 +36,7 @@
#include "linespec.h"
#include "exceptions.h"
#include "language.h"
+#include "gdbcmd.h"

/* We share this one with symtab.c, but it is not exported widely. */

@@ -140,6 +141,16 @@ static struct
symtabs_and_lines minsym_found (int funfirstline,
struct minimal_symbol *msymbol);

+static int symbol_user_choice = 0;
+
+static void
+show_symbol_user_choice (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("User choice for multiple symbols is %s.\n"),
+ value);
+}
+
/* Helper functions. */

/* Issue a helpful hint on using the command completion feature on
@@ -1725,9 +1736,35 @@ decode_variable (char *copy, int funfirs
struct symbol *sym;
/* The symtab that SYM was found in. */
struct symtab *sym_symtab;
-
struct minimal_symbol *msymbol;

+ if (symbol_user_choice && !file_symtab)
+ {
+ int nelts;
+ struct symbol_search *symbols, *p;
+ struct cleanup *chain;
+ struct symbol **sym_arr;
+
+ search_symbols (copy, FUNCTIONS_DOMAIN, 0, (char **) NULL, &symbols);
+ chain = make_cleanup_free_search_symbols (symbols);
+
+ nelts = count_symbols (symbols);
+ if (nelts)
+ {
+ int idx = 0;
+ sym_arr = xmalloc ((nelts) * sizeof (struct symbol *));
+ make_cleanup (xfree, sym_arr);
+
+ for (p = symbols; p != NULL; p = p->next)
+ if (p->symbol)
+ sym_arr[idx++] = p->symbol;
+
+ return decode_line_2 (sym_arr, idx, funfirstline,
+ canonical);
+ }
+ }
+
+
sym = lookup_symbol (copy,
(file_symtab
? BLOCKVECTOR_BLOCK (BLOCKVECTOR (file_symtab),
@@ -1856,3 +1893,18 @@ minsym_found (int funfirstline, struct m
values.nelts = 1;
return values;
}
+
+
+void
+_initialize_linespec (void)
+{
+
+ /* Toggle wheter or not to let the user choose multiple defined symbols. */
+ add_setshow_boolean_cmd ("symbol-user-choice", class_support,
+ &symbol_user_choice,
+ _("Set whether the user is to choose a symbol when multiple symbols are defined."),
+ _("Show whether the user is to choose a symbol when multiple symbols are defined."),
+ _("Use \"on\" to let the user choose a symbol when multiple symbols are defined. Use \"off\" to pick the first of those symbols by default."),
+ NULL, show_symbol_user_choice, &setlist, &showlist);
+
+}
diff -urpN src/gdb/Makefile.in dev/gdb/Makefile.in
--- src/gdb/Makefile.in 2008-01-08 11:22:24.000000000 +0100
+++ dev/gdb/Makefile.in 2008-01-08 15:33:48.000000000 +0100
@@ -2331,7 +2331,7 @@ libunwind-frame.o: libunwind-frame.c $(d
$(gdb_string_h) $(libunwind_frame_h) $(complaints_h)
linespec.o: linespec.c $(defs_h) $(symtab_h) $(frame_h) $(command_h) \
$(symfile_h) $(objfiles_h) $(source_h) $(demangle_h) $(value_h) \
- $(completer_h) $(cp_abi_h) $(parser_defs_h) $(block_h) \
+ $(completer_h) $(cp_abi_h) $(parser_defs_h) $(block_h) $(gdbcmd_h)\
$(objc_lang_h) $(linespec_h) $(exceptions_h) $(language_h)
linux-fork.o: linux-fork.c $(defs_h) $(inferior_h) $(regcache_h) $(gdbcmd_h) \
$(infcall_h) $(gdb_assert_h) $(gdb_string_h) $(linux_fork_h) \
diff -urpN src/gdb/symtab.c dev/gdb/symtab.c
--- src/gdb/symtab.c 2008-01-03 22:30:13.000000000 +0100
+++ dev/gdb/symtab.c 2008-01-08 15:33:48.000000000 +0100
@@ -2778,6 +2778,21 @@ file_matches (char *file, char *files[],
return 0;
}

+
+/* Returns number of elements in search reusult SYMBOLS. */
+
+int
+count_symbols (struct symbol_search *symbols)
+{
+ struct symbol_search *p;
+ int nr = 0;
+
+ for (p = symbols; p != NULL; p = p->next)
+ nr++;
+
+ return nr;
+}
+
/* Free any memory associated with a search. */
void
free_search_symbols (struct symbol_search *symbols)
diff -urpN src/gdb/symtab.h dev/gdb/symtab.h
--- src/gdb/symtab.h 2008-01-01 23:53:13.000000000 +0100
+++ dev/gdb/symtab.h 2008-01-08 15:33:48.000000000 +0100
@@ -1385,6 +1385,7 @@ struct symbol_search

extern void search_symbols (char *, domain_enum, int, char **,
struct symbol_search **);
+extern int count_symbols (struct symbol_search *);
extern void free_search_symbols (struct symbol_search *);
extern struct cleanup *make_cleanup_free_search_symbols (struct symbol_search
*);