This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [PATCH] Revised display-linkage-name
- From: Michael Eager <eager at eagerm dot com>
- To: Keith Seitz <keiths at redhat dot com>
- Cc: gdb-patches at sourceware dot org, Eli Zaretskii <eliz at gnu dot org>, Tom Tromey <tromey at redhat dot com>
- Date: Wed, 17 Jul 2013 11:51:03 -0700
- Subject: Re: [PATCH] Revised display-linkage-name
- References: <519D086A dot 50105 at eagerm dot com> <51BF47DB dot 6070709 at eagerm dot com> <51DD891D dot 7090009 at eagerm dot com> <51DF3F97 dot 90805 at redhat dot com> <51E07263 dot 6080605 at eagerm dot com>
On 07/12/13 14:17, Michael Eager wrote:
On 07/11/13 16:28, Keith Seitz wrote:
On 07/10/2013 09:17 AM, Michael Eager wrote:
Can someone review and approve this patch?
Tom's been a little busy of late, so I thought I would try to help out here a little. You'll be one
step closer to approval!
Your patches no longer apply cleanly to HEAD, so I fixed them up to play with them. I'll be
commenting on this version.
...
Keith
Thanks. I'll look at your comments and submit an update.
I'll eliminate the whitespace changes; I find them annoying as well.
I'll allow passing a NULL for the linkname where the result is
not used. I'm not sure how the default got set to "on"; that was
not intentional, and yes, it causes a lot of noise regressions.
"Prepend" appears to be listed in some dictionaries as a synonym
for "prefix," but it may sound like jargon; I'll change it.
I'll look at the suggestions about the test suite. I've reasonable
experience with tcl/expect, but tcl always seems to turn into a tar pit.
If you have a different term for "linkage name" I'd be happy to
hear it. The only use of this that I was able to find is in the
DWARF Standard. Or I can add a definition to the docs to clarify.
I believe I have addressed your comments, as well as Eli's previous
notes about the docs. I didn't merge the tests cases into a single proc.
BTW, "prepend" appears in several places in the docs. I replaced it this
patch with prefix. If there is a concern that "prepend" sounds like jargon,
then the other uses should be changed as well.
gdb/
2013-07-17 Michael Eager <eager@eagercon.com>
* NEWS: Announcement.
* ada-lang.c: Update calls to find_frame_funname (pass NULL for linkname).
* disasm.c: Likewise.
* python/py-frame.c: Likewise.
* annotate.c (annotate_linkage_name): New.
* annotate.h (annotate_linkage_name): New decl.
* breakpoint.c (print_breakpoint_location): Print linkage name.
* defs.h (build_address_symbolic): Add linkname arg.
* printcmd.c (print_address_symbolic): Print linkage name.
(build_address_symbolic): Return linkage name.
* annotate.c (annotate_linkage_name): New.
* annotate.h (annotate_linkage_name): Declare.
* stack.c (find_frame_funname): Return linkage name.
(print_frame): Print linkage name.
* stack.h (find_frame_funname): Update declaration.
* top.c (display_linkage_name, display_linkage_name_len): New.
(show_display_linkage_name, show_display_linkage_name_len): New cmds.
* top.h (display_linkage_name, display_linkage_name_len): Declare.
gdb/doc
2013-07-17 Michael Eager <eager@eagercon.com>
* gdb.texinfo: Add description.
gdb/testsuite
2013-07-17 Michael Eager <eager@eagercon.com>
* gdb.cp/display-linkage-name.exp: New.
* gdb.cp/display-linkage-name.cc: New.
--
Michael Eager eager@eagercon.com
1960 Park Blvd., Palo Alto, CA 94306 650-325-8077
From bc509670f21f11aee21084aba60b58dd46391435 Mon Sep 17 00:00:00 2001
From: Michael Eager <eager@eagercon.com>
Date: Wed, 17 Jul 2013 11:37:04 -0700
Subject: [PATCH] GDB - display linkage name command
---
gdb/NEWS | 14 +++
gdb/ada-lang.c | 5 +-
gdb/annotate.c | 7 ++
gdb/annotate.h | 2 +
gdb/breakpoint.c | 28 ++++++
gdb/defs.h | 1 +
gdb/disasm.c | 4 +-
gdb/doc/gdb.texinfo | 28 +++++-
gdb/printcmd.c | 43 ++++++++-
gdb/python/py-frame.c | 2 +-
gdb/stack.c | 44 ++++++++-
gdb/stack.h | 3 +-
gdb/testsuite/gdb.cp/display-linkage-name.cc | 36 +++++++
gdb/testsuite/gdb.cp/display-linkage-name.exp | 129 ++++++++++++++++++++++++++
gdb/top.c | 40 +++++++-
gdb/top.h | 2 +
16 files changed, 373 insertions(+), 15 deletions(-)
create mode 100644 gdb/testsuite/gdb.cp/display-linkage-name.cc
create mode 100644 gdb/testsuite/gdb.cp/display-linkage-name.exp
diff --git a/gdb/NEWS b/gdb/NEWS
index e469f1e..ac62062 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -56,6 +56,20 @@ show range-stepping
--configuration
Display the details of GDB configure-time options.
+* New commands have been added to select whether to display the
+ linker symbol name for functions in addition to the name used in the
+ source. This may be useful when debugging programs where the compiler
+ prefixes characters to the source symbol, such as a leading underscore:
+
+set|show display-linkage-name [off|on]
+
+ The default is "off", to not display the linkage name.
+
+set|show display-linkage-name-len
+
+ Set the maximum number of characters to display in the linkage name,
+ if display-linkage-name is on. The default is 20.
+
* The command 'tsave' can now support new option '-ctf' to save trace
buffer in Common Trace Format.
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index dc5f2b6..3430e3f 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -11114,6 +11114,7 @@ is_known_support_routine (struct frame_info *frame)
{
struct symtab_and_line sal;
char *func_name;
+ const char *linkname;
enum language func_lang;
int i;
const char *fullname;
@@ -11152,7 +11153,7 @@ is_known_support_routine (struct frame_info *frame)
/* Check whether the function is a GNAT-generated entity. */
- find_frame_funname (frame, &func_name, &func_lang, NULL);
+ find_frame_funname (frame, &func_name, NULL, &func_lang, NULL);
if (func_name == NULL)
return 1;
@@ -11227,7 +11228,7 @@ ada_unhandled_exception_name_addr_from_raise (void)
char *func_name;
enum language func_lang;
- find_frame_funname (fi, &func_name, &func_lang, NULL);
+ find_frame_funname (fi, &func_name, NULL, &func_lang, NULL);
if (func_name != NULL)
{
make_cleanup (xfree, func_name);
diff --git a/gdb/annotate.c b/gdb/annotate.c
index ccba5fe..84edeac 100644
--- a/gdb/annotate.c
+++ b/gdb/annotate.c
@@ -582,6 +582,13 @@ breakpoint_changed (struct breakpoint *b)
}
void
+annotate_linkage_name (void)
+{
+ if (annotation_level == 2)
+ printf_filtered (("\n\032\032linkage_name\n"));
+}
+
+void
_initialize_annotate (void)
{
observer_attach_breakpoint_created (breakpoint_changed);
diff --git a/gdb/annotate.h b/gdb/annotate.h
index 72c4f19..33a9a0e 100644
--- a/gdb/annotate.h
+++ b/gdb/annotate.h
@@ -98,5 +98,7 @@ extern void annotate_elt_rep_end (void);
extern void annotate_elt (void);
extern void annotate_array_section_end (void);
+extern void annotate_linkage_name (void);
+
extern void (*deprecated_annotate_signalled_hook) (void);
extern void (*deprecated_annotate_signal_hook) (void);
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 4d09b30..e40af59 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -5704,6 +5704,34 @@ print_breakpoint_location (struct breakpoint *b,
ui_out_text (uiout, "in ");
ui_out_field_string (uiout, "func",
SYMBOL_PRINT_NAME (sym));
+ if (display_linkage_name)
+ {
+ struct bound_minimal_symbol msymbol =
+ lookup_minimal_symbol_by_pc (loc->address);
+ if (msymbol.minsym != NULL
+ && strcmp (SYMBOL_LINKAGE_NAME (msymbol.minsym),
+ SYMBOL_PRINT_NAME (sym)) != 0)
+ {
+ ui_out_text (uiout, " [");
+
+ if (strlen (SYMBOL_LINKAGE_NAME (msymbol.minsym))
+ > display_linkage_name_len)
+ {
+ char *lname = alloca (display_linkage_name_len + 4);
+
+ strncpy (lname, SYMBOL_LINKAGE_NAME (msymbol.minsym),
+ display_linkage_name_len);
+ lname[display_linkage_name_len] = '\0';
+ strcat (lname, "...");
+ ui_out_field_string (uiout, "linkage-name", lname);
+ }
+ else
+ ui_out_field_string (uiout, "linkage-name",
+ SYMBOL_LINKAGE_NAME (msymbol.minsym));
+
+ ui_out_text (uiout, "]");
+ }
+ }
ui_out_text (uiout, " ");
ui_out_wrap_hint (uiout, wrap_indent_at_field (uiout, "what"));
ui_out_text (uiout, "at ");
diff --git a/gdb/defs.h b/gdb/defs.h
index 014d7d4..0d10a0d 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -336,6 +336,7 @@ extern int build_address_symbolic (struct gdbarch *,
CORE_ADDR addr,
int do_demangle,
char **name,
+ char **linkname,
int *offset,
char **filename,
int *line,
diff --git a/gdb/disasm.c b/gdb/disasm.c
index e643c2d..396dce9 100644
--- a/gdb/disasm.c
+++ b/gdb/disasm.c
@@ -127,8 +127,8 @@ dump_insns (struct gdbarch *gdbarch, struct ui_out *uiout,
ui_out_text (uiout, pc_prefix (pc));
ui_out_field_core_addr (uiout, "address", gdbarch, pc);
- if (!build_address_symbolic (gdbarch, pc, 0, &name, &offset, &filename,
- &line, &unmapped))
+ if (!build_address_symbolic (gdbarch, pc, 0, &name, NULL, &offset,
+ &filename, &line, &unmapped))
{
/* We don't care now about line, filename and
unmapped. But we might in the future. */
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index fae54e4..4f48c4c 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -15933,8 +15933,31 @@ line 1574.
@}
(@value{GDBP})
@end smallexample
-@end table
+@kindex set display-linkage-name
+@cindex list linkage names
+@item set display-linkage-name
+@itemx show display-linkage-name
+Control displaying linker symbol names for functions.
+
+The default is @code{off}, which means that @value{GDBN} will only
+display the function name used in the source. When @code{on}, @value{GDBN}
+will also display the linkage name for the symbol name within brackets if it is
+different from the name in the source.
+
+The linkage name is the name used by the linker for a symbol. This may be
+the same as the symbol's name in the source, or may be different if the compiler
+adds a prefix to the name (for example, an underscore) or modifies it, such
+as by C@t{++} name mangling.
+
+This is different from "set print asm-demangle on" which only displays
+the linkage name for C@t{++} symbols and does not display the source name.
+
+@kindex show display-linkage-name-len
+@itemx show display-linkage-name-len @var{len}
+Set the maximum number of characters of linkage name to display. The
+@code{show} command displays the current setting. The default is @code{20}.
+@end table
@node Altering
@chapter Altering Execution
@@ -29250,6 +29273,9 @@ is not.
@item what
Some extra data, the exact contents of which are type-dependent.
+@item linkage-name
+The name used by the linker for this function.
+
@end table
For example, here is what the output of @code{-break-insert}
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 99d4dba..e3b8c21 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -51,6 +51,7 @@
#include "cli/cli-utils.h"
#include "format.h"
#include "source.h"
+#include "top.h"
#ifdef TUI
#include "tui/tui.h" /* For tui_active et al. */
@@ -569,17 +570,19 @@ print_address_symbolic (struct gdbarch *gdbarch, CORE_ADDR addr,
int do_demangle, char *leadin)
{
char *name = NULL;
+ char *linkname = NULL;
char *filename = NULL;
int unmapped = 0;
int offset = 0;
int line = 0;
- /* Throw away both name and filename. */
+ /* Throw away name, linkname, and filename. */
struct cleanup *cleanup_chain = make_cleanup (free_current_contents, &name);
make_cleanup (free_current_contents, &filename);
+ make_cleanup (free_current_contents, &linkname);
- if (build_address_symbolic (gdbarch, addr, do_demangle, &name, &offset,
- &filename, &line, &unmapped))
+ if (build_address_symbolic (gdbarch, addr, do_demangle, &name, &linkname,
+ &offset, &filename, &line, &unmapped))
{
do_cleanups (cleanup_chain);
return 0;
@@ -591,6 +594,28 @@ print_address_symbolic (struct gdbarch *gdbarch, CORE_ADDR addr,
else
fputs_filtered ("<", stream);
fputs_filtered (name, stream);
+
+ /* Print linkage name after source name if requested and different. */
+ if (display_linkage_name
+ && linkname != NULL && strcmp (name, linkname) != 0)
+ {
+ fputs_filtered (" [", stream);
+
+ if (strlen (linkname) > display_linkage_name_len)
+ {
+ char *lname = alloca (display_linkage_name_len + 4);
+
+ strncpy (lname, linkname, display_linkage_name_len);
+ lname[display_linkage_name_len] = '\0';
+ strcat (lname, "...");
+ fputs_filtered (lname, stream);
+ }
+ else
+ fputs_filtered (linkname, stream);
+
+ fputs_filtered ("]", stream);
+ }
+
if (offset != 0)
fprintf_filtered (stream, "+%u", (unsigned int) offset);
@@ -623,6 +648,7 @@ build_address_symbolic (struct gdbarch *gdbarch,
CORE_ADDR addr, /* IN */
int do_demangle, /* IN */
char **name, /* OUT */
+ char **linkname, /* OUT */
int *offset, /* OUT */
char **filename, /* OUT */
int *line, /* OUT */
@@ -637,6 +663,10 @@ build_address_symbolic (struct gdbarch *gdbarch,
/* Let's say it is mapped (not unmapped). */
*unmapped = 0;
+ /* Let's say the link name is the same as the symbol name. */
+ if (linkname)
+ *linkname = 0;
+
/* Determine if the address is in an overlay, and whether it is
mapped. */
if (overlay_debugging)
@@ -740,6 +770,13 @@ build_address_symbolic (struct gdbarch *gdbarch,
*line = sal.line;
}
}
+
+ /* If we have both symbol names and they are different, let caller know. */
+ if (msymbol != NULL && symbol != NULL
+ && strcmp (SYMBOL_LINKAGE_NAME (msymbol), SYMBOL_LINKAGE_NAME (symbol)) != 0)
+ if (linkname)
+ *linkname = xstrdup (SYMBOL_LINKAGE_NAME (msymbol));
+
return 0;
}
diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c
index f960b08..6b48140 100644
--- a/gdb/python/py-frame.c
+++ b/gdb/python/py-frame.c
@@ -131,7 +131,7 @@ frapy_name (PyObject *self, PyObject *args)
{
FRAPY_REQUIRE_VALID (self, frame);
- find_frame_funname (frame, &name, &lang, NULL);
+ find_frame_funname (frame, &name, NULL, &lang, NULL);
}
if (except.reason < 0)
diff --git a/gdb/stack.c b/gdb/stack.c
index 313d57f..4bc8824 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -55,6 +55,7 @@
#include "psymtab.h"
#include "symfile.h"
#include "python/python.h"
+#include "top.h"
void (*deprecated_selected_frame_level_changed_hook) (int);
@@ -1000,15 +1001,19 @@ get_last_displayed_sal (struct symtab_and_line *sal)
/* Attempt to obtain the FUNNAME, FUNLANG and optionally FUNCP of the function
- corresponding to FRAME. FUNNAME needs to be freed by the caller. */
+ corresponding to FRAME. FUNNAME needs to be freed by the caller.
+ Set LINKNAME to linkage name (symbol used by linker) if LINKNAME is non-null
+ and linkage name differs from source name. */
void
find_frame_funname (struct frame_info *frame, char **funname,
- enum language *funlang, struct symbol **funcp)
+ const char **linkname, enum language *funlang,
+ struct symbol **funcp)
{
struct symbol *func;
*funname = NULL;
+ *linkname = NULL;
*funlang = language_unknown;
if (funcp)
*funcp = NULL;
@@ -1045,6 +1050,12 @@ find_frame_funname (struct frame_info *frame, char **funname,
memset (&msymbol, 0, sizeof (msymbol));
if (msymbol.minsym != NULL
+ && strcmp (SYMBOL_LINKAGE_NAME (msymbol.minsym),
+ SYMBOL_LINKAGE_NAME (func)) != 0)
+ if (linkname)
+ *linkname = SYMBOL_LINKAGE_NAME (msymbol.minsym);
+
+ if (msymbol.minsym != NULL
&& (SYMBOL_VALUE_ADDRESS (msymbol.minsym)
> BLOCK_START (SYMBOL_BLOCK_VALUE (func))))
{
@@ -1102,6 +1113,7 @@ print_frame (struct frame_info *frame, int print_level,
struct gdbarch *gdbarch = get_frame_arch (frame);
struct ui_out *uiout = current_uiout;
char *funname = NULL;
+ const char *linkname = NULL;
enum language funlang = language_unknown;
struct ui_file *stb;
struct cleanup *old_chain, *list_chain;
@@ -1115,7 +1127,7 @@ print_frame (struct frame_info *frame, int print_level,
stb = mem_fileopen ();
old_chain = make_cleanup_ui_file_delete (stb);
- find_frame_funname (frame, &funname, &funlang, &func);
+ find_frame_funname (frame, &funname, &linkname, &funlang, &func);
make_cleanup (xfree, funname);
annotate_frame_begin (print_level ? frame_relative_level (frame) : 0,
@@ -1147,9 +1159,33 @@ print_frame (struct frame_info *frame, int print_level,
fprintf_symbol_filtered (stb, funname ? funname : "??",
funlang, DMGL_ANSI);
ui_out_field_stream (uiout, "func", stb);
+
+ /* Print linkage name after source name if requested and different. */
+ if ((display_linkage_name || ui_out_is_mi_like_p (uiout))
+ && linkname != NULL && strcmp (funname, linkname) != 0)
+ {
+ annotate_linkage_name ();
+ ui_out_text (uiout, " [");
+
+ if (strlen (linkname) > display_linkage_name_len)
+ {
+ char *lname = alloca (display_linkage_name_len + 4);
+
+ strncpy (lname, linkname, display_linkage_name_len);
+ lname[display_linkage_name_len] = '\0';
+ strcat (lname, "...");
+ ui_out_text (uiout, lname);
+ }
+ else
+ ui_out_text (uiout, linkname);
+
+ ui_out_text (uiout, "]");
+ ui_out_field_stream (uiout, "linkage_name", stb);
+ }
+
ui_out_wrap_hint (uiout, " ");
annotate_frame_args ();
-
+
ui_out_text (uiout, " (");
if (print_args)
{
diff --git a/gdb/stack.h b/gdb/stack.h
index 4badf19..9248c85 100644
--- a/gdb/stack.h
+++ b/gdb/stack.h
@@ -23,7 +23,8 @@
void select_frame_command (char *level_exp, int from_tty);
void find_frame_funname (struct frame_info *frame, char **funname,
- enum language *funlang, struct symbol **funcp);
+ const char **linkname, enum language *funlang,
+ struct symbol **funcp);
typedef void (*iterate_over_block_arg_local_vars_cb) (const char *print_name,
struct symbol *sym,
diff --git a/gdb/testsuite/gdb.cp/display-linkage-name.cc b/gdb/testsuite/gdb.cp/display-linkage-name.cc
new file mode 100644
index 0000000..d9db673
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/display-linkage-name.cc
@@ -0,0 +1,36 @@
+/* This test script is part of GDB, the GNU debugger.
+
+ 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/>. */
+
+void foo (const char *msg)
+{
+} /* set breakpoint 1 here */
+
+void fun_with_a_long_name (int i, const char *s, double d)
+{
+ foo ("Hello"); /* set breakpoint 2 here */
+}
+
+void goo (void)
+{
+ fun_with_a_long_name (1, "abc", 3.14);
+}
+
+int main (void)
+{
+ goo();
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.cp/display-linkage-name.exp b/gdb/testsuite/gdb.cp/display-linkage-name.exp
new file mode 100644
index 0000000..6cde8af
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/display-linkage-name.exp
@@ -0,0 +1,129 @@
+# 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/>.
+
+# This file was written by Michael Eager (eager@eagercon.com).
+
+if { [skip_cplus_tests] } { continue }
+
+standard_testfile .cc
+
+if {[get_compiler_info "c++"]} {
+ return -1
+}
+
+if { [prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}] } {
+ return -1
+}
+
+# set break at functions
+
+set bp1 [gdb_get_line_number "set breakpoint 1 here"]
+set bp2 [gdb_get_line_number "set breakpoint 2 here"]
+
+if {![gdb_breakpoint "foo"]} {
+ fail "set breakpoint foo"
+}
+
+if {![gdb_breakpoint "fun_with_a_long_name"]} {
+ fail "set breakpoint fun_with_a_long_name"
+}
+
+########################
+# Test with display-linkage-name off
+
+gdb_test_no_output "set display-linkage-name off" ""
+
+gdb_test "info break" \
+ "Num Type\[ \]+Disp Enb Address\[\t \]+What.*
+1\[\t \]+breakpoint keep y.* in foo(.*) at .*$srcfile:$bp1.*
+2\[\t \]+breakpoint keep y.* in fun_with_a_long_name(.*) at .*$srcfile:$bp2.*" \
+ "info breakpoint - display off"
+
+gdb_run_cmd
+set test "break at fun_with_a_long_name"
+gdb_test_multiple "continue" $test {
+ -re "Breakpoint 2, fun_with_a_long_name (.*) at.*$srcfile.$bp2.*$gdb_prompt $" {
+ pass $test
+ break
+ }
+}
+
+set bttable "#0 foo (.*) at.*\[\r\n\]"
+append bttable "#1 $hex in fun_with_a_long_name (.*) at .*$srcfile:.*\[\r\n\]"
+append bttable "#2 $hex in goo (.*) at .*$srcfile:.*\[\r\n\]"
+append bttable "#3 $hex in main (.*) at .*$srcfile:.*"
+
+gdb_test "backtrace" $bttable "backtrace - display off"
+
+########################
+# Test with display-linkage-name on
+
+gdb_test_no_output "set display-linkage-name on" ""
+
+gdb_test "info break" \
+ "Num Type\[ \]+Disp Enb Address\[\t \]+What.*
+1\[\t \]+breakpoint keep y.* in foo(.*) \\\[_Z3fooPKc\\\] at .*$srcfile:$bp1.*
+2\[\t \]+breakpoint keep y.* in fun_with_a_long_name(.*) \\\[_Z20fun_with_a_long_\.\.\.\\\] at .*$srcfile:$bp2.*" \
+ "info breakpoint - display on"
+
+gdb_run_cmd
+set test "break at fun_with_a_long_name - display on"
+gdb_test_multiple "continue" $test {
+ -re "Breakpoint 2, fun_with_a_long_name \\\[_Z20fun_with_a_long_...\\\] (.*) at.*$srcfile.$bp2.*$gdb_prompt $" {
+ pass $test
+ break
+ }
+}
+
+set bttable "#0 foo \\\[_Z3fooPKc\\\] (.*) at.*\[\r\n\]"
+append bttable "#1 $hex in fun_with_a_long_name \\\[_Z20fun_with_a_long_\.\.\.\\\] (.*) at .*$srcfile:.*\[\r\n\]"
+append bttable "#2 $hex in goo \\\[_Z3goov\\\] (.*) at .*$srcfile:.*\[\r\n\]"
+append bttable "#3 $hex in main (.*) at .*$srcfile:.*"
+
+gdb_test "backtrace" $bttable "backtrace - display on"
+
+########################
+# Test set/show display-linkage-name-len
+
+gdb_test "show display-linkage-name-len" \
+ "Length of linkage names \\(symbol used by linker\\) to be displayed is 20."
+
+gdb_test_no_output "set display-linkage-name-len 10" ""
+
+gdb_test "show display-linkage-name-len" \
+ "Length of linkage names \\(symbol used by linker\\) to be displayed is 10."
+
+gdb_test "info break" \
+ "Num Type\[ \]+Disp Enb Address\[\t \]+What.*
+1\[\t \]+breakpoint keep y.* in foo(.*) \\\[_Z3fooPKc\\\] at .*$srcfile:$bp1.*
+2\[\t \]+breakpoint keep y.* in fun_with_a_long_name(.*) \\\[_Z20fun_wi\.\.\.\\\] at .*$srcfile:$bp2.*" \
+ "info breakpoint - display 10"
+
+gdb_run_cmd
+set test "break at fun_with_a_long_name - display 10"
+gdb_test_multiple "continue" $test {
+ -re "Breakpoint 2, fun_with_a_long_name \\\[_Z20fun_wi\.\.\.\\\] (.*) at .*$srcfile:$bp2.*$gdb_prompt $" {
+ pass $test
+ break
+ }
+}
+
+set bttable "#0 foo \\\[_Z3fooPKc\\\] (.*) at.*\[\r\n\]"
+append bttable "#1 $hex in fun_with_a_long_name \\\[_Z20fun_wi\.\.\.\\\] (.*) at .*$srcfile:.*\[\r\n\]"
+append bttable "#2 $hex in goo \\\[_Z3goov\\\] (.*) at .*$srcfile:.*\[\r\n\]"
+append bttable "#3 $hex in main (.*) at .*$srcfile:.*"
+
+gdb_test "backtrace" $bttable "backtrace - display 10"
+
diff --git a/gdb/top.c b/gdb/top.c
index 46faaa7..c0f6f25 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -287,6 +287,29 @@ quit_cover (void)
quit_command ((char *) 0, 0);
}
#endif /* defined SIGHUP */
+
+/* Flag for whether we want to print linkage name for functions.
+ Length of linkage name to print. */
+
+int display_linkage_name = 0; /* Default is no. */
+int display_linkage_name_len = 20; /* Default is first 20 chars. */
+
+static void
+show_display_linkage_name (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("\
+Whether to display linkage name (symbol used by linker) of functions is %s.\n"),
+ value);
+}
+static void
+show_display_linkage_name_len (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("\
+Length of linkage names (symbol used by linker) to be displayed is %s.\n"),
+ value);
+}
/* Line number we are currently in, in a file which is being sourced. */
/* NOTE 1999-04-29: This variable will be static again, once we modify
@@ -1809,7 +1832,22 @@ Use \"on\" to enable the notification, and \"off\" to disable it."),
When set, GDB uses the specified path to search for data files."),
set_gdb_datadir, NULL,
&setlist,
- &showlist);
+ &showlist);
+
+ add_setshow_boolean_cmd ("display-linkage-name", class_support, &display_linkage_name, _("\
+Set whether to display linkage name (symbol used by linker) for functions."), _("\
+Show whether to display linkage name (symbol used by linker) for functions."), NULL,
+ NULL,
+ show_display_linkage_name,
+ &setlist, &showlist);
+
+ add_setshow_zinteger_cmd ("display-linkage-name-len", class_support, &display_linkage_name_len, _("\
+Set number of characters of linkage name to display."), _("\
+Show number of characters of linkage name to display."), NULL,
+ NULL,
+ show_display_linkage_name_len,
+ &setlist, &showlist);
+
}
void
diff --git a/gdb/top.h b/gdb/top.h
index 2f70539..5acb311 100644
--- a/gdb/top.h
+++ b/gdb/top.h
@@ -26,6 +26,8 @@ extern int saved_command_line_size;
extern FILE *instream;
extern int in_user_command;
extern int confirm;
+extern int display_linkage_name;
+extern int display_linkage_name_len;
extern char gdb_dirbuf[1024];
extern int inhibit_gdbinit;
extern const char gdbinit[];
--
1.8.1.4