[PATCH] Revised display-linkage-name

Michael Eager
2013-05-22T18:28:20Z

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

Attached is a revised patch to display the linkage name (the linker symbol)
along with the function name when setting, listing, or hitting a breakpoint.
This is a revision of http://sourceware.org/ml/gdb-patches/2013-03/msg00806.html.
(BTW, the gdb-patches mailing list archive doesn't show the original email from
3/18/13, quoted in the referenced message.)

Changes:
Add NEWS and docs.
Add linkage name to "info break" listing.
Add MI annotations.
Add command to set/show display length limit, remove define.
Add test case.

There is a minor inconsistency where the linkage name is displayed.
When setting/hitting a breakpoint, the linkage name is displayed
within brackets following the source name, before the arguments. In
the "info breakpoint" command, the linkage name is displayed in brackets
after the arguments. This is because SYMBOL_PRINT_NAME(sym) returns a
complete function signature, not just the function name.

The test case was added to gdb.cp for convenience, since it uses
the C++ compiler. The patch is not dependent on C++.

Tom -- can you verify that the MI support is correct? I don't have
any way to test this.

gdb/
2013-05-23 Michael Eager <eager@eagercon.com>

* NEWS: Announcement.
* ada-lang.c: Update calls to find_frame_funname.
* disasm.c: Likewise.
* python/py-frame.c: Likewise.
* annotate.c (annotate_linkage_name): New.
* annotate.h (annotate_linkage_name): Declare.
* 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.
* 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-05-23 Michael Eager <eager@eagercon.com>

* gdb.texinfo: Add description.

gdb/testsuite
2013-05-23 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

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: display-linkage-name.patch --]
[-- Type: text/x-patch; name="display-linkage-name.patch", Size: 26978 bytes --]

commit b7dd81ef7313eebf8ceeb6a592b4d2cb615190d8
Author: Michael Eager <eager@eagercon.com>
Date: Wed May 22 10:48:44 2013 -0700

GDB - Display Linkage Name

Display linkage name (symbol linker uses) where function name is displayed.

gdb:
* NEWS: Announcement.
* ada-lang.c: Update call to find_frame_funname.
* disasm.c (dump_insns): Likewise.
* python/py-frame.c (frapy_is_valid): Likewise.
* annotate.c (annotate_linkage_name): New.
* annotate.h (annotate_linkage_name): Declare.
* 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.
* 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.

doc:
* gdb.texinfo: Add description.

testsuite:
* gdb.cp/display-linkage-name.exp: New.
* gdb.cp/display-linkage-name.cc: New.

diff --git a/gdb/NEWS b/gdb/NEWS
index 7cd1646..4185c34 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -45,6 +45,20 @@ show debug nios2
--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
+ prepends 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 3510750..f73e0b1 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -11104,6 +11104,7 @@ is_known_support_routine (struct frame_info *frame)
{
struct symtab_and_line sal;
const char *func_name;
+ const char *linkname;
enum language func_lang;
int i;
const char *fullname;
@@ -11142,7 +11143,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, &linkname, &func_lang, NULL);
if (func_name == NULL)
return 1;

