[RFC] new substitute path when loading feature

Aleksandar Ristovski
2008-05-13T18:07:45Z

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

Hello,

For us who deal with mixed-platform development environment it is common to debug binaries built on a different machine, often different OS. A real-life example:

development environment (sdk) is setup on a win32 machine, with headers and all. When compiled, binaries are being debugged on a linux-hosted gdb. Linux machine has the same development environment (sdk) only in different root directories. Where win32 may have C:/foo, linux will have /opt/foo, etc...

To properly translate the paths it is useful to be able to tell gdb to translate such paths into new environment. Existing "substitute-path" functionality seems like the most logical choice, and the diff exploits this to add new feature - rewriting source paths at readin time.

The difference can be observed if a binary built on a win32 system is loaded in gdb on linux. For example
(gdb) maint info symtabs
....
{ symtab C:/QNX632/target/qnx6/usr/include/sys/compiler_gnu.h
((struct symtab *) 0x8390808)
dirname c:/Temp/dirs/debug
fullname (null)
blockvector ((struct blockvector *) 0x8392f24)
linetable ((struct linetable *) (nil))
debugformat unknown
}
{ symtab ../main.c ((struct symtab *) 0x83907b0)
dirname c:/Temp/dirs/debug
fullname (null)
blockvector ((struct blockvector *) 0x8392f24) (primary)
linetable ((struct linetable *) 0x8392f9c)
debugformat DWARF 2
}
...
while with the patch:
(gdb) set substitute-path-at-source 1
(gdb) set substitute-path C:/QNX632 /opt/qnx632
(gdb) set substitute-path c:/Temp /tmp
(gdb) symbol-file /tmp/dirs/debug/main
Load new symbol table from "/tmp/dirs/debug/main"? (y or n) y
Reading symbols from /tmp/dirs/debug/main...done.
(gdb) maint info symtabs
....
{ symtab /opt/qnx632/target/qnx6/usr/include/sys/compiler_gnu.h
((struct symtab *) 0x8379c10)
dirname /tmp/dirs/debug
fullname (null)
blockvector ((struct blockvector *) 0x837c32c)
linetable ((struct linetable *) (nil))
debugformat unknown
}
{ symtab ../main.c ((struct symtab *) 0x8379bb8)
dirname /tmp/dirs/debug
fullname (null)
blockvector ((struct blockvector *) 0x837c32c) (primary)
linetable ((struct linetable *) 0x837c390)
debugformat DWARF 2
}
...

Thanks,

Aleksandar Ristovski
QNX Software Systems

ChangeLog:

2008-05-13 Aleksandar Ristovski <aristovski@qnx.com>

* Makefile.in (buildsym.o): Add new dependency.
* buildsym.c (source.h): New include.
(start_subfile): Rewrite path is substitute-path-at-source is set.
* source.c (substitute_pat_at_source): New variable.
(rewrite_source_path): Make external.
(_initialize_source): Add new set/show variable
'substitute-path-at-source'.
* source.h (rewrite_source_path substitute_pat_at_source): New
declarations.
* symfile.c (start_psymtab_common): Rewrite file name if
substitute-path-at-source is set.

