Create new common/pathstuff.[ch]

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-28  Sergio Durigan Junior  <sergiodj@redhat.com>

	* Makefile.in (COMMON_SFILES): Add "common/pathstuff.c".
	(HFILES_NO_SRCDIR): Add "common/pathstuff.h".
	* auto-load.c: Include "common/pathstuff.h".
	* common/common-def.h (current_directory): Move here.
	* common/gdb_tilde_expand.c (gdb_tilde_expand_up): New
	function.
	* common/gdb_tilde_expand.h (gdb_tilde_expand_up): New
	prototype.
	* common/pathstuff.c: New file.
	* common/pathstuff.h: New file.
	* compile/compile.c: Include "common/pathstuff.h".
	* defs.h (current_directory): Move to "common/common-defs.h".
	* dwarf2read.c: Include "common/pathstuff.h".
	* exec.c: Likewise.
	* guile/scm-safe-call.c: Likewise.
	* linux-thread-db.c: Likewise.
	* main.c: Likewise.
	* nto-tdep.c: Likewise.
	* objfiles.c: Likewise.
	* source.c: Likewise.
	* symtab.c: Likewise.
	* utils.c: Include "common/pathstuff.h".
	(gdb_realpath): Move to "common/pathstuff.c".
	(gdb_realpath_keepfile): Likewise.
	(gdb_abspath): Likewise.
	* utils.h (gdb_realpath): Move to "common/pathstuff.h".
	(gdb_realpath_keepfile): Likewise.
	(gdb_abspath): Likewise.

gdb/gdbserver/ChangeLog:
2018-02-28  Sergio Durigan Junior  <sergiodj@redhat.com>

	* Makefile.in (SFILES): Add "$(srcdir)/common/pathstuff.c".
	(OBJS): Add "pathstuff.o".
	* server.c (current_directory): New global variable.
	(captured_main): Initialize "current_directory".
This commit is contained in:
Sergio Durigan Junior 2018-02-09 18:44:59 -05:00
parent 3083294d65
commit b4987c956d
24 changed files with 276 additions and 129 deletions

View File

@ -1,3 +1,34 @@
2018-02-28 Sergio Durigan Junior <sergiodj@redhat.com>
* Makefile.in (COMMON_SFILES): Add "common/pathstuff.c".
(HFILES_NO_SRCDIR): Add "common/pathstuff.h".
* auto-load.c: Include "common/pathstuff.h".
* common/common-def.h (current_directory): Move here.
* common/gdb_tilde_expand.c (gdb_tilde_expand_up): New
function.
* common/gdb_tilde_expand.h (gdb_tilde_expand_up): New
prototype.
* common/pathstuff.c: New file.
* common/pathstuff.h: New file.
* compile/compile.c: Include "common/pathstuff.h".
* defs.h (current_directory): Move to "common/common-defs.h".
* dwarf2read.c: Include "common/pathstuff.h".
* exec.c: Likewise.
* guile/scm-safe-call.c: Likewise.
* linux-thread-db.c: Likewise.
* main.c: Likewise.
* nto-tdep.c: Likewise.
* objfiles.c: Likewise.
* source.c: Likewise.
* symtab.c: Likewise.
* utils.c: Include "common/pathstuff.h".
(gdb_realpath): Move to "common/pathstuff.c".
(gdb_realpath_keepfile): Likewise.
(gdb_abspath): Likewise.
* utils.h (gdb_realpath): Move to "common/pathstuff.h".
(gdb_realpath_keepfile): Likewise.
(gdb_abspath): Likewise.
2018-02-28 John Baldwin <jhb@FreeBSD.org>
* fbsd-nat.c (fbsd_resume): Use PT_SETSTEP for stepping and a

View File

@ -955,6 +955,7 @@ COMMON_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 \
@ -1429,6 +1430,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 \

View File

@ -40,6 +40,7 @@
#include "extension.h"
#include "gdb/section-scripts.h"
#include <algorithm>
#include "common/pathstuff.h"
/* The section to look in for auto-loaded scripts (in file formats that
support sections).

View File

@ -91,4 +91,7 @@
/* Pull in gdb::unique_xmalloc_ptr. */
#include "common/gdb_unique_ptr.h"
/* String containing the current directory (what getwd would return). */
extern char *current_directory;
#endif /* COMMON_DEFS_H */

View File

