This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH, doc RFA] New option -B: simplify running gdb from build directory


Doug Evans writes:
 > Hi.
 > 
 > The "make run" Makefile rule simplifies running gdb from the shell,
 > but it doesn't simplify running gdb from gdb: I'm always typing
 > "--data-directory=$(pwd)/data-directory".
 > And since we can't agree on a way to let gdb auto-detect being run
 > from the build directory, how about this?
 > 
 > This patch provides a new option, -B, which if provided tells gdb
 > it *may* have been run from the build directory.  If -B was provided
 > and --data-directory was not provided, use a heuristic to determine
 > if gdb was run from the build directory and if so set gdb_datadir
 > appropriately.
 > 
 > We can certainly discuss what's the best heuristic to use here.
 > We don't, IMO, have to employ too complicated a heuristic because
 > the user has explicitly passed -B.
 > OTOH, I'm sure one can improve a bit on the heuristic that's here.
 > One thought I have is to have the Makefile create a file with a name that
 > is reasonably obscure (maybe even pseudo-cryptographically secure and encode
 > the name in gdb?), and then simplify the test by just checking for that file.
 > 
 > If we can agree on this approach, I'll add NEWS and docs.

I believe I've addressed Eli's comments,
[ref: https://sourceware.org/ml/gdb-patches/2013-12/msg00969.html]
and I didn't see any other discussion, so here's the patch.

2014-03-06  Doug Evans  <dje@google.com>

	New option -B.
	* NEWS: Mention it.
	* main.c (maybe_run_from_builddir): New static global.
	(get_build_data_directory): New function.
	(captured_main): New enum value OPT_BATCH_SILENT.  Use it instead of
	'B' for --batch-silent.  Recognize and handle -B option.

	doc/
	* gdb.texinfo (Mode Options): Document -B.

	testsuite/
	* gdb.base/dash-b.exp: New file.

diff --git a/gdb/NEWS b/gdb/NEWS
index 2a384ba..a1561e7 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -3,6 +3,11 @@
 
 *** Changes since GDB 7.7
 
+* New command line options:
+
+-B  Indicates GDB may have been run from its build directory, and GDB
+    should first look for its ancillary files there.
+
 * Guile scripting
 
   GDB now has support for scripting using Guile.  Whether this is
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index de5ac63..ab6a643 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -1169,6 +1169,18 @@ Run @value{GDBN} using @var{directory} as its data directory.
 The data directory is where @value{GDBN} searches for its
 auxiliary files.  @xref{Data Files}.
 
+@item -B
+@cindex @code{-B}
+This option tells @value{GDBN} it may have been run from its build directory,
+and it should first look for its auxiliary files there.  @xref{Data Files}.
+If @value{GDBN} cannot determine it has been run from its build directory,
+then it will expect to find its auxiliary files in their installed
+location as specified by the @code{--prefix} option when @value{GDBN} was
+configured.
+
+This option is ignored if the data directory has been explicitly specified
+with @code{--data-directory}.
+
 @item -fullname
 @itemx -f
 @cindex @code{--fullname}
diff --git a/gdb/main.c b/gdb/main.c
index 59015f5..536f9b7 100644
--- a/gdb/main.c
+++ b/gdb/main.c
@@ -57,6 +57,9 @@ int xdb_commands = 0;
 /* Whether dbx commands will be handled.  */
 int dbx_commands = 0;
 
+/* Whether GDB may have been run from the build directory.  */
+static int maybe_run_from_builddir = 0;
+
 /* System root path, used to find libraries etc.  */
 char *gdb_sysroot = 0;
 
@@ -160,6 +163,60 @@ relocate_gdb_directory (const char *initial, int flag)
   return dir;
 }
 
