From patchwork Sat Feb 10 01:42:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergio Durigan Junior X-Patchwork-Id: 25896 Received: (qmail 124580 invoked by alias); 10 Feb 2018 01:42:58 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 124415 invoked by uid 89); 10 Feb 2018 01:42:57 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.3 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_LOW, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=doubling X-HELO: mx1.redhat.com Received: from mx3-rdu2.redhat.com (HELO mx1.redhat.com) (66.187.233.73) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 10 Feb 2018 01:42:54 +0000 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9F5E640FB630; Sat, 10 Feb 2018 01:42:52 +0000 (UTC) Received: from psique.yyz.redhat.com (unused-10-15-17-196.yyz.redhat.com [10.15.17.196]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5C4BA2026DFD; Sat, 10 Feb 2018 01:42:52 +0000 (UTC) From: Sergio Durigan Junior To: GDB Patches Cc: Simon Marchi , Sergio Durigan Junior Subject: [PATCH 1/2] Create new common/pathstuff.[ch] Date: Fri, 9 Feb 2018 20:42:40 -0500 Message-Id: <20180210014241.19278-2-sergiodj@redhat.com> In-Reply-To: <20180210014241.19278-1-sergiodj@redhat.com> References: <20180210014241.19278-1-sergiodj@redhat.com> X-IsSubscribed: yes This commit moves the path manipulation routines found on utils.c to a new common/pathstuff.c, and updates the Makefile.in's accordingly. The routines moved are "gdb_realpath", "gdb_realpath_keepfile" and "gdb_abspath". This will be needed because gdbserver will have to call "gdb_abspath" on my next patch, which implements a way to expand the path of the inferior provided by the user in order to allow specifying just the binary name when starting gdbserver, like: $ gdbserver :1234 a.out With the recent addition of the startup-with-shell feature on gdbserver, this scenario doesn't work anymore if the user doesn't have the current directory listed in the PATH variable. I had to do a minor adjustment on "gdb_abspath" because we don't have access to "tilde_expand" on gdbserver, so now the function is using "gdb_tilde_expand" instead. Otherwise, the code is the same. Regression tested on the BuildBot, without regressions. gdb/ChangeLog: 2018-02-09 Sergio Durigan Junior * Makefile.in (SFILES): Add "common/pathstuff.c". (HFILES_NO_SRCDIR): Add "common/pathstuff.h". (COMMON_OBS): Add "pathstuff.o". * common/pathstuff.c: New file. * common/pathstuff.h: New file. * utils.c (gdb_realpath): Move to "common/pathstuff.c". (gdb_realpath_keepfile): Likewise. (gdb_abspath): Likewise. * utils.h: Include "common/pathstuff.h". (gdb_realpath): Move to "common/pathstuff.h". (gdb_realpath_keepfile): Likewise. (gdb_abspath): Likewise. gdb/gdbserver/ChangeLog: 2018-02-09 Sergio Durigan Junior * Makefile.in (SFILES): Add "$(srcdir)/common/pathstuff.c". (OBJS): Add "pathstuff.o". --- gdb/Makefile.in | 3 + gdb/common/pathstuff.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++ gdb/common/pathstuff.h | 39 +++++++++++++ gdb/gdbserver/Makefile.in | 2 + gdb/utils.c | 119 -------------------------------------- gdb/utils.h | 7 +-- 6 files changed, 189 insertions(+), 125 deletions(-) create mode 100644 gdb/common/pathstuff.c create mode 100644 gdb/common/pathstuff.h diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 957654c9bd..64c9df3eaf 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -1136,6 +1136,7 @@ SFILES = \ common/gdb_tilde_expand.c \ common/gdb_vecs.c \ common/new-op.c \ + common/pathstuff.c \ common/print-utils.c \ common/ptid.c \ common/rsp-low.c \ @@ -1427,6 +1428,7 @@ HFILES_NO_SRCDIR = \ common/gdb_wait.h \ common/common-inferior.h \ common/host-defs.h \ + common/pathstuff.h \ common/print-utils.h \ common/ptid.h \ common/queue.h \ @@ -1552,6 +1554,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \ gdb_vecs.o \ mi/mi-common.o \ new-op.o \ + pathstuff.o \ print-utils.o \ ptid.o \ rsp-low.o \ diff --git a/gdb/common/pathstuff.c b/gdb/common/pathstuff.c new file mode 100644 index 0000000000..42af3fa65a --- /dev/null +++ b/gdb/common/pathstuff.c @@ -0,0 +1,144 @@ +/* Path manipulation routines for GDB and gdbserver. + + Copyright (C) 1986-2018 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "common-defs.h" +#include "pathstuff.h" +#include "host-defs.h" +#include "filenames.h" +#include "gdb_tilde_expand.h" + +gdb::unique_xmalloc_ptr +gdb_realpath (const char *filename) +{ +/* On most hosts, we rely on canonicalize_file_name to compute + the FILENAME's realpath. + + But the situation is slightly more complex on Windows, due to some + versions of GCC which were reported to generate paths where + backlashes (the directory separator) were doubled. For instance: + c:\\some\\double\\slashes\\dir + ... instead of ... + c:\some\double\slashes\dir + Those double-slashes were getting in the way when comparing paths, + for instance when trying to insert a breakpoint as follow: + (gdb) b c:/some/double/slashes/dir/foo.c:4 + No source file named c:/some/double/slashes/dir/foo.c:4. + (gdb) b c:\some\double\slashes\dir\foo.c:4 + No source file named c:\some\double\slashes\dir\foo.c:4. + To prevent this from happening, we need this function to always + strip those extra backslashes. While canonicalize_file_name does + perform this simplification, it only works when the path is valid. + Since the simplification would be useful even if the path is not + valid (one can always set a breakpoint on a file, even if the file + does not exist locally), we rely instead on GetFullPathName to + perform the canonicalization. */ + +#if defined (_WIN32) + { + char buf[MAX_PATH]; + DWORD len = GetFullPathName (filename, MAX_PATH, buf, NULL); + + /* The file system is case-insensitive but case-preserving. + So it is important we do not lowercase the path. Otherwise, + we might not be able to display the original casing in a given + path. */ + if (len > 0 && len < MAX_PATH) + return gdb::unique_xmalloc_ptr (xstrdup (buf)); + } +#else + { + char *rp = canonicalize_file_name (filename); + + if (rp != NULL) + return gdb::unique_xmalloc_ptr (rp); + } +#endif + + /* This system is a lost cause, just dup the buffer. */ + return gdb::unique_xmalloc_ptr (xstrdup (filename)); +} + +/* See common/pathstuff.h. */ + +gdb::unique_xmalloc_ptr +gdb_realpath_keepfile (const char *filename) +{ + const char *base_name = lbasename (filename); + char *dir_name; + char *result; + + /* Extract the basename of filename, and return immediately + a copy of filename if it does not contain any directory prefix. */ + if (base_name == filename) + return gdb::unique_xmalloc_ptr (xstrdup (filename)); + + dir_name = (char *) alloca ((size_t) (base_name - filename + 2)); + /* Allocate enough space to store the dir_name + plus one extra + character sometimes needed under Windows (see below), and + then the closing \000 character. */ + strncpy (dir_name, filename, base_name - filename); + dir_name[base_name - filename] = '\000'; + +#ifdef HAVE_DOS_BASED_FILE_SYSTEM + /* We need to be careful when filename is of the form 'd:foo', which + is equivalent of d:./foo, which is totally different from d:/foo. */ + if (strlen (dir_name) == 2 && isalpha (dir_name[0]) && dir_name[1] == ':') + { + dir_name[2] = '.'; + dir_name[3] = '\000'; + } +#endif + + /* Canonicalize the directory prefix, and build the resulting + filename. If the dirname realpath already contains an ending + directory separator, avoid doubling it. */ + gdb::unique_xmalloc_ptr path_storage = gdb_realpath (dir_name); + const char *real_path = path_storage.get (); + if (IS_DIR_SEPARATOR (real_path[strlen (real_path) - 1])) + result = concat (real_path, base_name, (char *) NULL); + else + result = concat (real_path, SLASH_STRING, base_name, (char *) NULL); + + return gdb::unique_xmalloc_ptr (result); +} + +/* See common/pathstuff.h. */ + +gdb::unique_xmalloc_ptr +gdb_abspath (const char *path) +{ + gdb_assert (path != NULL && path[0] != '\0'); + + if (path[0] == '~') + { + std::string new_path = gdb_tilde_expand (path); + + return gdb::unique_xmalloc_ptr (xstrdup (new_path.c_str ())); + } + + if (IS_ABSOLUTE_PATH (path)) + return gdb::unique_xmalloc_ptr (xstrdup (path)); + + /* Beware the // my son, the Emacs barfs, the botch that catch... */ + return gdb::unique_xmalloc_ptr + (concat (current_directory, + IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1]) + ? "" : SLASH_STRING, + path, (char *) NULL)); +} diff --git a/gdb/common/pathstuff.h b/gdb/common/pathstuff.h new file mode 100644 index 0000000000..909fd786bb --- /dev/null +++ b/gdb/common/pathstuff.h @@ -0,0 +1,39 @@ +/* Path manipulation routines for GDB and gdbserver. + + Copyright (C) 1986-2018 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef PATHSTUFF_H +#define PATHSTUFF_H + +/* Path utilities. */ + +extern gdb::unique_xmalloc_ptr gdb_realpath (const char *filename); + +/* Return a copy of FILENAME, with its directory prefix canonicalized + by gdb_realpath. */ + +extern gdb::unique_xmalloc_ptr + gdb_realpath_keepfile (const char *filename); + +/* Return PATH in absolute form, performing tilde-expansion if necessary. + PATH cannot be NULL or the empty string. + This does not resolve symlinks however, use gdb_realpath for that. */ + +extern gdb::unique_xmalloc_ptr gdb_abspath (const char *path); + +#endif /* PATHSTUFF_H */ diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in index 3ce086d70f..4ac068c6dd 100644 --- a/gdb/gdbserver/Makefile.in +++ b/gdb/gdbserver/Makefile.in @@ -209,6 +209,7 @@ SFILES = \ $(srcdir)/common/gdb_tilde_expand.c \ $(srcdir)/common/gdb_vecs.c \ $(srcdir)/common/new-op.c \ + $(srcdir)/common/pathstuff.c \ $(srcdir)/common/print-utils.c \ $(srcdir)/common/ptid.c \ $(srcdir)/common/rsp-low.c \ @@ -256,6 +257,7 @@ OBS = \ mem-break.o \ new-op.o \ notif.o \ + pathstuff.o \ print-utils.o \ ptid.o \ regcache.o \ diff --git a/gdb/utils.c b/gdb/utils.c index c531748fe4..0acfad60cf 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -2838,57 +2838,6 @@ string_to_core_addr (const char *my_string) return addr; } -gdb::unique_xmalloc_ptr -gdb_realpath (const char *filename) -{ -/* On most hosts, we rely on canonicalize_file_name to compute - the FILENAME's realpath. - - But the situation is slightly more complex on Windows, due to some - versions of GCC which were reported to generate paths where - backlashes (the directory separator) were doubled. For instance: - c:\\some\\double\\slashes\\dir - ... instead of ... - c:\some\double\slashes\dir - Those double-slashes were getting in the way when comparing paths, - for instance when trying to insert a breakpoint as follow: - (gdb) b c:/some/double/slashes/dir/foo.c:4 - No source file named c:/some/double/slashes/dir/foo.c:4. - (gdb) b c:\some\double\slashes\dir\foo.c:4 - No source file named c:\some\double\slashes\dir\foo.c:4. - To prevent this from happening, we need this function to always - strip those extra backslashes. While canonicalize_file_name does - perform this simplification, it only works when the path is valid. - Since the simplification would be useful even if the path is not - valid (one can always set a breakpoint on a file, even if the file - does not exist locally), we rely instead on GetFullPathName to - perform the canonicalization. */ - -#if defined (_WIN32) - { - char buf[MAX_PATH]; - DWORD len = GetFullPathName (filename, MAX_PATH, buf, NULL); - - /* The file system is case-insensitive but case-preserving. - So it is important we do not lowercase the path. Otherwise, - we might not be able to display the original casing in a given - path. */ - if (len > 0 && len < MAX_PATH) - return gdb::unique_xmalloc_ptr (xstrdup (buf)); - } -#else - { - char *rp = canonicalize_file_name (filename); - - if (rp != NULL) - return gdb::unique_xmalloc_ptr (rp); - } -#endif - - /* This system is a lost cause, just dup the buffer. */ - return gdb::unique_xmalloc_ptr (xstrdup (filename)); -} - #if GDB_SELF_TEST static void @@ -2925,74 +2874,6 @@ gdb_realpath_tests () #endif /* GDB_SELF_TEST */ -/* Return a copy of FILENAME, with its directory prefix canonicalized - by gdb_realpath. */ - -gdb::unique_xmalloc_ptr -gdb_realpath_keepfile (const char *filename) -{ - const char *base_name = lbasename (filename); - char *dir_name; - char *result; - - /* Extract the basename of filename, and return immediately - a copy of filename if it does not contain any directory prefix. */ - if (base_name == filename) - return gdb::unique_xmalloc_ptr (xstrdup (filename)); - - dir_name = (char *) alloca ((size_t) (base_name - filename + 2)); - /* Allocate enough space to store the dir_name + plus one extra - character sometimes needed under Windows (see below), and - then the closing \000 character. */ - strncpy (dir_name, filename, base_name - filename); - dir_name[base_name - filename] = '\000'; - -#ifdef HAVE_DOS_BASED_FILE_SYSTEM - /* We need to be careful when filename is of the form 'd:foo', which - is equivalent of d:./foo, which is totally different from d:/foo. */ - if (strlen (dir_name) == 2 && isalpha (dir_name[0]) && dir_name[1] == ':') - { - dir_name[2] = '.'; - dir_name[3] = '\000'; - } -#endif - - /* Canonicalize the directory prefix, and build the resulting - filename. If the dirname realpath already contains an ending - directory separator, avoid doubling it. */ - gdb::unique_xmalloc_ptr path_storage = gdb_realpath (dir_name); - const char *real_path = path_storage.get (); - if (IS_DIR_SEPARATOR (real_path[strlen (real_path) - 1])) - result = concat (real_path, base_name, (char *) NULL); - else - result = concat (real_path, SLASH_STRING, base_name, (char *) NULL); - - return gdb::unique_xmalloc_ptr (result); -} - -/* Return PATH in absolute form, performing tilde-expansion if necessary. - PATH cannot be NULL or the empty string. - This does not resolve symlinks however, use gdb_realpath for that. */ - -gdb::unique_xmalloc_ptr -gdb_abspath (const char *path) -{ - gdb_assert (path != NULL && path[0] != '\0'); - - if (path[0] == '~') - return gdb::unique_xmalloc_ptr (tilde_expand (path)); - - if (IS_ABSOLUTE_PATH (path)) - return gdb::unique_xmalloc_ptr (xstrdup (path)); - - /* Beware the // my son, the Emacs barfs, the botch that catch... */ - return gdb::unique_xmalloc_ptr - (concat (current_directory, - IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1]) - ? "" : SLASH_STRING, - path, (char *) NULL)); -} - ULONGEST align_up (ULONGEST v, int n) { diff --git a/gdb/utils.h b/gdb/utils.h index b234762929..4f25be0968 100644 --- a/gdb/utils.h +++ b/gdb/utils.h @@ -23,6 +23,7 @@ #include "exceptions.h" #include "common/scoped_restore.h" +#include "common/pathstuff.h" #include extern void initialize_utils (void); @@ -295,12 +296,6 @@ extern struct cleanup *make_bpstat_clear_actions_cleanup (void); /* Path utilities. */ -extern gdb::unique_xmalloc_ptr gdb_realpath (const char *); - -extern gdb::unique_xmalloc_ptr gdb_realpath_keepfile (const char *); - -extern gdb::unique_xmalloc_ptr gdb_abspath (const char *); - extern int gdb_filename_fnmatch (const char *pattern, const char *string, int flags);