From patchwork Fri Aug 18 20:00:22 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 22232 Received: (qmail 101196 invoked by alias); 18 Aug 2017 20:01:10 -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 89084 invoked by uid 89); 18 Aug 2017 20:00:35 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.5 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: gproxy10-pub.mail.unifiedlayer.com Received: from gproxy10-pub.mail.unifiedlayer.com (HELO gproxy10-pub.mail.unifiedlayer.com) (69.89.20.226) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 18 Aug 2017 20:00:31 +0000 Received: from cmgw4 (unknown [10.0.90.85]) by gproxy10.mail.unifiedlayer.com (Postfix) with ESMTP id D540A140759 for ; Fri, 18 Aug 2017 14:00:29 -0600 (MDT) Received: from box522.bluehost.com ([74.220.219.122]) by cmgw4 with id yk0S1v02T2f2jeq01k0Vti; Fri, 18 Aug 2017 14:00:29 -0600 X-Authority-Analysis: v=2.2 cv=ELV26xRC c=1 sm=1 tr=0 a=GsOEXm/OWkKvwdLVJsfwcA==:117 a=GsOEXm/OWkKvwdLVJsfwcA==:17 a=KeKAF7QvOSUA:10 a=zstS-IiYAAAA:8 a=KKAkSRfTAAAA:8 a=mDV3o1hIAAAA:8 a=544D_HGdAAAA:8 a=ZKVEt8IAUld8LwyjNiMA:9 a=jMA7kMfXHRociw9G:21 a=FMEUInoa-otaI2Fb:21 a=4G6NA9xxw8l3yy4pmD5M:22 a=cvBusfyB2V15izCimMoJ:22 a=_FVE-zBwftR9WsbkzFJk:22 a=m6Qi5owKsdZQ2eb-sZEm:22 Received: from 75-166-24-97.hlrn.qwest.net ([75.166.24.97]:49122 helo=bapiya.Home) by box522.bluehost.com with esmtpsa (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.87) (envelope-from ) id 1dinRS-001KNP-K7; Fri, 18 Aug 2017 14:00:26 -0600 From: Tom Tromey To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [RFA 3/5] Change gdb_realpath to return a unique_xmalloc_ptr Date: Fri, 18 Aug 2017 14:00:22 -0600 Message-Id: <20170818200024.4948-4-tom@tromey.com> In-Reply-To: <20170818200024.4948-1-tom@tromey.com> References: <20170818200024.4948-1-tom@tromey.com> X-BWhitelist: no X-Exim-ID: 1dinRS-001KNP-K7 X-Source-Sender: 75-166-24-97.hlrn.qwest.net (bapiya.Home) [75.166.24.97]:49122 X-Source-Auth: tom+tromey.com X-Email-Count: 4 X-Source-Cap: ZWx5bnJvYmk7ZWx5bnJvYmk7Ym94NTIyLmJsdWVob3N0LmNvbQ== X-Local-Domain: yes This changes gdb_realpath to return a unique_xmalloc_ptr and fixes up the callers. This allows removing some cleanups. This change by itself caused xfullpath.exp to fail; and attempting to fix that ran into various problems (like .get() being optimized out); so this patch also rewrites xfullpath.exp to be a C++ selftest instead. ChangeLog 2017-08-18 Tom Tromey * exec.c (exec_file_attach): Update. * linux-thread-db.c (try_thread_db_load): Update. * guile/scm-safe-call.c (gdbscm_safe_source_script): Update. * utils.c (gdb_realpath): Change return type. (gdb_realpath_keepfile): Update. (gdb_realpath_check_trailer, gdb_realpath_tests): New functions. (_initialize_utils): Register the new self test. * source.c (openp): Update. (find_and_open_source): Update. * nto-tdep.c (nto_find_and_open_solib): Update. * main.c (set_gdb_data_directory): Update. (captured_main_1): Update. * dwarf2read.c (dwarf2_get_dwz_file): Update (dw2_map_symbol_filenames): Update. * auto-load.c (auto_load_safe_path_vec_update): Update. (filename_is_in_auto_load_safe_path_vec): Change type of "filename_realp". (auto_load_objfile_script): Update. (file_is_auto_load_safe): Update. Use std::string. * utils.h (gdb_realpath): Return a gdb::unique_xmalloc_ptr. testsuite/ChangeLog 2017-08-18 Tom Tromey * gdb.gdb/xfullpath.exp: Remove. --- gdb/ChangeLog | 23 +++++++++++++ gdb/auto-load.c | 69 +++++++++++++++---------------------- gdb/dwarf2read.c | 14 ++++---- gdb/exec.c | 27 ++++++--------- gdb/guile/scm-safe-call.c | 5 ++- gdb/linux-thread-db.c | 2 +- gdb/main.c | 5 +-- gdb/nto-tdep.c | 2 +- gdb/objfiles.c | 2 +- gdb/source.c | 4 +-- gdb/symtab.c | 2 +- gdb/testsuite/ChangeLog | 4 +++ gdb/testsuite/gdb.gdb/xfullpath.exp | 60 -------------------------------- gdb/utils.c | 54 +++++++++++++++++++++++++---- gdb/utils.h | 2 +- 15 files changed, 130 insertions(+), 145 deletions(-) delete mode 100644 gdb/testsuite/gdb.gdb/xfullpath.exp diff --git a/gdb/ChangeLog b/gdb/ChangeLog index ec022c3..0257189 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,28 @@ 2017-08-18 Tom Tromey + * exec.c (exec_file_attach): Update. + * linux-thread-db.c (try_thread_db_load): Update. + * guile/scm-safe-call.c (gdbscm_safe_source_script): Update. + * utils.c (gdb_realpath): Change return type. + (gdb_realpath_keepfile): Update. + (gdb_realpath_check_trailer, gdb_realpath_tests): New functions. + (_initialize_utils): Register the new self test. + * source.c (openp): Update. + (find_and_open_source): Update. + * nto-tdep.c (nto_find_and_open_solib): Update. + * main.c (set_gdb_data_directory): Update. + (captured_main_1): Update. + * dwarf2read.c (dwarf2_get_dwz_file): Update + (dw2_map_symbol_filenames): Update. + * auto-load.c (auto_load_safe_path_vec_update): Update. + (filename_is_in_auto_load_safe_path_vec): Change type of + "filename_realp". + (auto_load_objfile_script): Update. + (file_is_auto_load_safe): Update. Use std::string. + * utils.h (gdb_realpath): Return a gdb::unique_xmalloc_ptr. + +2017-08-18 Tom Tromey + * utils.c (gdb_realpath_keepfile): Return a gdb::unique_xmalloc_ptr. * exec.c (exec_file_attach): Update. diff --git a/gdb/auto-load.c b/gdb/auto-load.c index 9f1f13f..5bba813 100644 --- a/gdb/auto-load.c +++ b/gdb/auto-load.c @@ -218,7 +218,7 @@ auto_load_safe_path_vec_update (void) { char *dir = VEC_index (char_ptr, auto_load_safe_path_vec, ix); char *expanded = tilde_expand (dir); - char *real_path = gdb_realpath (expanded); + gdb::unique_xmalloc_ptr real_path = gdb_realpath (expanded); /* Ensure the current entry is at least tilde_expand-ed. */ VEC_replace (char_ptr, auto_load_safe_path_vec, ix, expanded); @@ -238,16 +238,15 @@ auto_load_safe_path_vec_update (void) xfree (dir); /* If gdb_realpath returns a different content, append it. */ - if (strcmp (real_path, expanded) == 0) - xfree (real_path); - else + if (strcmp (real_path.get (), expanded) != 0) { - VEC_safe_push (char_ptr, auto_load_safe_path_vec, real_path); - if (debug_auto_load) fprintf_unfiltered (gdb_stdlog, _("auto-load: And canonicalized as \"%s\".\n"), - real_path); + real_path.get ()); + + VEC_safe_push (char_ptr, auto_load_safe_path_vec, + real_path.release ()); } } } @@ -419,12 +418,11 @@ filename_is_in_pattern (const char *filename, const char *pattern) /* Return 1 if FILENAME belongs to one of directory components of AUTO_LOAD_SAFE_PATH_VEC. Return 0 otherwise. auto_load_safe_path_vec_update is never called. - *FILENAME_REALP may be updated by gdb_realpath of FILENAME - it has to be - freed by the caller. */ + *FILENAME_REALP may be updated by gdb_realpath of FILENAME. */ static int filename_is_in_auto_load_safe_path_vec (const char *filename, - char **filename_realp) + gdb::unique_xmalloc_ptr *filename_realp) { char *pattern; int ix; @@ -439,17 +437,17 @@ filename_is_in_auto_load_safe_path_vec (const char *filename, if (*filename_realp == NULL) { *filename_realp = gdb_realpath (filename); - if (debug_auto_load && strcmp (*filename_realp, filename) != 0) + if (debug_auto_load && strcmp (filename_realp->get (), filename) != 0) fprintf_unfiltered (gdb_stdlog, _("auto-load: Resolved " "file \"%s\" as \"%s\".\n"), - filename, *filename_realp); + filename, filename_realp->get ()); } - if (strcmp (*filename_realp, filename) != 0) + if (strcmp (filename_realp->get (), filename) != 0) for (ix = 0; VEC_iterate (char_ptr, auto_load_safe_path_vec, ix, pattern); ++ix) - if (filename_is_in_pattern (*filename_realp, pattern)) + if (filename_is_in_pattern (filename_realp->get (), pattern)) break; } @@ -476,8 +474,7 @@ filename_is_in_auto_load_safe_path_vec (const char *filename, int file_is_auto_load_safe (const char *filename, const char *debug_fmt, ...) { - char *filename_real = NULL; - struct cleanup *back_to; + gdb::unique_xmalloc_ptr filename_real; static int advice_printed = 0; if (debug_auto_load) @@ -489,34 +486,24 @@ file_is_auto_load_safe (const char *filename, const char *debug_fmt, ...) va_end (debug_args); } - back_to = make_cleanup (free_current_contents, &filename_real); - if (filename_is_in_auto_load_safe_path_vec (filename, &filename_real)) - { - do_cleanups (back_to); - return 1; - } + return 1; auto_load_safe_path_vec_update (); if (filename_is_in_auto_load_safe_path_vec (filename, &filename_real)) - { - do_cleanups (back_to); - return 1; - } + return 1; warning (_("File \"%s\" auto-loading has been declined by your " "`auto-load safe-path' set to \"%s\"."), - filename_real, auto_load_safe_path); + filename_real.get (), auto_load_safe_path); if (!advice_printed) { const char *homedir = getenv ("HOME"); - char *homeinit; if (homedir == NULL) homedir = "$HOME"; - homeinit = xstrprintf ("%s/%s", homedir, gdbinit); - make_cleanup (xfree, homeinit); + std::string homeinit = string_printf ("%s/%s", homedir, gdbinit); printf_filtered (_("\ To enable execution of this file add\n\ @@ -528,11 +515,11 @@ line to your configuration file \"%s\".\n\ For more information about this security protection see the\n\ \"Auto-loading safe path\" section in the GDB manual. E.g., run from the shell:\n\ \tinfo \"(gdb)Auto-loading safe path\"\n"), - filename_real, homeinit, homeinit); + filename_real.get (), + homeinit.c_str (), homeinit.c_str ()); advice_printed = 1; } - do_cleanups (back_to); return 0; } @@ -891,30 +878,28 @@ void auto_load_objfile_script (struct objfile *objfile, const struct extension_language_defn *language) { - char *realname = gdb_realpath (objfile_name (objfile)); - struct cleanup *cleanups = make_cleanup (xfree, realname); + gdb::unique_xmalloc_ptr realname + = gdb_realpath (objfile_name (objfile)); - if (!auto_load_objfile_script_1 (objfile, realname, language)) + if (!auto_load_objfile_script_1 (objfile, realname.get (), language)) { /* For Windows/DOS .exe executables, strip the .exe suffix, so that FOO-gdb.gdb could be used for FOO.exe, and try again. */ - size_t len = strlen (realname); + size_t len = strlen (realname.get ()); const size_t lexe = sizeof (".exe") - 1; - if (len > lexe && strcasecmp (realname + len - lexe, ".exe") == 0) + if (len > lexe && strcasecmp (realname.get () + len - lexe, ".exe") == 0) { len -= lexe; - realname[len] = '\0'; + realname.get ()[len] = '\0'; if (debug_auto_load) fprintf_unfiltered (gdb_stdlog, _("auto-load: Stripped .exe suffix, " "retrying with \"%s\".\n"), - realname); - auto_load_objfile_script_1 (objfile, realname, language); + realname.get ()); + auto_load_objfile_script_1 (objfile, realname.get (), language); } } - - do_cleanups (cleanups); } /* Subroutine of source_section_scripts to simplify it. diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 0e28144..3822850 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -2717,10 +2717,10 @@ dwarf2_get_dwz_file (void) std::string abs_storage; if (!IS_ABSOLUTE_PATH (filename)) { - char *abs = gdb_realpath (objfile_name (dwarf2_per_objfile->objfile)); + gdb::unique_xmalloc_ptr abs + = gdb_realpath (objfile_name (dwarf2_per_objfile->objfile)); - make_cleanup (xfree, abs); - abs_storage = ldirname (abs) + SLASH_STRING + filename; + abs_storage = ldirname (abs.get ()) + SLASH_STRING + filename; filename = abs_storage.c_str (); } @@ -3589,7 +3589,7 @@ dw2_get_real_path (struct objfile *objfile, qfn->num_file_names, const char *); if (qfn->real_names[index] == NULL) - qfn->real_names[index] = gdb_realpath (qfn->file_names[index]); + qfn->real_names[index] = gdb_realpath (qfn->file_names[index]).release (); return qfn->real_names[index]; } @@ -4383,13 +4383,11 @@ dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun, dwarf2_per_objfile->filenames_cache->traverse ([&] (const char *filename) { - const char *this_real_name; + gdb::unique_xmalloc_ptr this_real_name; if (need_fullname) this_real_name = gdb_realpath (filename); - else - this_real_name = NULL; - (*fun) (filename, this_real_name, data); + (*fun) (filename, this_real_name.get (), data); }); } diff --git a/gdb/exec.c b/gdb/exec.c index 45bc133..92c87e4 100644 --- a/gdb/exec.c +++ b/gdb/exec.c @@ -249,16 +249,12 @@ exec_file_locate_attach (int pid, int defer_bp_reset, int from_tty) void exec_file_attach (const char *filename, int from_tty) { - struct cleanup *cleanups; - /* First, acquire a reference to the current exec_bfd. We release this at the end of the function; but acquiring it now lets the BFD cache return it if this call refers to the same file. */ gdb_bfd_ref (exec_bfd); gdb_bfd_ref_ptr exec_bfd_holder (exec_bfd); - cleanups = make_cleanup (null_cleanup, NULL); - /* Remove any previous exec file. */ exec_close (); @@ -274,7 +270,7 @@ exec_file_attach (const char *filename, int from_tty) else { int load_via_target = 0; - char *scratch_pathname, *canonical_pathname; + const char *scratch_pathname, *canonical_pathname; int scratch_chan; struct target_section *sections = NULL, *sections_end = NULL; char **matching; @@ -287,6 +283,7 @@ exec_file_attach (const char *filename, int from_tty) load_via_target = 1; } + gdb::unique_xmalloc_ptr canonical_storage, scratch_storage; if (load_via_target) { /* gdb_bfd_fopen does not support "target:" filenames. */ @@ -295,19 +292,18 @@ exec_file_attach (const char *filename, int from_tty) "not supported for %s sysroots"), TARGET_SYSROOT_PREFIX); - scratch_pathname = xstrdup (filename); - make_cleanup (xfree, scratch_pathname); - + scratch_pathname = filename; scratch_chan = -1; - canonical_pathname = scratch_pathname; } else { + char *temp_pathname; + scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, filename, write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY, - &scratch_pathname); + &temp_pathname); #if defined(__GO32__) || defined(_WIN32) || defined(__CYGWIN__) if (scratch_chan < 0) { @@ -318,18 +314,19 @@ exec_file_attach (const char *filename, int from_tty) exename, write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY, - &scratch_pathname); + &temp_pathname); } #endif if (scratch_chan < 0) perror_with_name (filename); - make_cleanup (xfree, scratch_pathname); + scratch_storage.reset (temp_pathname); + scratch_pathname = temp_pathname; /* gdb_bfd_open (and its variants) prefers canonicalized pathname for better BFD caching. */ - canonical_pathname = gdb_realpath (scratch_pathname); - make_cleanup (xfree, canonical_pathname); + canonical_storage = gdb_realpath (scratch_pathname); + canonical_pathname = canonical_storage.get (); } gdb_bfd_ref_ptr temp; @@ -390,8 +387,6 @@ exec_file_attach (const char *filename, int from_tty) (*deprecated_exec_file_display_hook) (filename); } - do_cleanups (cleanups); - bfd_cache_close_all (); observer_notify_executable_changed (); } diff --git a/gdb/guile/scm-safe-call.c b/gdb/guile/scm-safe-call.c index 64a69a3..15bab27 100644 --- a/gdb/guile/scm-safe-call.c +++ b/gdb/guile/scm-safe-call.c @@ -438,19 +438,18 @@ gdbscm_safe_source_script (const char *filename) %load-path, but we don't want %load-path to be searched. At least not by default. This function is invoked by the "source" GDB command which already has its own path search support. */ - char *abs_filename = NULL; + gdb::unique_xmalloc_ptr abs_filename; const char *result; if (!IS_ABSOLUTE_PATH (filename)) { abs_filename = gdb_realpath (filename); - filename = abs_filename; + filename = abs_filename.get (); } result = gdbscm_with_guile (scscm_source_scheme_script, (void *) filename); - xfree (abs_filename); if (result != NULL) return xstrdup (result); return NULL; diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c index cf68013..6d98135 100644 --- a/gdb/linux-thread-db.c +++ b/gdb/linux-thread-db.c @@ -695,7 +695,7 @@ try_thread_db_load (const char *library, int check_auto_load_safe) /* Do not save system library name, that one is always trusted. */ if (strchr (library, '/') != NULL) - info->filename = gdb_realpath (library); + info->filename = gdb_realpath (library).release (); if (try_thread_db_load_1 (info)) return 1; diff --git a/gdb/main.c b/gdb/main.c index 886e17f..a0646ed 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -120,7 +120,7 @@ set_gdb_data_directory (const char *new_datadir) warning (_("%s is not a directory."), new_datadir); xfree (gdb_datadir); - gdb_datadir = gdb_realpath (new_datadir); + gdb_datadir = gdb_realpath (new_datadir).release (); /* gdb_realpath won't return an absolute path if the path doesn't exist, but we still want to record an absolute path here. If the user entered @@ -1083,7 +1083,8 @@ captured_main_1 (struct captured_main_args *context) the same as the $HOME/.gdbinit file (it should exist, also). */ if (local_gdbinit) { - auto_load_local_gdbinit_pathname = gdb_realpath (local_gdbinit); + auto_load_local_gdbinit_pathname + = gdb_realpath (local_gdbinit).release (); if (!inhibit_gdbinit && auto_load_local_gdbinit && file_is_auto_load_safe (local_gdbinit, diff --git a/gdb/nto-tdep.c b/gdb/nto-tdep.c index f9959ca..0b53c4b 100644 --- a/gdb/nto-tdep.c +++ b/gdb/nto-tdep.c @@ -142,7 +142,7 @@ nto_find_and_open_solib (const char *solib, unsigned o_flags, if (temp_pathname) { if (ret >= 0) - *temp_pathname = gdb_realpath (arch_path); + *temp_pathname = gdb_realpath (arch_path).release (); else *temp_pathname = NULL; } diff --git a/gdb/objfiles.c b/gdb/objfiles.c index ff99ca6..c49c7ea 100644 --- a/gdb/objfiles.c +++ b/gdb/objfiles.c @@ -376,7 +376,7 @@ struct objfile * allocate_objfile (bfd *abfd, const char *name, objfile_flags flags) { struct objfile *objfile; - char *expanded_name; + const char *expanded_name; objfile = XCNEW (struct objfile); objfile->psymbol_cache = psymbol_bcache_init (); diff --git a/gdb/source.c b/gdb/source.c index e2a507d..0453f92 100644 --- a/gdb/source.c +++ b/gdb/source.c @@ -911,7 +911,7 @@ done: if (fd < 0) *filename_opened = NULL; else if ((opts & OPF_RETURN_REALPATH) != 0) - *filename_opened = gdb_realpath (filename); + *filename_opened = gdb_realpath (filename).release (); else *filename_opened = gdb_abspath (filename).release (); } @@ -1050,7 +1050,7 @@ find_and_open_source (const char *filename, result = gdb_open_cloexec (*fullname, OPEN_MODE, 0); if (result >= 0) { - char *lpath = gdb_realpath (*fullname); + char *lpath = gdb_realpath (*fullname).release (); xfree (*fullname); *fullname = lpath; diff --git a/gdb/symtab.c b/gdb/symtab.c index ccf31cc..2babe7f 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -468,7 +468,7 @@ iterate_over_symtabs (const char *name, absolutizing a relative path. */ if (IS_ABSOLUTE_PATH (name)) { - real_path.reset (gdb_realpath (name)); + real_path = gdb_realpath (name); gdb_assert (IS_ABSOLUTE_PATH (real_path.get ())); } diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index d188f83..78e7940 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2017-08-18 Tom Tromey + + * gdb.gdb/xfullpath.exp: Remove. + 2017-08-18 Yao Qi * gdb.server/unittest.exp: New. diff --git a/gdb/testsuite/gdb.gdb/xfullpath.exp b/gdb/testsuite/gdb.gdb/xfullpath.exp deleted file mode 100644 index 8c90693..0000000 --- a/gdb/testsuite/gdb.gdb/xfullpath.exp +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright 2002-2017 Free Software Foundation, Inc. - -# 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 . - -# This file was written by Joel Brobecker. (brobecker@gnat.com), derived -# from selftest.exp, written by Rob Savoye. - -load_lib selftest-support.exp - -proc test_with_self {} { - # A file which contains a directory prefix - gdb_test "print gdb_realpath (\"./xfullpath.exp\")" \ - ".\[0-9\]+ =.*\".*/xfullpath.exp\"" \ - "A filename with ./ as the directory prefix" - - # A file which contains a directory prefix - gdb_test "print gdb_realpath (\"../../defs.h\")" \ - ".\[0-9\]+ =.*\".*/defs.h\"" \ - "A filename with ../ in the directory prefix" - - # A one-character filename - gdb_test "print gdb_realpath (\"./a\")" \ - ".\[0-9\]+ =.*\".*/a\"" \ - "A one-char filename in the current directory" - - # A file in the root directory - gdb_test "print gdb_realpath (\"/root_file_which_should_exist\")" \ - ".\[0-9\]+ =.*\"/root_file_which_should_exist\"" \ - "A filename in the root directory" - - # A file which does not have a directory prefix - gdb_test "print gdb_realpath (\"xfullpath.exp\")" \ - ".\[0-9\]+ =.*\"xfullpath.exp\"" \ - "A filename without any directory prefix" - - # A one-char filename without any directory prefix - gdb_test "print gdb_realpath (\"a\")" \ - ".\[0-9\]+ =.*\"a\"" \ - "A one-char filename without any directory prefix" - - # An empty filename - gdb_test "print gdb_realpath (\"\")" \ - ".\[0-9\]+ =.*\"\"" \ - "an empty filename" - - return 0 -} - -do_self_tests captured_main test_with_self diff --git a/gdb/utils.c b/gdb/utils.c index 5bdc638..3ca29b7 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -66,6 +66,7 @@ #include "interps.h" #include "gdb_regex.h" #include "job-control.h" +#include "common/selftest.h" #if !HAVE_DECL_MALLOC extern PTR malloc (); /* ARI: PTR */ @@ -2662,7 +2663,7 @@ string_to_core_addr (const char *my_string) return addr; } -char * +gdb::unique_xmalloc_ptr gdb_realpath (const char *filename) { /* On most hosts, we rely on canonicalize_file_name to compute @@ -2698,21 +2699,57 @@ gdb_realpath (const char *filename) we might not be able to display the original casing in a given path. */ if (len > 0 && len < MAX_PATH) - return xstrdup (buf); + return gdb::unique_xmalloc_ptr (xstrdup (buf)); } #else { char *rp = canonicalize_file_name (filename); if (rp != NULL) - return rp; + return gdb::unique_xmalloc_ptr (rp); } #endif /* This system is a lost cause, just dup the buffer. */ - return xstrdup (filename); + return gdb::unique_xmalloc_ptr (xstrdup (filename)); } +#if GDB_SELF_TEST + +static void +gdb_realpath_check_trailer (const char *input, const char *trailer) +{ + gdb::unique_xmalloc_ptr result = gdb_realpath (input); + + size_t len = strlen (result.get ()); + size_t trail_len = strlen (trailer); + + SELF_CHECK (len >= trail_len + && strcmp (result.get () + len - trail_len, trailer) == 0); +} + +static void +gdb_realpath_tests () +{ + /* A file which contains a directory prefix. */ + gdb_realpath_check_trailer ("./xfullpath.exp", "/xfullpath.exp"); + /* A file which contains a directory prefix. */ + gdb_realpath_check_trailer ("../../defs.h", "/defs.h"); + /* A one-character filename. */ + gdb_realpath_check_trailer ("./a", "/a"); + /* A file in the root directory. */ + gdb_realpath_check_trailer ("/root_file_which_should_exist", + "/root_file_which_should_exist"); + /* A file which does not have a directory prefix. */ + gdb_realpath_check_trailer ("xfullpath.exp", "xfullpath.exp"); + /* A one-char filename without any directory prefix. */ + gdb_realpath_check_trailer ("a", "a"); + /* An empty filename. */ + gdb_realpath_check_trailer ("", ""); +} + +#endif /* GDB_SELF_TEST */ + /* Return a copy of FILENAME, with its directory prefix canonicalized by gdb_realpath. */ @@ -2721,7 +2758,6 @@ gdb_realpath_keepfile (const char *filename) { const char *base_name = lbasename (filename); char *dir_name; - char *real_path; char *result; /* Extract the basename of filename, and return immediately @@ -2749,13 +2785,13 @@ gdb_realpath_keepfile (const char *filename) /* Canonicalize the directory prefix, and build the resulting filename. If the dirname realpath already contains an ending directory separator, avoid doubling it. */ - real_path = gdb_realpath (dir_name); + 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); - xfree (real_path); return gdb::unique_xmalloc_ptr (result); } @@ -3283,4 +3319,8 @@ _initialize_utils (void) add_internal_problem_command (&internal_error_problem); add_internal_problem_command (&internal_warning_problem); add_internal_problem_command (&demangler_warning_problem); + +#if GDB_SELF_TEST + selftests::register_test (gdb_realpath_tests); +#endif } diff --git a/gdb/utils.h b/gdb/utils.h index 477257b..3ceefc1 100644 --- a/gdb/utils.h +++ b/gdb/utils.h @@ -252,7 +252,7 @@ extern struct cleanup *make_bpstat_clear_actions_cleanup (void); /* Path utilities. */ -extern char *gdb_realpath (const char *); +extern gdb::unique_xmalloc_ptr gdb_realpath (const char *); extern gdb::unique_xmalloc_ptr gdb_realpath_keepfile (const char *);