+/* Return the path of the data directory in the build tree if we can
+   reasonably determine that gdb was run from the build directory.
+   Otherwise return NULL.
+   Space for the result is obtained with malloc, caller must free.
+
+   We say "reasonably" because gdb *could* be run from a place that *looks*
+   like the build directory, and we want to avoid false positives as much as
+   is reasonably possible.  This code is only used if the user passes -B to
+   gdb so our tests needn't be *perfect*.
+
+   The test is done by seeing if various files that we expect to find in a
+   build directory exist.  There are a few constraints on our choices:
+
+   1) We don't test for object files so that we don't have to deal with the
+      complexity of different suffixes (e.g., .o vs .obj).
+   2) We can't (easily) test for files that only exist for a particular
+      configuration.
+
+   In the end we choose three files from the data-directory since it's the
+   data-directory that we need to find:
+   1) Makefile - only exists in build tree,
+   2) stamp-syscalls - only exists in build tree that has been built,
+   3) syscalls/amd64-linux.xml - gdb needs this
+      (installed regardless of platform so it doesn't matter if the current
+      platform is not amd64-linux).  */
+
+static char *
+get_build_data_directory (void)
+{
+  char *gdb_dirname = ldirname (gdb_program_name);
+  char *full_gdb_dirname = gdb_realpath (gdb_dirname);
+  char *datadir = concat (full_gdb_dirname, SLASH_STRING "data-directory",
+			  NULL);
+  char *test_file1 = concat (datadir, SLASH_STRING, "Makefile", NULL);
+  char *test_file2 = concat (datadir, SLASH_STRING, "stamp-syscalls", NULL);
+  char *test_file3 = concat (datadir, SLASH_STRING, "syscalls",
+			     SLASH_STRING, "amd64-linux.xml", NULL);
+  int builddir_found;
+
+  builddir_found = (access (test_file1, R_OK) == 0
+		    && access (test_file2, R_OK) == 0
+		    && access (test_file3, R_OK) == 0);
+  xfree (gdb_dirname);
+  xfree (full_gdb_dirname);
+  xfree (test_file1);
+  xfree (test_file2);
+  xfree (test_file3);
+
+  if (builddir_found)
+    return datadir;
+  xfree (datadir);
+  return NULL;
+}
+
 /* Compute the locations of init files that GDB should source and
    return them in SYSTEM_GDBINIT, HOME_GDBINIT, LOCAL_GDBINIT.  If
    there is no system gdbinit (resp. home gdbinit and local gdbinit)
@@ -461,7 +518,8 @@ captured_main (void *data)
       OPT_NOWINDOWS,
       OPT_WINDOWS,
       OPT_IX,
-      OPT_IEX
+      OPT_IEX,
+      OPT_BATCH_SILENT
     };
     static struct option long_options[] =
     {
@@ -476,7 +534,7 @@ captured_main (void *data)
       {"nh", no_argument, &inhibit_home_gdbinit, 1},
       {"nx", no_argument, &inhibit_gdbinit, 1},
       {"n", no_argument, &inhibit_gdbinit, 1},
-      {"batch-silent", no_argument, 0, 'B'},
+      {"batch-silent", no_argument, 0, OPT_BATCH_SILENT},
       {"batch", no_argument, &batch_flag, 1},
 
     /* This is a synonym for "--annotate=1".  --annotate is now
@@ -530,6 +588,7 @@ captured_main (void *data)
       {"args", no_argument, &set_args, 1},
       {"l", required_argument, 0, 'l'},
       {"return-child-result", no_argument, &return_child_result, 1},
+      {"B", no_argument, &maybe_run_from_builddir, 1},
       {0, no_argument, 0, 0}
     };
 
@@ -636,7 +695,7 @@ captured_main (void *data)
 	      VEC_safe_push (cmdarg_s, cmdarg_vec, &cmdarg);
 	    }
 	    break;
-	  case 'B':
+	  case OPT_BATCH_SILENT:
 	    batch_flag = batch_silent = 1;
 	    gdb_stdout = ui_file_new();
 	    break;
@@ -742,6 +801,20 @@ captured_main (void *data)
       quiet = 1;
   }
 
+  /* If -B was provided and --data-directory was not, then see if we have been
+     run from the build directory and if so use the data-directory there.  */
+  if (maybe_run_from_builddir && !gdb_datadir_provided)
+    {
+      char *builddir = get_build_data_directory ();
+
+      if (builddir != NULL)
+	{
+	  xfree (gdb_datadir);
+	  gdb_datadir = builddir;
+	  gdb_datadir_provided = 1;
+	}
+    }
+
   /* Initialize all files.  Give the interpreter a chance to take
      control of the console via the deprecated_init_ui_hook ().  */
   gdb_init (gdb_program_name);
diff --git a/gdb/testsuite/gdb.base/dash-b.exp b/gdb/testsuite/gdb.base/dash-b.exp
new file mode 100644
index 0000000..24ac6f9
--- /dev/null
+++ b/gdb/testsuite/gdb.base/dash-b.exp
@@ -0,0 +1,34 @@
+# Copyright 2014 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 <http://www.gnu.org/licenses/>.  */
+
+# Test the -B option.
+# The test here needs to handle the case where gdb has already been installed,
+# in which case if -B isn't working probably the test might still pass whereas
+# it should fail.  The way we test this is to verify the value of the
+# "data-directory" parameter after gdb has started.
+
+set save_INTERNAL_GDBFLAGS $INTERNAL_GDBFLAGS
+set INTERNAL_GDBFLAGS "-nw -nx -B"
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+
+set normalized_objdir [file normalize $objdir]
+verbose -log "normalized objdir: $normalized_objdir"
+gdb_test "show data-directory" \
+    "GDB's data directory is \"[file dirname $normalized_objdir]/data-directory\"\."
+
+set INTERNAL_GDBFLAGS $save_INTERNAL_GDBFLAGS


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]