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

iam ahal
2011-08-02T19:41:35Z

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

I've created the new patch. Here is example of usage patched gdb:

(gdb) backtrace
#0 main () at /home/eldar/testdir/test.c:4

(gdb) set backtrace filename-display basename
(gdb) backtrace
#0 main () at test.c:4

(gdb) set backtrace filename-display without-compile-dir
(gdb) backtrace
#0 main () at testdir/test.c:4

(gdb) set backtrace filename-display full
(gdb) backtrace
#0 main () at /home/eldar/testdir/test.c:4

I can change something if you want. If this implementation is good I
will prepare ChangeLog and testsuite.

On Thu, Jul 28, 2011 at 7:17 PM, Tom Tromey <tromey@redhat.com> wrote:
> I forget (I never keep records of this, I think perhaps I should) -- did
> we get you started on the copyright assignment paperwork?

Not yet, because my previous patches is very different. I mean the
different files was changed and I don't know which files I need to
change in the next patch.
I hope some people here can accept implementation in this last patch.
After I can start the copyright assignment.

> iam> +static int backtrace_skip_compile;
> iam> +static void
>
> Newline between these two lines.

I'm not sure that's right because I see that there's no newline in
this case (if you look at other places related 'set backtrace ...').

> iam> +char *
> iam> +get_display_filename_from_sal (struct symtab_and_line *sal)
>
> Should have an introductory comment before this function.

Comment was added in 'frame.h'

> Ah, ok -- you are using the absolute file name when compiling.
> That seems weird to me, but I understand now.

Some big build systems uses absolute file name (e.g. Mozilla) because
I started this topic. I wrote about motivation idea in my first
message with patch.

With best regards,
Eldar.

[-- Attachment #2: gdb-7.2-filename-display.patch --]
[-- Type: text/x-patch, Size: 6822 bytes --]

diff -rup gdb-7.2-orig/gdb/frame.c gdb-7.2/gdb/frame.c
--- gdb-7.2-orig/gdb/frame.c 2010-07-01 19:36:15.000000000 +0400
+++ gdb-7.2/gdb/frame.c 2011-08-02 22:44:00.699942001 +0400
@@ -44,6 +44,7 @@
#include "block.h"
#include "inline-frame.h"
#include "tracepoint.h"
+#include "filenames.h"

static struct frame_info *get_prev_frame_1 (struct frame_info *this_frame);
static struct frame_info *get_prev_frame_raw (struct frame_info *this_frame);
@@ -135,6 +136,18 @@ struct frame_info
sufficient for now. */
static struct frame_info *frame_stash = NULL;

+/* Possible values of 'set backtrace filename-display'. */
+static const char filename_display_full[] = "full";
+static const char filename_display_basename[] = "basename";
+static const char filename_display_without_comp_dir[] = "without-compile-dir";
+
+static const char *filename_display_kind_names[] = {
+ filename_display_full,
+ filename_display_basename,
+ filename_display_without_comp_dir,
+ NULL
+};
+
/* Add the following FRAME to the frame stash. */

static void
@@ -205,6 +218,15 @@ An upper bound on the number of backtrac
value);
}

+static const char *filename_display_string = filename_display_full;
+static void
+show_filename_display_string (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("\
+A filename is displayed in backtrace as \"%s\".\n"),
+ value);
+}

static void
fprint_field (struct ui_file *file, const char *name, int p, CORE_ADDR addr)
@@ -1900,6 +1922,34 @@ find_frame_sal (struct frame_info *frame
(*sal) = find_pc_line (get_frame_pc (frame), notcurrent);
}

+const char *
+get_filename_display_from_sal (struct symtab_and_line *sal)
+{
+ const char *filename = sal->symtab->filename;
+ const char *dirname = sal->symtab->dirname;
+ size_t flen = strlen (filename);
+ size_t dlen = strlen (dirname);
+
+ if (filename_display_string == filename_display_basename
+ && filename)
+ {
+ return lbasename (filename);
+ }
+ else
+ if (filename_display_string == filename_display_without_comp_dir
+ && filename && dirname && dlen <= flen
+ && !FILENAME_NCMP (filename, dirname, dlen))
+ {
+ const char *result = filename + strlen (dirname);
+ while (IS_DIR_SEPARATOR (*result))
+ result++;
+
+ return result;
+ }
+
+ return filename;
+}
+
/* Per "frame.h", return the ``address'' of the frame. Code should
really be using get_frame_id(). */
CORE_ADDR
@@ -2270,6 +2320,21 @@ Zero is unlimited."),
&set_backtrace_cmdlist,
&show_backtrace_cmdlist);