[-- Attachment #2: substitute-path-at-source.diff --]
[-- Type: text/plain, Size: 6248 bytes --]

Index: gdb/Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.1018
diff -u -p -r1.1018 Makefile.in
--- gdb/Makefile.in 9 May 2008 17:02:01 -0000 1.1018
+++ gdb/Makefile.in 13 May 2008 17:59:11 -0000
@@ -1998,7 +1998,7 @@ buildsym.o: buildsym.c $(defs_h) $(bfd_h
$(complaints_h) $(gdb_string_h) $(expression_h) $(bcache_h) \
$(filenames_h) $(macrotab_h) $(demangle_h) $(block_h) \
$(cp_support_h) $(dictionary_h) $(buildsym_h) $(stabsread_h) \
- $(addrmap_h)
+ $(addrmap_h) $(source_h)
c-exp.o: c-exp.c $(defs_h) $(gdb_string_h) $(expression_h) $(value_h) \
$(parser_defs_h) $(language_h) $(c_lang_h) $(bfd_h) $(symfile_h) \
$(objfiles_h) $(charset_h) $(block_h) $(cp_support_h) $(dfp_h)
Index: gdb/buildsym.c
===================================================================
RCS file: /cvs/src/src/gdb/buildsym.c,v
retrieving revision 1.60
diff -u -p -r1.60 buildsym.c
--- gdb/buildsym.c 17 Apr 2008 17:54:04 -0000 1.60
+++ gdb/buildsym.c 13 May 2008 17:59:11 -0000
@@ -44,6 +44,7 @@
#include "cp-support.h"
#include "dictionary.h"
#include "addrmap.h"
+#include "source.h"

/* Ask buildsym.h to define the vars it normally declares `extern'. */
#define EXTERN
@@ -583,6 +584,24 @@ void
start_subfile (char *name, char *dirname)
{
struct subfile *subfile;
+ char *rwname = NULL;
+ char *rwdirname = NULL;
+
+ if (substitute_path_at_source)
+ {
+ rwname = rewrite_source_path (name);
+ rwdirname = rewrite_source_path (dirname);
+ }
+
+ if (rwname == NULL)
+ rwname = name;
+ else
+ make_cleanup (xfree, rwname);
+ if (rwdirname == NULL)
+ rwdirname = dirname;
+ else
+ make_cleanup (xfree, rwdirname);
+

/* See if this subfile is already known as a subfile of the current
main source file. */
@@ -593,7 +612,7 @@ start_subfile (char *name, char *dirname

/* If NAME is an absolute path, and this subfile is not, then
attempt to create an absolute path to compare. */
- if (IS_ABSOLUTE_PATH (name)
+ if (IS_ABSOLUTE_PATH (rwname)
&& !IS_ABSOLUTE_PATH (subfile->name)
&& subfile->dirname != NULL)
subfile_name = concat (subfile->dirname, SLASH_STRING,
@@ -601,7 +620,7 @@ start_subfile (char *name, char *dirname
else
subfile_name = subfile->name;

- if (FILENAME_CMP (subfile_name, name) == 0)
+ if (FILENAME_CMP (subfile_name, rwname) == 0)
{
current_subfile = subfile;
if (subfile_name != subfile->name)
@@ -623,9 +642,10 @@ start_subfile (char *name, char *dirname
current_subfile = subfile;

/* Save its name and compilation directory name */
- subfile->name = (name == NULL) ? NULL : savestring (name, strlen (name));
+ subfile->name =
+ (rwname == NULL) ? NULL : savestring (rwname, strlen (rwname));
subfile->dirname =
- (dirname == NULL) ? NULL : savestring (dirname, strlen (dirname));
+ (rwdirname == NULL) ? NULL : savestring (rwdirname, strlen (rwdirname));

/* Initialize line-number recording for this subfile. */
subfile->line_vector = NULL;
Index: gdb/source.c
===================================================================
RCS file: /cvs/src/src/gdb/source.c,v
retrieving revision 1.88
diff -u -p -r1.88 source.c
--- gdb/source.c 3 May 2008 06:13:21 -0000 1.88
+++ gdb/source.c 13 May 2008 17:59:12 -0000
@@ -91,6 +91,8 @@ static struct symtab *current_source_sym

static int current_source_line;

+int substitute_path_at_source = 0;
+
/* Default number of lines to print with commands like "list".
This is based on guessing how many long (i.e. more than chars_per_line
characters) lines there will be. To be completely correct, "list"
@@ -895,7 +897,7 @@ get_substitute_path_rule (const char *pa
Return NULL if no substitution rule was specified by the user,
or if no rule applied to the given PATH. */

-static char *
+char *
rewrite_source_path (const char *path)
{
const struct substitute_path_rule *rule = get_substitute_path_rule (path);
@@ -2027,4 +2029,12 @@ Usage: show substitute-path [FROM]\n\
Print the rule for substituting FROM in source file names. If FROM\n\
is not specified, print all substitution rules."),
&showlist);
+
+ add_setshow_zinteger_cmd ("substitute-path-at-source", class_files,
+ &substitute_path_at_source, _("\
+Activate path substitution rule at source."), _("\
+Show path substitution rule at source."), _("\
+When set, paths loaded from debug info will be rewritten before\n\
+being used in GDB."),
+ NULL, NULL, &setlist, &showlist);
}
Index: gdb/source.h
===================================================================
RCS file: /cvs/src/src/gdb/source.h,v
retrieving revision 1.9
diff -u -p -r1.9 source.h
--- gdb/source.h 1 Jan 2008 22:53:13 -0000 1.9
+++ gdb/source.h 13 May 2008 17:59:12 -0000
@@ -66,4 +66,9 @@ extern struct symtab_and_line set_curren

/* Reset any information stored about a default file and line to print. */
extern void clear_current_source_symtab_and_line (void);
+
+extern char *rewrite_source_path (const char *path);
+
+extern int substitute_path_at_source;
+
#endif
Index: gdb/symfile.c
===================================================================
RCS file: /cvs/src/src/gdb/symfile.c,v
retrieving revision 1.203
diff -u -p -r1.203 symfile.c
--- gdb/symfile.c 5 May 2008 16:13:49 -0000 1.203
+++ gdb/symfile.c 13 May 2008 17:59:13 -0000
@@ -3072,13 +3072,22 @@ start_psymtab_common (struct objfile *ob
struct partial_symbol **static_syms)
{
struct partial_symtab *psymtab;
+ char *rwfilename = NULL;

- psymtab = allocate_psymtab (filename, objfile);
+ if (substitute_path_at_source)
+ rwfilename = rewrite_source_path (filename);
+
+ if (rwfilename == NULL)
+ rwfilename = filename;
+
+ psymtab = allocate_psymtab (rwfilename, objfile);
psymtab->section_offsets = section_offsets;
psymtab->textlow = textlow;
psymtab->texthigh = psymtab->textlow; /* default */
psymtab->globals_offset = global_syms - objfile->global_psymbols.list;
psymtab->statics_offset = static_syms - objfile->static_psymbols.list;
+ if (rwfilename != filename)
+ xfree (rwfilename);
return (psymtab);
}
\f