+2021-04-15 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ PR cli/25956
+ * NEWS: Mention new early init files and command line options.
+ * config.in: Regenerate.
+ * configure: Regenerate.
+ * configure.ac: Define GDBEARLYINIT.
+ * main.c (get_earlyinit_files): New function.
+ (enum cmdarg_kind): Add CMDARG_EARLYINIT_FILE and
+ CMDARG_EARLYINIT_COMMAND.
+ (captured_main_1): Add support for new command line flags, and for
+ processing startup files.
+ (print_gdb_help): Include startup files in the output.
+
2021-04-15 Andrew Burgess <andrew.burgess@embecosm.com>
* main.c (relocate_gdbinit_path_maybe_in_datadir): Rename to...
the use of the GNAT encoding (based on information added to the type's
name following a GNAT-specific format).
+* GDB will now load and process commands from ~/.config/gdb/gdbearlyinit
+ or ~/.gdbearlyinit if these files are present. These files are
+ processed earlier than any of the other initialization files and
+ can affect parts of GDB's startup that previously had already been
+ completed before the initialization files were read, for example
+ styling of the initial GDB greeting.
+
+* GDB now has two new options "--early-init-command" and
+ "--early-init-eval-command" with corresponding short options "-eix"
+ and "-eiex" that allow options (that would normally appear in a
+ gdbearlyinit file) to be passed on the command line.
+
* New commands
set debug event-loop
language is requested. */
#undef ENABLE_NLS
+/* The .gdbearlyinit filename. */
+#undef GDBEARLYINIT
+
/* The .gdbinit filename. */
#undef GDBINIT
+cat >>confdefs.h <<_ACEOF
+#define GDBEARLYINIT ".gdbearlyinit"
+_ACEOF
+
+
+
# Support for --with-sysroot is a copy of GDB_AC_WITH_DIR,
# except that the argument to --with-sysroot is optional.
# --with-sysroot (or --with-sysroot=yes) sets the default sysroot path.
esac
AC_DEFINE_UNQUOTED(GDBINIT,"$gdbinit",[The .gdbinit filename.])
+dnl Set the host's .gdbearlyinit filename
+AC_DEFINE_UNQUOTED(GDBEARLYINIT,".gdbearlyinit",[The .gdbearlyinit filename.])
+
dnl Handle optional features that can be enabled.
# Support for --with-sysroot is a copy of GDB_AC_WITH_DIR,
+2021-04-15 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ PR cli/25956
+ * gdb.texinfo (File Options): Mention new command line options.
+ (Startup): Discuss when early init files are processed.
+ (Initialization Files): Add description of early init files.
+ (Output Styling): Update description of 'version' style.
+ (gdb man): Mention early init files.
+
2021-04-14 Andrew Burgess <andrew.burgess@embecosm.com>
* gdb.texinfo (GDB/MI Miscellaneous Commands): Add missing
after loading gdbinit files).
@xref{Startup}.
+@item -early-init-command @var{file}
+@itemx -eix @var{file}
+@cindex @code{--early-init-command}
+@cindex @code{-eix}
+Execute commands from @var{file} very early in the initialization
+process, before any output is produced. @xref{Startup}.
+
+@item -early-init-eval-command @var{command}
+@itemx -eiex @var{command}
+@cindex @code{--early-init-eval-command}
+@cindex @code{-eiex}
+Execute a single @value{GDBN} command very early in the initialization
+process, before any output is produced.
+
@item -directory @var{directory}
@itemx -d @var{directory}
@cindex @code{--directory}
Here's the description of what @value{GDBN} does during session startup:
@enumerate
+
+@item
+Performs minimal setup required to initialize basic internal state.
+
+@item
+@cindex early initialization file
+Reads commands from the early initialization file (if any) in your
+home directory. Only a restricted set of commands can be placed into
+an early initialization file, see @ref{Initialization Files}, for
+details.
+
+@item
+Executes commands and command files specified by the @samp{-eiex} and
+@samp{-eix} command line options in their specified order. Only a
+restricted set of commands can be used with @samp{-eiex} and
+@samp{eix}, see @ref{Initialization Files}, for details.
+
@item
Sets up the command interpreter as specified by the command line
(@pxref{Mode Options, interpreter}).
startup, in the order they will be loaded, you can use @kbd{gdb
--help}.
+@cindex early initialization
+The @dfn{early initialization} file is loaded very early in
+@value{GDBN}'s initialization process, before the interpreter
+(@pxref{Interpreters}) has been initialized, and before the default
+target (@pxref{Targets}) is initialized. Only @code{set} or
+@code{source} commands should be placed into an early initialization
+file, and the only @code{set} commands that can be used are those that
+control how @value{GDBN} starts up.
+
+Commands that can be placed into an early initialization file will be
+documented as such throughout this manual. Any command that is not
+documented as being suitable for an early initialization file should
+instead be placed into a general initialization file. Command files
+passed to @code{--early-init-command} or @code{-eix} are also early
+initialization files, with the same command restrictions. Only
+commands that can appear in an early initialization file should be
+passed to @code{--early-init-eval-command} or @code{-eiex}.
+
+@cindex general initialization
+In contrast, the @dfn{general initialization} files are processed
+later, after @value{GDBN} has finished its own internal initialization
+process, any valid command can be used in these files.
+
+@cindex initialization file
+Throughout the rest of this document the term @dfn{initialization
+file} refers to one of the general initialization files, not the early
+initialization file. Any discussion of the early initialization file
+will specifically mention that it is the early initialization file
+being discussed.
+
As the system wide and home directory initialization files are
processed before most command line options, changes to settings
(e.g. @samp{set complaints}) can affect subsequent processing of
command line options and operands.
-The following sections describe where @value{GDBN} looks for the
-initialization and the order that the files are searched for.
+The following sections describe where @value{GDBN} looks for the early
+initialization and initialization files, and the order that the files
+are searched for.
+
+@subsubsection Home directory early initialization files
+
+@value{GDBN} initially looks for an early initialization file in the
+users home directory@footnote{On DOS/Windows systems, the home
+directory is the one pointed to by the @code{HOME} environment
+variable.}. There are a number of locations that @value{GDBN} will
+search in the home directory, these locations are searched in order
+and @value{GDBN} will load the first file that it finds, and
+subsequent locations will not be checked.
+
+On non-macOS hosts the locations searched are:
+@itemize
+@item
+The file @file{gdb/gdbearlyinit} within the directory pointed to by the
+environment variable @env{XDG_CONFIG_HOME}, if it is defined.
+@item
+The file @file{.config/gdb/gdbearlyinit} within the directory pointed to
+by the environment variable @env{HOME}, if it is defined.
+@item
+The file @file{.gdbearlyinit} within the directory pointed to by the
+environment variable @env{HOME}, if it is defined.
+@end itemize
+
+By contrast, on macOS hosts the locations searched are:
+@itemize
+@item
+The file @file{Library/Preferences/gdb/gdbearlyinit} within the
+directory pointed to by the environment variable @env{HOME}, if it is
+defined.
+@item
+The file @file{.gdbearlyinit} within the directory pointed to by the
+environment variable @env{HOME}, if it is defined.
+@end itemize
+
+It is possible to prevent the home directory early initialization file
+from being loaded using the @samp{-nx} or @samp{-nh} command line
+options, @pxref{Mode Options,,Choosing Modes}.
@anchor{System Wide Init Files}
@subsubsection System wide initialization files
intensity. The version number is displayed in two places, the output
of @command{show version}, and when @value{GDBN} starts up.
-Currently the version string displayed at startup is printed before
-@value{GDBN} has parsed any command line options, or parsed any
-command files, so there is currently no way to control the styling of
-this string. However, @value{GDBN}'s @code{--quiet} command line option
-can be used to disable printing of the version string on startup.
+In order to control how @value{GDBN} styles the version number at
+startup, add the @code{set style version} family of commands to the
+early initialization command file (@pxref{Initialization
+Files}).
@item title
Control the styling of titles. These are managed with the
Add @var{directory} to the path to search for source files.
@item -nh
-Do not execute commands from @file{~/.config/gdb/gdbinit} or
-@file{~/.gdbinit}.
+Do not execute commands from @file{~/.config/gdb/gdbinit},
+@file{~/.gdbinit}, @file{~/.config/gdb/gdbearlyinit}, or
+@file{~/.gdbearlyinit}
@item -nx
@itemx -n
-Do not execute commands from any @file{.gdbinit} initialization files.
+Do not execute commands from any @file{.gdbinit} or
+@file{.gdbearlyinit} initialization files.
@item -quiet
@itemx -q
*local_gdbinit = init_files->local_file ();
}
+/* Compute the location of the early init file GDB should source and return
+ it in HOME_GDBEARLYINIT. HOME_GDBEARLYINIT could be returned as an
+ empty string if there is no early init file found. */
+
+static void
+get_earlyinit_files (std::string *home_gdbearlyinit)
+{
+ /* Cache the file lookup object so we only actually search for the files
+ once. */
+ static gdb::optional<gdb_initfile_finder> init_files;
+ if (!init_files.has_value ())
+ init_files.emplace (GDBEARLYINIT, nullptr, false, nullptr, false, false);
+
+ *home_gdbearlyinit = init_files->home_file ();
+}
+
/* Start up the event loop. This is the entry point to the event loop
from the command loop. */
CMDARG_INIT_FILE,
/* Option type -iex. */
- CMDARG_INIT_COMMAND
+ CMDARG_INIT_COMMAND,
+
+ /* Option type -sx. */
+ CMDARG_EARLYINIT_FILE,
+
+ /* Option type -sex. */
+ CMDARG_EARLYINIT_COMMAND
};
/* Arguments of --command option and its counterpart. */
OPT_WINDOWS,
OPT_IX,
OPT_IEX,
+ OPT_EIX,
+ OPT_EIEX,
OPT_READNOW,
OPT_READNEVER
};
{"init-eval-command", required_argument, 0, OPT_IEX},
{"ix", required_argument, 0, OPT_IX},
{"iex", required_argument, 0, OPT_IEX},
+ {"early-init-command", required_argument, 0, OPT_EIX},
+ {"early-init-eval-command", required_argument, 0, OPT_EIEX},
+ {"eix", required_argument, 0, OPT_EIX},
+ {"eiex", required_argument, 0, OPT_EIEX},
#ifdef GDBTK
{"tclcommand", required_argument, 0, 'z'},
{"enable-external-editor", no_argument, 0, 'y'},
case OPT_IEX:
cmdarg_vec.emplace_back (CMDARG_INIT_COMMAND, optarg);
break;
+ case OPT_EIX:
+ cmdarg_vec.emplace_back (CMDARG_EARLYINIT_FILE, optarg);
+ break;
+ case OPT_EIEX:
+ cmdarg_vec.emplace_back (CMDARG_EARLYINIT_COMMAND, optarg);
+ break;
case 'B':
batch_flag = batch_silent = 1;
gdb_stdout = new null_file ();
/* Initialize all files. */
gdb_init (gdb_program_name);
+ /* Process early init files and early init options from the command line. */
+ if (!inhibit_gdbinit)
+ {
+ std::string home_gdbearlyinit;
+ get_earlyinit_files (&home_gdbearlyinit);
+ if (!home_gdbearlyinit.empty () && !inhibit_home_gdbinit)
+ ret = catch_command_errors (source_script,
+ home_gdbearlyinit.c_str (), 0);
+ }
+ execute_cmdargs (&cmdarg_vec, CMDARG_EARLYINIT_FILE,
+ CMDARG_EARLYINIT_COMMAND, &ret);
+
/* Now that gdb_init has created the initial inferior, we're in
position to set args for that inferior. */
if (set_args)
std::vector<std::string> system_gdbinit;
std::string home_gdbinit;
std::string local_gdbinit;
+ std::string home_gdbearlyinit;
get_init_files (&system_gdbinit, &home_gdbinit, &local_gdbinit);
+ get_earlyinit_files (&home_gdbearlyinit);
/* Note: The options in the list below are only approximately sorted
in the alphabetical order, so as to group closely related options
Set GDB's data-directory to DIR.\n\
"), stream);
fputs_unfiltered (_("\n\
+At startup, GDB reads the following early init files and executes their\n\
+commands:\n\
+"), stream);
+ if (!home_gdbearlyinit.empty ())
+ fprintf_unfiltered (stream, _("\
+ * user-specific early init file: %s\n\
+"), home_gdbearlyinit.c_str ());
+ if (home_gdbearlyinit.empty ())
+ fprintf_unfiltered (stream, _("\
+ None found.\n"));
+ fputs_unfiltered (_("\n\
At startup, GDB reads the following init files and executes their commands:\n\
"), stream);
if (!system_gdbinit.empty ())
+2021-04-15 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ PR cli/25956
+ * gdb.base/early-init-file.c: New file.
+ * gdb.base/early-init-file.exp: New file.
+ * lib/gdb-utils.exp (style): Handle style 'none'.
+
2021-04-14 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
* gdb.dwarf2/dw2-inline-with-lexical-scope.exp: Use
--- /dev/null
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2021 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/>. */
+
+int
+main ()
+{
+ return 0;
+}
--- /dev/null
+# Copyright 2021 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 GDB's early init file mechanism.
+
+standard_testfile
+
+# Compile the test executable.
+if {[build_executable "failed to build" $testfile $srcfile]} {
+ return -1
+}
+
+# Start gdb and ensure that the initial version string is styled in
+# STYLE, use MESSAGE as the name of the test.
+proc check_gdb_startup_version_string { style { message "" } } {
+ if { $message == "" } {
+ set message "check startup version string has style $style"
+ }
+
+ gdb_exit
+ gdb_spawn
+ set vers [style "GNU gdb.*" $style]
+ gdb_test "" "^${vers}.*" $message
+}
+
+# Return a list containing two directory paths for newly created home
+# directories.
+#
+# The first directory is a HOME style home directory, it contains a
+# .gdbearlyinit file containing CONTENT.
+#
+# The second directory is an XDG_CONFIG_HOME style home directory, it
+# contains a sub-directory gdb/, inside which is a file gdbearlyinit
+# that also contains CONTENT.
+#
+# The PREFIX is used in both directory names and should be unique for
+# each call to this function.
+proc setup_home_directories { prefix content } {
+ set home_dir [standard_output_file "${prefix}-home"]
+ set xdg_home_dir [standard_output_file "${prefix}-xdg"]
+
+ file mkdir $home_dir
+ file mkdir "$xdg_home_dir/gdb"
+
+ # Write the content into the HOME directory.
+ set fd [open "$home_dir/.gdbearlyinit" w]
+ puts $fd $content
+ close $fd
+
+ # Copy this from the HOME directory into the XDG_CONFIG_HOME
+ # directory.
+ file copy -force "$home_dir/.gdbearlyinit" "$xdg_home_dir/gdb/gdbearlyinit"
+
+ return [list $home_dir $xdg_home_dir]
+}
+
+save_vars { env(TERM) } {
+ # We need an ANSI-capable terminal to get the output.
+ setenv TERM ansi
+
+ # Start GDB and confirm that the version string is styled.
+ check_gdb_startup_version_string version
+
+ # Create an empty directory we can use as HOME for some of the
+ # tests below. When we set XDG_CONFIG_HOME we still need to point
+ # HOME at something otherwise GDB complains that it doesn't know
+ # where to create the index cache.
+ set empty_home_dir [standard_output_file fake-empty-home]
+
+ # Create two directories to use for the style setting test.
+ set dirs [setup_home_directories "style" \
+ [multi_line_input \
+ "set style version foreground none" \
+ "set style version background none" \
+ "set style version intensity normal"]]
+ set home_dir [lindex $dirs 0]
+ set xdg_home_dir [lindex $dirs 1]
+
+ # Now arrange to use the fake home directory early init file.
+ save_vars { INTERNAL_GDBFLAGS env(HOME) env(XDG_CONFIG_HOME) } {
+ set INTERNAL_GDBFLAGS [string map {"-nx" ""} $INTERNAL_GDBFLAGS]
+
+ # Now test GDB when using the HOME directory.
+ set env(HOME) $home_dir
+ unset -nocomplain env(XDG_CONFIG_HOME)
+ check_gdb_startup_version_string none \
+ "check version string is unstyled using HOME"
+
+ # Now test using the XDG_CONFIG_HOME folder. We still need to
+ # have a HOME directory set otherwise GDB will issue an error
+ # about not knowing where to place the index cache.
+ set env(XDG_CONFIG_HOME) $xdg_home_dir
+ set env(HOME) $empty_home_dir
+ check_gdb_startup_version_string none \
+ "check version string is unstyled using XDG_CONFIG_HOME"
+ }
+}
address { set style 34 }
metadata { set style 2 }
version { set style "35;1" }
+ none { return $str }
}
return "\033\\\[${style}m${str}\033\\\[m"
}