[patch] GDB 7.2: new feature for "backtrace" that cuts path to file (remain filename)

iam ahal
2011-06-26T20:00:50Z

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

Some build systems (e.g. mozilla firefox) provides build of source
code with only full path to files (i.e. pass to gcc full path to
file).
Sometimes it's difficult to change build (especially if it's huge
project). If you debug compiled program you may see full path in
backtraces, like this:

(gdb) backtrace
#0 main (argc=4, argv=0xbffff884) at
/media/25b7639d-9a70-42ca-aaa7-28f4d1f417fd/firefox-dev/mozilla-central/browser/app/nsBrowserApp.cpp:204

I'm uncomfortable to read such backtraces.

I've implemented the new feature (patch for gdb-7.2 release from
"02-Sep-2010 20:12"):
New argument for "backtrace" called "nopath". If you run "backtrace
nopath" you will see something like this:

(gdb) backtrace nopath
#0 main (argc=4, argv=0xbffff884) at nsBrowserApp.cpp:204

(instead above result)

"nopath" argument just cuts full path to file and remains only filename.

If you think that this feature is useful for somebody you can see
ChangeLog and patch in attachment.
If it's useful feature but i made some mistakes (e.g. made ugly names)
i will change it if you want.

P.S. Sorry for my poor english.

ChangeLog:

2011-06-26 Eldar Gaynetdinov <hal9000ed2k@gmail.com>:

* stack.c (backtrace_command): Created new variable "nofull_path" for
implementation of "backtrace nopath" command.
It has similar logic as "fulltrace_arg"
for "backtrace full" command.
(backtrace_full_command): nofull_path is just zero (i.e.
it's not used there).
(backtrace_command_stub): just pass new argument
("args->nofull_path") to backtrace_command_1
(backtrace_command_1): if "nofull_path" is enabled (by
"backtrace nopath") then call print_frame_info with LOC_NO_FULLPATH.
(print_frame_info): work with LOC_NO_FULLPATH same as
LOCATION (because it's almost same thing).
(print_frame): if LOC_NO_FULLPATH was passed then cut
fullpath (if exist) and remain only filename.
* frame.h (enum print_what): Added LOC_NO_FULLPATH with comment.

[-- Attachment #2: gdb-7.2-nofull-path.patch --]
[-- Type: text/x-patch, Size: 5462 bytes --]

diff -rup -x configure gdb-7.2-orig/gdb/frame.h gdb-7.2/gdb/frame.h
--- gdb-7.2-orig/gdb/frame.h 2010-01-01 10:31:32.000000000 +0300
+++ gdb-7.2/gdb/frame.h 2011-06-26 21:56:52.000000000 +0400
@@ -582,7 +582,10 @@ enum print_what
/* Print both of the above. */
SRC_AND_LOC,
/* Print location only, but always include the address. */
- LOC_AND_ADDRESS
+ LOC_AND_ADDRESS,
+ /* Print only the location but without the full path to file, *
+ * i.e. print only filename even if full path is defined in symtable. */
+ LOC_NO_FULLPATH
};

/* Allocate zero initialized memory from the frame cache obstack.
diff -rup -x configure gdb-7.2-orig/gdb/stack.c gdb-7.2/gdb/stack.c
--- gdb-7.2-orig/gdb/stack.c 2010-07-01 19:36:17.000000000 +0400
+++ gdb-7.2/gdb/stack.c 2011-06-26 22:36:41.000000000 +0400
@@ -592,7 +592,8 @@ print_frame_info (struct frame_info *fra

location_print = (print_what == LOCATION
|| print_what == LOC_AND_ADDRESS
- || print_what == SRC_AND_LOC);
+ || print_what == SRC_AND_LOC
+ || print_what == LOC_NO_FULLPATH);

if (location_print || !sal.symtab)
print_frame (frame, print_level, print_what, print_args, sal);
@@ -652,7 +653,7 @@ print_frame_info (struct frame_info *fra
do_gdb_disassembly (get_frame_arch (frame), -1, sal.pc, sal.end);
}

- if (print_what != LOCATION)
+ if (print_what != LOCATION || print_what != LOC_NO_FULLPATH)
set_default_breakpoint (1, sal.pspace,
get_frame_pc (frame), sal.symtab, sal.line);

@@ -810,11 +811,24 @@ print_frame (struct frame_info *frame, i
ui_out_text (uiout, ")");
if (sal.symtab && sal.symtab->filename)
{
+ const char *filename;
+
annotate_frame_source_begin ();
ui_out_wrap_hint (uiout, " ");
ui_out_text (uiout, " at ");
annotate_frame_source_file ();
- ui_out_field_string (uiout, "file", sal.symtab->filename);
+
+ filename = NULL;
+ if (print_what == LOC_NO_FULLPATH)
+ {
+ filename = strrchr( sal.symtab->filename, '/' );
+ if (filename != NULL)
+ filename++;
+ }
+ if (filename == NULL || *filename == '\0')
+ filename = sal.symtab->filename;
+
+ ui_out_field_string (uiout, "file", filename);
if (ui_out_is_mi_like_p (uiout))
{
const char *fullname = symtab_to_fullname (sal.symtab);
@@ -1269,7 +1283,7 @@ frame_info (char *addr_exp, int from_tty
frames. */

static void
-backtrace_command_1 (char *count_exp, int show_locals, int from_tty)
+backtrace_command_1 (char *count_exp, int show_locals, int from_tty, int nofull_path)
{
struct frame_info *fi;
int count;
@@ -1345,7 +1359,11 @@ backtrace_command_1 (char *count_exp, in
means further attempts to backtrace would fail (on the other
hand, perhaps the code does or could be fixed to make sure
the frame->prev field gets set to NULL in that case). */
- print_frame_info (fi, 1, LOCATION, 1);
+ if (nofull_path)
+ print_frame_info (fi, 1, LOC_NO_FULLPATH, 1);
+ else
+ print_frame_info (fi, 1, LOCATION, 1);
+
if (show_locals)
print_frame_local_vars (fi, 1, gdb_stdout);

@@ -1375,6 +1393,7 @@ struct backtrace_command_args
char *count_exp;
int show_locals;
int from_tty;
+ int nofull_path;
};

/* Stub for catch_errors. */
@@ -1384,7 +1403,7 @@ backtrace_command_stub (void *data)
{
struct backtrace_command_args *args = data;

- backtrace_command_1 (args->count_exp, args->show_locals, args->from_tty);
+ backtrace_command_1 (args->count_exp, args->show_locals, args->from_tty, args->nofull_path);
return 0;
}

@@ -1392,7 +1411,7 @@ static void
backtrace_command (char *arg, int from_tty)
{
struct cleanup *old_chain = NULL;
- int fulltrace_arg = -1, arglen = 0, argc = 0;
+ int fulltrace_arg = -1, arglen = 0, argc = 0, nofull_path = -1;
struct backtrace_command_args btargs;

if (arg)
@@ -1412,6 +1431,8 @@ backtrace_command (char *arg, int from_t

if (fulltrace_arg < 0 && subset_compare (argv[i], "full"))
fulltrace_arg = argc;
+ else if (nofull_path < 0 && subset_compare (argv[i], "nopath"))
+ nofull_path = argc;
else
{
arglen += strlen (argv[i]);
@@ -1419,7 +1440,7 @@ backtrace_command (char *arg, int from_t
}
}
arglen += argc;
- if (fulltrace_arg >= 0)
+ if (fulltrace_arg >= 0 || nofull_path >= 0)
{
if (arglen > 0)
{
@@ -1427,7 +1448,7 @@ backtrace_command (char *arg, int from_t
memset (arg, 0, arglen + 1);
for (i = 0; i < (argc + 1); i++)
{
- if (i != fulltrace_arg)
+ if (i != fulltrace_arg && i != nofull_path)
{
strcat (arg, argv[i]);
strcat (arg, " ");
@@ -1442,9 +1463,10 @@ backtrace_command (char *arg, int from_t
btargs.count_exp = arg;
btargs.show_locals = (fulltrace_arg >= 0);
btargs.from_tty = from_tty;
+ btargs.nofull_path = (nofull_path >= 0);
catch_errors (backtrace_command_stub, &btargs, "", RETURN_MASK_ERROR);

- if (fulltrace_arg >= 0 && arglen > 0)
+ if ((fulltrace_arg >= 0 || nofull_path >= 0) && arglen > 0)
xfree (arg);

if (old_chain)
@@ -1459,6 +1481,7 @@ backtrace_full_command (char *arg, int f
btargs.count_exp = arg;
btargs.show_locals = 1;
btargs.from_tty = from_tty;
+ btargs.nofull_path = 0;
catch_errors (backtrace_command_stub, &btargs, "", RETURN_MASK_ERROR);
}
\f