+ add_setshow_enum_cmd ("filename-display", class_obscure,
+ filename_display_kind_names,
+ &filename_display_string, _("\
+Set a way how to display filename."), _("\
+Show a way how to display filename."), _("\
+filename-display can be:\n\
+ full - display full filename\n\
+ basename - display only basename of filename\n\
+ without-compile-dir - display filename without compile directory part\n\
+By default, full filename is displayed."),
+ NULL,
+ show_filename_display_string,
+ &set_backtrace_cmdlist,
+ &show_backtrace_cmdlist);
+
/* Debug this files internals. */
add_setshow_zinteger_cmd ("frame", class_maintenance, &frame_debug, _("\
Set frame debugging."), _("\
diff -rup 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-08-02 22:44:00.579942001 +0400
@@ -327,6 +327,12 @@ extern CORE_ADDR get_frame_func (struct
extern void find_frame_sal (struct frame_info *frame,
struct symtab_and_line *sal);

+/* Returns either full filename or basename from filename or filename
+ without compile directory part.
+ It depends on 'set backtrace filename-display' value. */
+
+extern const char *get_filename_display_from_sal (struct symtab_and_line *sal);
+
/* Set the current source and line to the location given by frame
FRAME, if possible. When CENTER is true, adjust so the relevant
line is in the center of the next 'list'. */
diff -rup 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-08-02 22:44:00.729942001 +0400
@@ -810,11 +810,15 @@ print_frame (struct frame_info *frame, i
ui_out_text (uiout, ")");
if (sal.symtab && sal.symtab->filename)
{
+ const char *filename_display = get_filename_display_from_sal (&sal);
+ if (filename_display == NULL)
+ filename_display = sal.symtab->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);
+ ui_out_field_string (uiout, "file", filename_display);
if (ui_out_is_mi_like_p (uiout))
{
const char *fullname = symtab_to_fullname (sal.symtab);
diff -rup gdb-7.2-orig/include/filenames.h gdb-7.2/include/filenames.h
--- gdb-7.2-orig/include/filenames.h 2010-04-26 22:04:23.000000000 +0400
+++ gdb-7.2/include/filenames.h 2011-08-02 22:44:00.499942001 +0400
@@ -71,7 +71,9 @@ extern "C" {
|| HAS_DRIVE_SPEC_1 (dos_based, f))

extern int filename_cmp (const char *s1, const char *s2);
-#define FILENAME_CMP(s1, s2) filename_cmp(s1, s2)
+extern int filename_ncmp (const char *s1, const char *s2, size_t n);
+#define FILENAME_CMP(s1, s2) filename_cmp(s1, s2)
+#define FILENAME_NCMP(s1, s2, n) filename_ncmp(s1, s2, n)

#ifdef __cplusplus
}
diff -rup gdb-7.2-orig/libiberty/filename_cmp.c gdb-7.2/libiberty/filename_cmp.c
--- gdb-7.2-orig/libiberty/filename_cmp.c 2007-05-04 03:40:11.000000000 +0400
+++ gdb-7.2/libiberty/filename_cmp.c 2011-08-02 23:17:57.079942001 +0400
@@ -29,6 +29,48 @@

/*

+@deftypefn Extension int filename_ncmp (const char *@var{s1}, const char *@var{s2}, size_t @var{n})
+
+The function is similar as filename_cmp, except it only compares the
+first (at most) @var{n} characters.
+
+@end deftypefn
+
+*/
+
+int
+filename_ncmp (const char *s1, const char *s2, size_t n)
+{
+#ifndef HAVE_DOS_BASED_FILE_SYSTEM
+ return strncmp (s1, s2, n);
+#else
+ size_t i;
+
+ for (i = 0; i < n; i++)
+ {
+ int c1 = TOLOWER (*s1);
+ int c2 = TOLOWER (*s2);
+
+ /* On DOS-based file systems, the '/' and the '\' are equivalent. */
+ if (c1 == '/')
+ c1 = '\\';
+ if (c2 == '/')
+ c2 = '\\';
+
+ if (c1 != c2)
+ return (c1 - c2);
+
+ if (c1 == '\0')
+ return 0;
+
+ s1++;
+ s2++;
+ }
+#endif
+}
+
+/*
+
@deftypefn Extension int filename_cmp (const char *@var{s1}, const char *@var{s2})

Return zero if the two file names @var{s1} and @var{s2} are equivalent.