@@ -11209,9 +11210,10 @@ ada_unhandled_exception_name_addr_from_raise (void)
while (fi != NULL)
{
const char *func_name;
+ const char *linkname;
enum language func_lang;

- find_frame_funname (fi, &func_name, &func_lang, NULL);
+ find_frame_funname (fi, &func_name, &linkname, &func_lang, NULL);
if (func_name != NULL
&& strcmp (func_name, data->exception_info->catch_exception_sym) == 0)
break; /* We found the frame we were looking for... */
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 f4f9325..52dbcf4 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -5699,6 +5699,33 @@ 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 d8a1adb..9f32ea4 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -86,7 +86,7 @@
/* The O_BINARY flag is defined in fcntl.h on some non-Posix platforms.
It is used as an access modifier in calls to open(), where it acts
similarly to the "b" character in fopen()'s MODE argument. On Posix
- platforms it should be a no-op, so it is defined as 0 here. This
+ platforms it should be a no-op, so it is defined as 0 here. This
ensures that the symbol may be used freely elsewhere in gdb. */

#ifndef O_BINARY
@@ -160,7 +160,7 @@ extern char *debug_file_directory;
handler. Otherwise, SIGINT simply sets a flag; code that might
take a long time, and which ought to be interruptible, checks this
flag using the QUIT macro.
-
+
If GDB is built with Python support, it uses Python's low-level
interface to implement the flag. This approach makes it possible
for Python and GDB SIGINT handling to coexist seamlessly.
@@ -333,10 +333,11 @@ extern int print_address_symbolic (struct gdbarch *, CORE_ADDR,

extern int build_address_symbolic (struct gdbarch *,
CORE_ADDR addr,
- int do_demangle,
- char **name,
- int *offset,
- char **filename,
+ int do_demangle,
+ char **name,
+ char **linkname,
+ int *offset,
+ char **filename,
int *line,
int *unmapped);

@@ -716,9 +717,9 @@ extern int (*deprecated_ui_loop_hook) (int signo);
extern void (*deprecated_init_ui_hook) (char *argv0);
extern void (*deprecated_command_loop_hook) (void);
extern void (*deprecated_show_load_progress) (const char *section,
- unsigned long section_sent,
- unsigned long section_size,
- unsigned long total_sent,
+ unsigned long section_sent,
+ unsigned long section_size,
+ unsigned long total_sent,
unsigned long total_size);
extern void (*deprecated_print_frame_info_listing_hook) (struct symtab * s,
int line,
diff --git a/gdb/disasm.c b/gdb/disasm.c
index e643c2d..62fa34d 100644
--- a/gdb/disasm.c
+++ b/gdb/disasm.c
@@ -112,6 +112,7 @@ dump_insns (struct gdbarch *gdbarch, struct ui_out *uiout,
{
char *filename = NULL;
char *name = NULL;
+ char *linkname = NULL;

QUIT;
if (how_many >= 0)
@@ -127,8 +128,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, &linkname, &offset,
+ &filename, &line, &unmapped))
{
/* We don't care now about line, filename and
unmapped. But we might in the future. */
@@ -146,6 +147,7 @@ dump_insns (struct gdbarch *gdbarch, struct ui_out *uiout,
xfree (filename);
if (name != NULL)
xfree (name);
+ xfree (linkname);

ui_file_rewind (stb);
if (flags & DISASSEMBLY_RAW_INSN)
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 02c2408..5174726 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -15899,8 +15899,31 @@ line 1574.
@}
(@value{GDBP})
@end smallexample
-@end table

+@kindex set display-linkage-name @code{on}|@code{off}
+@kindex show display-linkage-name
+@cindex list linker symbol 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 symbol name used by the linker within brackets if it is
+different from the name in the source. This can be useful with compilers
+which may prepend characters to a source name, for example, an underscore.
+
+This is different from "set print asm-demangle on" which only displays
+the linkage name for C++ symbols and does not display the source name.
+
+@kindex set display-linkage-name-len
+@kindex show display-linkage-name-len
+@cindex list linker symbol names
+@item set display-linkage-name-len @var{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
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index 2cc33d0..994b503 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 both 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,27 @@ 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 +647,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 +662,9 @@ 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. */
+ *linkname = 0;
+
/* Determine if the address is in an overlay, and whether it is
mapped. */
if (overlay_debugging)
@@ -729,6 +757,12 @@ 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)
+ *linkname = xstrdup (SYMBOL_LINKAGE_NAME (msymbol));
+
return 0;
}

diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c
index e2eb9c5..2b2b64f 100644
--- a/gdb/python/py-frame.c
+++ b/gdb/python/py-frame.c
@@ -123,6 +123,7 @@ frapy_name (PyObject *self, PyObject *args)
{
struct frame_info *frame;
const char *name;
+ const char *linkname;
enum language lang;
PyObject *result;
volatile struct gdb_exception except;
@@ -131,7 +132,7 @@ frapy_name (PyObject *self, PyObject *args)
{
FRAPY_REQUIRE_VALID (self, frame);

- find_frame_funname (frame, &name, &lang, NULL);
+ find_frame_funname (frame, &name, &linkname, &lang, NULL);
}
GDB_PY_HANDLE_EXCEPTION (except);

diff --git a/gdb/stack.c b/gdb/stack.c
index d10e9b4..5465a2a 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);

@@ -1004,15 +1005,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. */
+ corresponding to FRAME.
+ 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, const 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;
@@ -1049,6 +1054,11 @@ find_frame_funname (struct frame_info *frame, const char **funname,
memset (&msymbol, 0, sizeof (msymbol));

if (msymbol.minsym != NULL
+ && strcmp (SYMBOL_LINKAGE_NAME (msymbol.minsym),
+ SYMBOL_LINKAGE_NAME (func)) != 0)
+ *linkname = SYMBOL_LINKAGE_NAME (msymbol.minsym);
+
+ if (msymbol.minsym != NULL
&& (SYMBOL_VALUE_ADDRESS (msymbol.minsym)
> BLOCK_START (SYMBOL_BLOCK_VALUE (func))))
{
@@ -1106,6 +1116,7 @@ print_frame (struct frame_info *frame, int print_level,
struct gdbarch *gdbarch = get_frame_arch (frame);
struct ui_out *uiout = current_uiout;
const char *funname = NULL;
+ const char *linkname = NULL;
enum language funlang = language_unknown;
struct ui_file *stb;
struct cleanup *old_chain, *list_chain;
@@ -1119,7 +1130,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);

annotate_frame_begin (print_level ? frame_relative_level (frame) : 0,
gdbarch, pc);
@@ -1150,9 +1161,32 @@ 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 841ad43..1e99a72 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, const 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..93b2ba2
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/display-linkage-name.cc
@@ -0,0 +1,19 @@
+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..aa077c4
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/display-linkage-name.exp
@@ -0,0 +1,153 @@
+# 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 display-linkage-name.exp display-linkage-name display-linkage-name.cc {debug c++}] } {
+ return -1
+}
+set srcfile display-linkage-name.cc
+
+set bp1 [gdb_get_line_number "set breakpoint 1 here"]
+set bp2 [gdb_get_line_number "set breakpoint 2 here"]
+
+#
+# test display-linkage-name commands.
+#
+
+gdb_test "set display-linkage-name off" ""
+
+#
+# set break at functions
+#
+gdb_test "break foo" \
+ "Breakpoint.*at.* file .*$srcfile, line $bp1.*" \
+ "breakpoint function"
+
+gdb_test "break fun_with_a_long_name" \
+ "Breakpoint.*at.* file .*$srcfile, line $bp2.*" \
+ "breakpoint function"
+
+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
+gdb_expect {
+ -re "Breakpoint 2, fun_with_a_long_name (.*) at .*$srcfile:$bp2.*$gdb_prompt $" {
+ pass "run until breakpoint - display off"
+ }
+ -re "$gdb_prompt $" {
+ fail "run until breakpoint - display off"
+ }
+ timeout {
+ fail "run until breakpoint - display off (timeout)"
+ }
+}
+
+gdb_test continue "Continuing\\..*Breakpoint 1, foo (.*) at .*$srcfile:$bp1.*\[\t \]+\\}.*" \
+ "continue until function breakpoint - display off"
+
+set bttable "#0 foo (.*) at.*\[\r\n\]"
+append bttable "#1 \[0-9a-fx\]+ in fun_with_a_long_name (.*) at .*$srcfile:.*\[\r\n\]"
+append bttable "#2 \[0-9a-fx\]+ in goo (.*) at .*$srcfile:.*\[\r\n\]"
+append bttable "#3 \[0-9a-fx\]+ in main (.*) at .*$srcfile:.*"
+
+gdb_test "backtrace" $bttable "backtrace - display off"
+
+########################
+# Test with display-linkage-name on
+
+gdb_test "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
+gdb_expect {
+ -re "Breakpoint 2, fun_with_a_long_name \\\[_Z20fun_with_a_long_\.\.\.\\\] (.*) at .*$srcfile:$bp2.*$gdb_prompt $" {
+ pass "run until function breakpoint - display on"
+ }
+ -re "$gdb_prompt $" {
+ fail "run until function breakpoint - display on"
+ }
+ timeout {
+ fail "run until function breakpoint (timeout) - display on"
+ }
+}
+
+gdb_test continue "Continuing\\..*Breakpoint 1, foo \\\[_Z3fooPKc\\\] (.*) at .*$srcfile:$bp1.*\[\t \]+\\}.*" \
+ "continue until function breakpoint - display on"
+
+set bttable "#0 foo \\\[_Z3fooPKc\\\] (.*) at.*\[\r\n\]"
+append bttable "#1 \[0-9a-fx\]+ in fun_with_a_long_name \\\[_Z20fun_with_a_long_\.\.\.\\\] (.*) at .*$srcfile:.*\[\r\n\]"
+append bttable "#2 \[0-9a-fx\]+ in goo \\\[_Z3goov\\\] (.*) at .*$srcfile:.*\[\r\n\]"
+append bttable "#3 \[0-9a-fx\]+ 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 name \\(symbol used by linker\\) to be displayed is 20."
+
+gdb_test "set display-linkage-name-len 10" ""
+
+gdb_test "show display-linkage-name-len" \
+ "Length of linkage name \\(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
+gdb_expect {
+ -re "Breakpoint 2, fun_with_a_long_name \\\[_Z20fun_wi\.\.\.\\\] (.*) at .*$srcfile:$bp2.*$gdb_prompt $" {
+ pass "run until function breakpoint - display 10"
+ }
+ -re "$gdb_prompt $" {
+ fail "run until function breakpoint - display 10"
+ }
+ timeout {
+ fail "run until function breakpoint (timeout) - display 10"
+ }
+}
+
+gdb_test continue "Continuing\\..*Breakpoint 1, foo \\\[_Z3fooPKc\\\] (.*) at .*$srcfile:$bp1.*\[\t \]+\\}.*" \
+ "continue until function breakpoint - display 10"
+
+set bttable "#0 foo \\\[_Z3fooPKc\\\] (.*) at.*\[\r\n\]"
+append bttable "#1 \[0-9a-fx\]+ in fun_with_a_long_name \\\[_Z20fun_wi\.\.\.\\\] (.*) at .*$srcfile:.*\[\r\n\]"
+append bttable "#2 \[0-9a-fx\]+ in goo \\\[_Z3goov\\\] (.*) at .*$srcfile:.*\[\r\n\]"
+append bttable "#3 \[0-9a-fx\]+ in main (.*) at .*$srcfile:.*"
+
+gdb_test "backtrace" $bttable "backtrace - display 10"
+
diff --git a/gdb/top.c b/gdb/top.c
index 480b67e..fb65ecc 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -298,6 +298,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 = 1; /* Default is yes. */
+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) for 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 name (symbol used by linker) to be displayed is %s.\n"),
+ value);
+}
\f
/* 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
@@ -1813,7 +1836,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 44aefb1..bb75189 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 char gdbinit[];