@ -80,3 +80,16 @@ gdb_tilde_expand (const char *dir)
return expanded_dir;
}
/* See common/gdb_tilde_expand.h. */
gdb::unique_xmalloc_ptr<char>
gdb_tilde_expand_up (const char *dir)
{
gdb_glob glob (dir, GLOB_TILDE_CHECK, NULL);
gdb_assert (glob.pathc () > 0);
/* "glob" may return more than one match to the path provided by the
user, but we are only interested in the first match. */
return gdb::unique_xmalloc_ptr<char> (xstrdup (glob.pathv ()[0]));
}

View File

@ -24,4 +24,8 @@
the full path. */
extern std::string gdb_tilde_expand (const char *dir);
/* Same as GDB_TILDE_EXPAND, but return the full path as a
gdb::unique_xmalloc_ptr<char>. */
extern gdb::unique_xmalloc_ptr<char> gdb_tilde_expand_up (const char *dir);
#endif /* ! GDB_TILDE_EXPAND_H */

142
gdb/common/pathstuff.c Normal file
View File

@ -0,0 +1,142 @@
/* 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 <http://www.gnu.org/licenses/>. */
#include "common-defs.h"
#include "pathstuff.h"
#include "host-defs.h"
#include "filenames.h"
#include "gdb_tilde_expand.h"
/* See common/pathstuff.h. */
gdb::unique_xmalloc_ptr<char>
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<char> (xstrdup (buf));
}
#else
{
char *rp = canonicalize_file_name (filename);
if (rp != NULL)
return gdb::unique_xmalloc_ptr<char> (rp);
}
#endif
/* This system is a lost cause, just dup the buffer. */
return gdb::unique_xmalloc_ptr<char> (xstrdup (filename));
}
/* See common/pathstuff.h. */
gdb::unique_xmalloc_ptr<char>
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<char> (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<char> 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<char> (result);
}
/* See common/pathstuff.h. */
gdb::unique_xmalloc_ptr<char>
gdb_abspath (const char *path)
{
gdb_assert (path != NULL && path[0] != '\0');
if (path[0] == '~')
return gdb_tilde_expand_up (path);
if (IS_ABSOLUTE_PATH (path))
return gdb::unique_xmalloc_ptr<char> (xstrdup (path));
/* Beware the // my son, the Emacs barfs, the botch that catch... */
return gdb::unique_xmalloc_ptr<char>
(concat (current_directory,
IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1])
? "" : SLASH_STRING,
path, (char *) NULL));
}

49
gdb/common/pathstuff.h Normal file
View File

@ -0,0 +1,49 @@
/* 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 <http://www.gnu.org/licenses/>. */
#ifndef PATHSTUFF_H
#define PATHSTUFF_H
/* Path utilities. */
/* Return the real path of FILENAME, expanding all the symbolic links.
Contrary to "gdb_abspath", this function does not use
CURRENT_DIRECTORY for path expansion. Instead, it relies on the
current working directory (CWD) of GDB or gdbserver. */
extern gdb::unique_xmalloc_ptr<char> gdb_realpath (const char *filename);
/* Return a copy of FILENAME, with its directory prefix canonicalized
by gdb_realpath. */
extern gdb::unique_xmalloc_ptr<char>
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.
Contrary to "gdb_realpath", this function uses CURRENT_DIRECTORY
for the path expansion. This may lead to scenarios the current
working directory (CWD) is different than CURRENT_DIRECTORY. */
extern gdb::unique_xmalloc_ptr<char> gdb_abspath (const char *path);
#endif /* PATHSTUFF_H */

View File

@ -41,6 +41,7 @@
#include "valprint.h"
#include "common/gdb_optional.h"
#include "common/gdb_unlinker.h"
#include "common/pathstuff.h"

View File

@ -402,10 +402,6 @@ enum info_proc_what
IP_ALL
};
/* * String containing the current directory (what getwd would return). */
extern char *current_directory;
/* * Default radixes for input and output. Only some values supported. */
extern unsigned input_radix;
extern unsigned output_radix;

View File

