From mboxrd@z Thu Jan 1 00:00:00 1970 From: Tom Tromey To: gdb-patches@sources.redhat.com Subject: Patch: search `directory' path for `break' files Date: Fri, 28 Sep 2001 16:45:00 -0000 Message-id: <87r8sq6fa9.fsf@creche.redhat.com> X-SW-Source: 2001-09/msg00445.html This patch is a follow-on to this discussion: http://sources.redhat.com/ml/gdb/2001-09/msg00052.html What I've done here is change lookup_symtab and lookup_partial_symtab to try to use the full path when looking up a file name. This only works on systems with realpath(); it could probably be ported to other systems (or a portable realpath() implementation could be found). With this patch, if the file name argument to lookup_symtab is a full path, we run it through realpath. Then we search for each symtab's file using the `dir' list. If we find a match, we use it. With this patch, my example: (gdb) break /home/tromey/gnu/egcs/mauve/mauve/gnu/testlet/java/text/DateFormat/Test.java:83 works just fine. I removed some dead code from symtab.c. I also had to add a new field to struct partial_symtab. I don't know if that is acceptable or not. I built and tested this on x86 Red Hat Linux 6.2. I ran make check against the cvs head and then again with this patch applied. There were no differences. I also tested this patch by running it against my Mauve test case and less formally when debugging other gdb patches I worked on today. Is this ok to check in? Tom Index: ChangeLog from Tom Tromey * configure, config.in: Rebuilt. * configure.in: Check for realpath. * defs.h (gdb_realpath): Declare. * symtab.h (partial_symtab): Added fullname field. * source.c (openp): Use gdb_realpath. (forget_cached_source_info): Clear full name of each partial symtab. * utils.c (gdb_realpath): New function. * symtab.c (lookup_symtab): Removed. (lookup_symtab_1): Renamed to lookup_symtab. (lookup_symtab): Look for real path. (lookup_partial_symtab): Likewise. Index: config.in =================================================================== RCS file: /cvs/src/src/gdb/config.in,v retrieving revision 1.30 diff -u -r1.30 config.in --- config.in 2001/08/27 22:39:55 1.30 +++ config.in 2001/09/28 20:36:10 @@ -220,6 +220,9 @@ /* Define if you have the putenv function. */ #undef HAVE_PUTENV +/* Define if you have the realpath function. */ +#undef HAVE_REALPATH + /* Define if you have the sbrk function. */ #undef HAVE_SBRK Index: configure =================================================================== RCS file: /cvs/src/src/gdb/configure,v retrieving revision 1.70 diff -u -r1.70 configure --- configure 2001/09/06 20:59:18 1.70 +++ configure 2001/09/28 20:36:15 @@ -3582,7 +3582,7 @@ fi -for ac_func in bcopy btowc bzero isascii poll sbrk setpgid setpgrp \ +for ac_func in bcopy btowc bzero isascii poll realpath sbrk setpgid setpgrp \ sigaction sigprocmask sigsetmask do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 @@ -8924,7 +8924,7 @@ # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. -ac_max_sed_cmds=60 # Maximum number of lines to put in a sed script. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. ac_file=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_cmds # Line after last line for current file. Index: configure.in =================================================================== RCS file: /cvs/src/src/gdb/configure.in,v retrieving revision 1.72 diff -u -r1.72 configure.in --- configure.in 2001/09/06 20:59:18 1.72 +++ configure.in 2001/09/28 20:36:16 @@ -131,7 +131,7 @@ AC_C_CONST -AC_CHECK_FUNCS(bcopy btowc bzero isascii poll sbrk setpgid setpgrp \ +AC_CHECK_FUNCS(bcopy btowc bzero isascii poll realpath sbrk setpgid setpgrp \ sigaction sigprocmask sigsetmask) AC_FUNC_ALLOCA AC_FUNC_VFORK Index: defs.h =================================================================== RCS file: /cvs/src/src/gdb/defs.h,v retrieving revision 1.63 diff -u -r1.63 defs.h --- defs.h 2001/09/07 21:33:08 1.63 +++ defs.h 2001/09/28 20:36:18 @@ -579,6 +579,8 @@ extern CORE_ADDR host_pointer_to_address (void *ptr); extern void *address_to_host_pointer (CORE_ADDR addr); +extern char *gdb_realpath (const char *); + /* From demangle.c */ extern void set_demangling_style (char *); Index: source.c =================================================================== RCS file: /cvs/src/src/gdb/source.c,v retrieving revision 1.20 diff -u -r1.20 source.c --- source.c 2001/07/17 06:41:47 1.20 +++ source.c 2001/09/28 20:36:35 @@ -234,6 +234,7 @@ { register struct symtab *s; register struct objfile *objfile; + struct partial_symtab *pst; for (objfile = object_files; objfile != NULL; objfile = objfile->next) { @@ -250,6 +251,15 @@ s->fullname = NULL; } } + + ALL_OBJFILE_PSYMTABS (objfile, pst) + { + if (pst->fullname != NULL) + { + xfree (pst->fullname); + pst->fullname = NULL; + } + } } } @@ -603,15 +613,17 @@ if (fd < 0) *filename_opened = NULL; else if (IS_ABSOLUTE_PATH (filename)) - *filename_opened = savestring (filename, strlen (filename)); + *filename_opened = gdb_realpath (filename); else { /* Beware the // my son, the Emacs barfs, the botch that catch... */ - *filename_opened = concat (current_directory, + char *f = concat (current_directory, IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1]) ? "" : SLASH_STRING, filename, NULL); + *filename_opened = gdb_realpath (f); + xfree (f); } } /* OBSOLETE #ifdef MPW */ Index: symtab.c =================================================================== RCS file: /cvs/src/src/gdb/symtab.c,v retrieving revision 1.42 diff -u -r1.42 symtab.c --- symtab.c 2001/07/07 17:19:50 1.42 +++ symtab.c 2001/09/28 20:36:37 @@ -79,8 +79,6 @@ const char *, int, namespace_enum); -static struct symtab *lookup_symtab_1 (const char *); - static struct symbol *lookup_symbol_aux (const char *name, const struct block *block, const namespace_enum namespace, int @@ -137,20 +135,39 @@ psymtabs. *If* there is no '/' in the name, a match after a '/' in the symtab filename will also work. */ -static struct symtab * -lookup_symtab_1 (const char *name) +struct symtab * +lookup_symtab (const char *name) { register struct symtab *s; register struct partial_symtab *ps; register struct objfile *objfile; + char *real_path = NULL; + + if (IS_ABSOLUTE_PATH (name)) + real_path = gdb_realpath (name); got_symtab: /* First, search for an exact match */ ALL_SYMTABS (objfile, s) + { if (FILENAME_CMP (name, s->filename) == 0) return s; + /* If the user gave us an absolute path, try to find the file in + this symtab and use its absolute path. */ + if (real_path != NULL) + { + char *rp = symtab_to_filename (s); + if (FILENAME_CMP (real_path, rp) == 0) + { + xfree (real_path); + return s; + } + } + } + + xfree (real_path); /* Now, search for a matching tail (only if name doesn't have any dirs) */ @@ -188,42 +205,6 @@ goto got_symtab; } -/* Lookup the symbol table of a source file named NAME. Try a couple - of variations if the first lookup doesn't work. */ - -struct symtab * -lookup_symtab (const char *name) -{ - register struct symtab *s; -#if 0 - register char *copy; -#endif - - s = lookup_symtab_1 (name); - if (s) - return s; - -#if 0 - /* This screws c-exp.y:yylex if there is both a type "tree" and a symtab - "tree.c". */ - - /* If name not found as specified, see if adding ".c" helps. */ - /* Why is this? Is it just a user convenience? (If so, it's pretty - questionable in the presence of C++, FORTRAN, etc.). It's not in - the GDB manual. */ - - copy = (char *) alloca (strlen (name) + 3); - strcpy (copy, name); - strcat (copy, ".c"); - s = lookup_symtab_1 (copy); - if (s) - return s; -#endif /* 0 */ - - /* We didn't find anything; die. */ - return 0; -} - /* Lookup the partial symbol table of a source file named NAME. *If* there is no '/' in the name, a match after a '/' in the psymtab filename will also work. */ @@ -233,6 +214,10 @@ { register struct partial_symtab *pst; register struct objfile *objfile; + char *real_path = NULL; + + if (IS_ABSOLUTE_PATH (name)) + real_path = gdb_realpath (name); ALL_PSYMTABS (objfile, pst) { @@ -240,7 +225,22 @@ { return (pst); } + /* If the user gave us an absolute path, try to find the file in + this symtab and use its absolute path. */ + if (real_path != NULL) + { + if (pst->fullname == NULL) + source_full_path_of (pst->filename, &pst->fullname); + if (pst->fullname != NULL + && FILENAME_CMP (real_path, pst->fullname) == 0) + { + xfree (real_path); + return pst; + } + } } + + xfree (real_path); /* Now, search for a matching tail (only if name doesn't have any dirs) */ Index: symtab.h =================================================================== RCS file: /cvs/src/src/gdb/symtab.h,v retrieving revision 1.24 diff -u -r1.24 symtab.h --- symtab.h 2001/07/07 17:19:50 1.24 +++ symtab.h 2001/09/28 20:36:39 @@ -959,6 +959,10 @@ char *filename; + /* Full path of the source file. NULL if not known. */ + + char *fullname; + /* Information about the object file from which symbols should be read. */ struct objfile *objfile; Index: utils.c =================================================================== RCS file: /cvs/src/src/gdb/utils.c,v retrieving revision 1.47 diff -u -r1.47 utils.c --- utils.c 2001/08/01 18:39:23 1.47 +++ utils.c 2001/09/28 20:36:43 @@ -2490,3 +2490,15 @@ ADDRESS_TO_POINTER (builtin_type_void_data_ptr, &ptr, addr); return ptr; } + +char * +gdb_realpath (const char *filename) +{ +#ifdef HAVE_REALPATH + char buf[PATH_MAX]; + char *rp = realpath (filename, buf); + return xstrdup (rp ? rp : filename); +#else + return xstrdup (filename); +#endif +}