From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4835 invoked by alias); 15 May 2008 16:06:27 -0000 Received: (qmail 4771 invoked by uid 22791); 15 May 2008 16:06:15 -0000 X-Spam-Check-By: sourceware.org Received: from NaN.false.org (HELO nan.false.org) (208.75.86.248) by sourceware.org (qpsmtpd/0.31) with ESMTP; Thu, 15 May 2008 16:05:55 +0000 Received: from nan.false.org (localhost [127.0.0.1]) by nan.false.org (Postfix) with ESMTP id 80A0B983D6; Thu, 15 May 2008 16:05:53 +0000 (GMT) Received: from caradoc.them.org (22.svnf5.xdsl.nauticom.net [209.195.183.55]) by nan.false.org (Postfix) with ESMTP id 333E59830E; Thu, 15 May 2008 16:05:53 +0000 (GMT) Received: from drow by caradoc.them.org with local (Exim 4.69) (envelope-from ) id 1Jwfxo-00017g-0b; Thu, 15 May 2008 12:05:52 -0400 Date: Thu, 15 May 2008 17:37:00 -0000 From: Daniel Jacobowitz To: Aleksandar Ristovski , gdb-patches@sources.redhat.com Cc: Eli Zaretskii Subject: Re: [RFC] new substitute path when loading feature Message-ID: <20080515160551.GA24101@caradoc.them.org> Mail-Followup-To: Aleksandar Ristovski , gdb-patches@sources.redhat.com, Eli Zaretskii References: <20080513190818.GA13776@caradoc.them.org> <4829E7DA.3010606@qnx.com> <20080513192041.GA14593@caradoc.them.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20080513192041.GA14593@caradoc.them.org> User-Agent: Mutt/1.5.17 (2008-05-11) X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-05/txt/msg00466.txt.bz2 On Tue, May 13, 2008 at 03:20:41PM -0400, Daniel Jacobowitz wrote: > On Tue, May 13, 2008 at 03:11:22PM -0400, Aleksandar Ristovski wrote: > > No, this particular issue is not because of the slashes, but rather > > due to IS_ABSOLUTE_PATH returning false on a path like "c:/Temp...". > > OK. I think I "fixed" FILENAME_CMP and not IS_ABSOLUTE_PATH, but it > would not be hard to do both. > > I'll try to post something tonight. Sorry, my existing patch was a mess so I had to rewrite it. I haven't really tested this; it doesn't break a native Linux GDB in any case that I consider significant. See the comments in defs.h and utils.c for the details. Does this fix the same problem you're working on? Does anyone see a problem with the compromises I made here? Eli, I'd appreciate your opinion. -- Daniel Jacobowitz CodeSourcery 2008-05-15 Daniel Jacobowitz * defs.h (GDB_IS_DIR_SEPARATOR, GDB_IS_ABSOLUTE_PATH) (GDB_FILENAME_CMP): New macros. (gdb_filename_cmp): Declare. * buildsym.c, dwarf2read.c, solib.c, source.c, symtab.c: Use the new macros. * utils.c (ldirname): Likewise. (gdb_filename_cmp): New function. Index: buildsym.c =================================================================== RCS file: /cvs/src/src/gdb/buildsym.c,v retrieving revision 1.60 diff -u -p -r1.60 buildsym.c --- buildsym.c 17 Apr 2008 17:54:04 -0000 1.60 +++ buildsym.c 15 May 2008 15:41:01 -0000 @@ -593,15 +593,15 @@ 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) - && !IS_ABSOLUTE_PATH (subfile->name) + if (GDB_IS_ABSOLUTE_PATH (name) + && !GDB_IS_ABSOLUTE_PATH (subfile->name) && subfile->dirname != NULL) subfile_name = concat (subfile->dirname, SLASH_STRING, subfile->name, NULL); else subfile_name = subfile->name; - if (FILENAME_CMP (subfile_name, name) == 0) + if (GDB_FILENAME_CMP (subfile_name, name) == 0) { current_subfile = subfile; if (subfile_name != subfile->name) Index: defs.h =================================================================== RCS file: /cvs/src/src/gdb/defs.h,v retrieving revision 1.223 diff -u -p -r1.223 defs.h --- defs.h 3 May 2008 22:20:13 -0000 1.223 +++ defs.h 15 May 2008 15:41:02 -0000 @@ -374,6 +374,24 @@ ULONGEST strtoulst (const char *num, con char *ldirname (const char *filename); +/* Versions of the filenames.h macros to use with filenames from debug + information, when the program may have been compiled on a DOS + filesystem even if GDB is running on a POSIX host. */ + +/* Recognizing backslashes as directory separators has a low false + positive rate, because POSIX filenames rarely include them. They + are likely to appear in full paths in debug information. */ +#define GDB_IS_DIR_SEPARATOR(c) ((c) == '/' || (c) == '\\') + +/* Recognizing drive letters as absolute path prefixes has a low false + positive rate, because POSIX directories are rarely named "c:". We + must not prepend a directory prefix to drive letters. */ +#define GDB_IS_ABSOLUTE_PATH(f) \ + (GDB_IS_DIR_SEPARATOR ((f)[0]) || (((f)[0]) && ((f)[1] == ':'))) + +#define GDB_FILENAME_CMP(lhs, rhs) gdb_filename_cmp (lhs, rhs) +int gdb_filename_cmp (const char *lhs, const char *rhs); + /* From demangle.c */ extern void set_demangling_style (char *); Index: dwarf2read.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2read.c,v retrieving revision 1.263 diff -u -p -r1.263 dwarf2read.c --- dwarf2read.c 5 May 2008 14:37:32 -0000 1.263 +++ dwarf2read.c 15 May 2008 15:41:02 -0000 @@ -2832,7 +2832,7 @@ read_file_scope (struct die_info *die, s attr = dwarf2_attr (die, DW_AT_comp_dir, cu); if (attr) comp_dir = DW_STRING (attr); - else if (name != NULL && IS_ABSOLUTE_PATH (name)) + else if (name != NULL && GDB_IS_ABSOLUTE_PATH (name)) { comp_dir = ldirname (name); if (comp_dir != NULL) @@ -7186,14 +7186,14 @@ dwarf_decode_lines (struct line_header * if (fe.dir_index) dir_name = lh->include_dirs[fe.dir_index - 1]; - if (!IS_ABSOLUTE_PATH (include_name) && dir_name != NULL) + if (!GDB_IS_ABSOLUTE_PATH (include_name) && dir_name != NULL) { include_name = concat (dir_name, SLASH_STRING, include_name, (char *)NULL); make_cleanup (xfree, include_name); } - if (!IS_ABSOLUTE_PATH (pst_filename) && pst->dirname != NULL) + if (!GDB_IS_ABSOLUTE_PATH (pst_filename) && pst->dirname != NULL) { pst_filename = concat (pst->dirname, SLASH_STRING, pst_filename, (char *)NULL); @@ -7274,7 +7274,7 @@ dwarf2_start_subfile (char *filename, ch that represent full path names''. Thus ignoring dirname in the `else' branch below isn't an issue. */ - if (!IS_ABSOLUTE_PATH (filename) && dirname != NULL) + if (!GDB_IS_ABSOLUTE_PATH (filename) && dirname != NULL) fullname = concat (dirname, SLASH_STRING, filename, (char *)NULL); else fullname = filename; @@ -9502,7 +9502,7 @@ file_full_name (int file, struct line_he { struct file_entry *fe = &lh->file_names[file - 1]; - if (IS_ABSOLUTE_PATH (fe->name)) + if (GDB_IS_ABSOLUTE_PATH (fe->name)) return xstrdup (fe->name); else { Index: solib.c =================================================================== RCS file: /cvs/src/src/gdb/solib.c,v retrieving revision 1.101 diff -u -p -r1.101 solib.c --- solib.c 7 Jan 2008 15:19:58 -0000 1.101 +++ solib.c 15 May 2008 15:41:02 -0000 @@ -150,7 +150,7 @@ solib_open (char *in_pathname, char **fo gdb_sysroot_is_empty = (gdb_sysroot == NULL || *gdb_sysroot == 0); - if (! IS_ABSOLUTE_PATH (in_pathname) || gdb_sysroot_is_empty) + if (! GDB_IS_ABSOLUTE_PATH (in_pathname) || gdb_sysroot_is_empty) temp_pathname = in_pathname; else { @@ -186,14 +186,14 @@ solib_open (char *in_pathname, char **fo absolute at this point, make it relative. (openp will try and open the file according to its absolute path otherwise, which is not what we want.) Affects subsequent searches for this solib. */ - if (found_file < 0 && IS_ABSOLUTE_PATH (in_pathname)) + if (found_file < 0 && GDB_IS_ABSOLUTE_PATH (in_pathname)) { /* First, get rid of any drive letters etc. */ - while (!IS_DIR_SEPARATOR (*in_pathname)) + while (!GDB_IS_DIR_SEPARATOR (*in_pathname)) in_pathname++; /* Next, get rid of all leading dir separators. */ - while (IS_DIR_SEPARATOR (*in_pathname)) + while (GDB_IS_DIR_SEPARATOR (*in_pathname)) in_pathname++; } Index: source.c =================================================================== RCS file: /cvs/src/src/gdb/source.c,v retrieving revision 1.88 diff -u -p -r1.88 source.c --- source.c 3 May 2008 06:13:21 -0000 1.88 +++ source.c 15 May 2008 15:41:03 -0000 @@ -700,7 +700,7 @@ openp (const char *path, int opts, const mode |= O_BINARY; - if ((opts & OPF_TRY_CWD_FIRST) || IS_ABSOLUTE_PATH (string)) + if ((opts & OPF_TRY_CWD_FIRST) || GDB_IS_ABSOLUTE_PATH (string)) { int i; @@ -720,16 +720,16 @@ openp (const char *path, int opts, const if (!(opts & OPF_SEARCH_IN_PATH)) for (i = 0; string[i]; i++) - if (IS_DIR_SEPARATOR (string[i])) + if (GDB_IS_DIR_SEPARATOR (string[i])) goto done; } /* /foo => foo, to avoid multiple slashes that Emacs doesn't like. */ - while (IS_DIR_SEPARATOR(string[0])) + while (GDB_IS_DIR_SEPARATOR(string[0])) string++; /* ./foo => foo */ - while (string[0] == '.' && IS_DIR_SEPARATOR (string[1])) + while (string[0] == '.' && GDB_IS_DIR_SEPARATOR (string[1])) string += 2; alloclen = strlen (path) + strlen (string) + 2; @@ -861,14 +861,14 @@ substitute_path_rule_matches (const stru strncpy (path_start, path, from_len); path_start[from_len] = '\0'; - if (FILENAME_CMP (path_start, rule->from) != 0) + if (GDB_FILENAME_CMP (path_start, rule->from) != 0) return 0; /* Make sure that the region in the path that matches the substitution rule is immediately followed by a directory separator (or the end of string character). */ - if (path[from_len] != '\0' && !IS_DIR_SEPARATOR (path[from_len])) + if (path[from_len] != '\0' && !GDB_IS_DIR_SEPARATOR (path[from_len])) return 0; return 1; @@ -1004,7 +1004,7 @@ find_and_open_source (struct objfile *ob } } - if (IS_ABSOLUTE_PATH (filename)) + if (GDB_IS_ABSOLUTE_PATH (filename)) { /* If filename is absolute path, try the source path substitution on it. */ @@ -1721,7 +1721,7 @@ strip_trailing_directory_separator (char if (last < 0) return; /* No stripping is needed if PATH is the empty string. */ - if (IS_DIR_SEPARATOR (path[last])) + if (GDB_IS_DIR_SEPARATOR (path[last])) path[last] = '\0'; } @@ -1735,7 +1735,7 @@ find_substitute_path_rule (const char *f while (rule != NULL) { - if (FILENAME_CMP (rule->from, from) == 0) + if (GDB_FILENAME_CMP (rule->from, from) == 0) return rule; rule = rule->next; } @@ -1831,7 +1831,7 @@ show_substitute_path_command (char *args while (rule != NULL) { - if (from == NULL || FILENAME_CMP (rule->from, from) == 0) + if (from == NULL || GDB_FILENAME_CMP (rule->from, from) == 0) printf_filtered (" `%s' -> `%s'.\n", rule->from, rule->to); rule = rule->next; } @@ -1871,7 +1871,7 @@ unset_substitute_path_command (char *arg { struct substitute_path_rule *next = rule->next; - if (from == NULL || FILENAME_CMP (from, rule->from) == 0) + if (from == NULL || GDB_FILENAME_CMP (from, rule->from) == 0) { delete_substitute_path_rule (rule); rule_found = 1; Index: symtab.c =================================================================== RCS file: /cvs/src/src/gdb/symtab.c,v retrieving revision 1.181 diff -u -p -r1.181 symtab.c --- symtab.c 5 May 2008 14:37:32 -0000 1.181 +++ symtab.c 15 May 2008 15:41:03 -0000 @@ -187,7 +187,7 @@ got_symtab: ALL_SYMTABS (objfile, s) { - if (FILENAME_CMP (name, s->filename) == 0) + if (GDB_FILENAME_CMP (name, s->filename) == 0) { return s; } @@ -198,7 +198,7 @@ got_symtab: if (full_path != NULL) { const char *fp = symtab_to_fullname (s); - if (fp != NULL && FILENAME_CMP (full_path, fp) == 0) + if (fp != NULL && GDB_FILENAME_CMP (full_path, fp) == 0) { return s; } @@ -211,7 +211,7 @@ got_symtab: { char *rp = gdb_realpath (fullname); make_cleanup (xfree, rp); - if (FILENAME_CMP (real_path, rp) == 0) + if (GDB_FILENAME_CMP (real_path, rp) == 0) { return s; } @@ -224,7 +224,7 @@ got_symtab: if (lbasename (name) == name) ALL_SYMTABS (objfile, s) { - if (FILENAME_CMP (lbasename (s->filename), name) == 0) + if (GDB_FILENAME_CMP (lbasename (s->filename), name) == 0) return s; } @@ -279,7 +279,7 @@ lookup_partial_symtab (const char *name) ALL_PSYMTABS (objfile, pst) { - if (FILENAME_CMP (name, pst->filename) == 0) + if (GDB_FILENAME_CMP (name, pst->filename) == 0) { return (pst); } @@ -290,7 +290,7 @@ lookup_partial_symtab (const char *name) { psymtab_to_fullname (pst); if (pst->fullname != NULL - && FILENAME_CMP (full_path, pst->fullname) == 0) + && GDB_FILENAME_CMP (full_path, pst->fullname) == 0) { return pst; } @@ -305,7 +305,7 @@ lookup_partial_symtab (const char *name) rp = gdb_realpath (pst->fullname); make_cleanup (xfree, rp); } - if (rp != NULL && FILENAME_CMP (real_path, rp) == 0) + if (rp != NULL && GDB_FILENAME_CMP (real_path, rp) == 0) { return pst; } @@ -317,7 +317,7 @@ lookup_partial_symtab (const char *name) if (lbasename (name) == name) ALL_PSYMTABS (objfile, pst) { - if (FILENAME_CMP (lbasename (pst->filename), name) == 0) + if (GDB_FILENAME_CMP (lbasename (pst->filename), name) == 0) return (pst); } Index: utils.c =================================================================== RCS file: /cvs/src/src/gdb/utils.c,v retrieving revision 1.187 diff -u -p -r1.187 utils.c --- utils.c 24 Apr 2008 11:13:44 -0000 1.187 +++ utils.c 15 May 2008 15:41:03 -0000 @@ -3205,7 +3205,7 @@ ldirname (const char *filename) const char *base = lbasename (filename); char *dirname; - while (base > filename && IS_DIR_SEPARATOR (base[-1])) + while (base > filename && GDB_IS_DIR_SEPARATOR (base[-1])) --base; if (base == filename) @@ -3214,12 +3214,43 @@ ldirname (const char *filename) dirname = xmalloc (base - filename + 2); memcpy (dirname, filename, base - filename); - /* On DOS based file systems, convert "d:foo" to "d:.", so that we + /* For DOS based file systems, convert "d:foo" to "d:.", so that we create "d:./bar" later instead of the (different) "d:/bar". */ - if (base - filename == 2 && IS_ABSOLUTE_PATH (base) - && !IS_DIR_SEPARATOR (filename[0])) + if (base - filename == 2 && GDB_IS_ABSOLUTE_PATH (base) + && !GDB_IS_DIR_SEPARATOR (filename[0])) dirname[base++ - filename] = '.'; dirname[base - filename] = '\0'; return dirname; } + +/* Compare two filenames. This version should be used instead of + FILENAME_CMP for filenames from debug information; it recognizes + equivalences from compiling on a DOS filesystem even if the + debugger is running on a POSIX host. */ + +int +gdb_filename_cmp (const char *lhs, const char *rhs) +{ + for (; *lhs || *rhs; lhs++, rhs++) + { +#ifndef HAVE_DOS_BASED_FILE_SYSTEM + /* When debugging on a POSIX host, assume that each filename was + recorded with a single consistent capitalization during + compilation. Source trees are too likely to contain both + main.c and Main.c. */ + if (*lhs == *rhs) + continue; +#else + if (tolower (*lhs) == tolower (*rhs)) + continue; +#endif + + if (*lhs == '/' && *rhs == '\\') + continue; + if (*lhs == '\\' && *rhs == '/') + continue; + return (int) *lhs - (int) *rhs; + } + return 0; +}