@ -87,6 +87,7 @@
#include <set>
#include <forward_list>
#include "rust-lang.h"
#include "common/pathstuff.h"
/* When == 1, print basic high level tracing messages.
When > 1, be more verbose.

View File

@ -45,6 +45,7 @@
#include <sys/stat.h>
#include "solist.h"
#include <algorithm>
#include "common/pathstuff.h"
void (*deprecated_file_changed_hook) (const char *);

View File

@ -1,3 +1,10 @@
2018-02-28 Sergio Durigan Junior <sergiodj@redhat.com>
* Makefile.in (SFILES): Add "$(srcdir)/common/pathstuff.c".
(OBJS): Add "pathstuff.o".
* server.c (current_directory): New global variable.
(captured_main): Initialize "current_directory".
2018-02-26 Alan Hayward <alan.hayward@arm.com>
* tdesc.c: Use common/tdesc.h.

View File

@ -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 \
@ -249,6 +250,7 @@ OBS = \
common/gdb_tilde_expand.o \
common/gdb_vecs.o \
common/new-op.o \
common/pathstuff.o \
common/print-utils.o \
common/ptid.o \
common/rsp-low.o \

View File

@ -56,6 +56,10 @@
break; \
}
/* String containing the current directory (what getwd would return). */
char *current_directory;
/* The environment to pass to the inferior when creating it. */
static gdb_environ our_environ;
@ -3539,6 +3543,13 @@ captured_main (int argc, char *argv[])
const char *selftest_filter = NULL;
#endif
current_directory = getcwd (NULL, 0);
if (current_directory == NULL)
{
error (_("%s: error finding working directory"),
safe_strerror (errno));
}
while (*next_arg != NULL && **next_arg == '-')
{
if (strcmp (*next_arg, "--version") == 0)

View File

@ -23,6 +23,7 @@
#include "defs.h"
#include "filenames.h"
#include "guile-internal.h"
#include "common/pathstuff.h"
/* Struct to marshall args to scscm_safe_call_body. */

View File

@ -46,6 +46,7 @@
#include <ctype.h>
#include "nat/linux-namespaces.h"
#include <algorithm>
#include "common/pathstuff.h"
/* GNU/Linux libthread_db support.

View File

@ -46,6 +46,7 @@
#include "infrun.h"
#include "signals-state-save-restore.h"
#include <vector>
#include "common/pathstuff.h"
/* The selected interpreter. This will be used as a set command
variable, so it should always be malloc'ed - since

View File

@ -32,6 +32,7 @@
#include "gdbcore.h"
#include "objfiles.h"
#include "source.h"
#include "common/pathstuff.h"
#define QNX_NOTE_NAME "QNX"
#define QNX_INFO_SECT_NAME "QNX_info"

View File

@ -52,6 +52,7 @@
#include "solist.h"
#include "gdb_bfd.h"
#include "btrace.h"
#include "common/pathstuff.h"
#include <vector>

View File

@ -44,6 +44,7 @@
#include "readline/readline.h"
#include "common/enum-flags.h"
#include <algorithm>
#include "common/pathstuff.h"
#define OPEN_MODE (O_RDONLY | O_BINARY)
#define FDOPEN_MODE FOPEN_RB

View File

@ -66,6 +66,7 @@
#include "filename-seen-cache.h"
#include "arch-utils.h"
#include <algorithm>
#include "common/pathstuff.h"
/* Forward declarations for local functions. */

View File

@ -70,6 +70,7 @@
#include "common/gdb_optional.h"
#include "cp-support.h"
#include <algorithm>
#include "common/pathstuff.h"
#if !HAVE_DECL_MALLOC
extern PTR malloc (); /* ARI: PTR */
@ -2838,57 +2839,6 @@ string_to_core_addr (const char *my_string)
return addr;
}
gdb::unique_xmalloc_ptr<char>
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<char> (xstrdup (buf));
}
#else
{
char *rp = canonicalize_file_name (filename);
if (rp != NULL)
return gdb::unique_xmalloc_ptr<char> (rp);
}
#endif
/* This system is a lost cause, just dup the buffer. */
return gdb::unique_xmalloc_ptr<char> (xstrdup (filename));
}
#if GDB_SELF_TEST
static void
@ -2925,74 +2875,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<char>
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<char> (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<char> 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<char> (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<char>
gdb_abspath (const char *path)
{
gdb_assert (path != NULL && path[0] != '\0');
if (path[0] == '~')
return gdb::unique_xmalloc_ptr<char> (tilde_expand (path));
if (IS_ABSOLUTE_PATH (path))
return gdb::unique_xmalloc_ptr<char> (xstrdup (path));
/* Beware the // my son, the Emacs barfs, the botch that catch... */
return gdb::unique_xmalloc_ptr<char>
(concat (current_directory,
IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1])
? "" : SLASH_STRING,
path, (char *) NULL));
}
ULONGEST
align_up (ULONGEST v, int n)
{

View File

@ -295,12 +295,6 @@ extern struct cleanup *make_bpstat_clear_actions_cleanup (void);
/* Path utilities. */
extern gdb::unique_xmalloc_ptr<char> gdb_realpath (const char *);
extern gdb::unique_xmalloc_ptr<char> gdb_realpath_keepfile (const char *);
extern gdb::unique_xmalloc_ptr<char> gdb_abspath (const char *);
extern int gdb_filename_fnmatch (const char *pattern, const char *string,
int flags);