diff options
-rw-r--r-- | gdb/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/NEWS | 6 | ||||
-rw-r--r-- | gdb/auto-load.c | 27 | ||||
-rw-r--r-- | gdb/doc/ChangeLog | 9 | ||||
-rw-r--r-- | gdb/doc/gdb.texinfo | 207 | ||||
-rw-r--r-- | gdb/main.c | 13 | ||||
-rw-r--r-- | gdbsupport/pathstuff.cc | 49 | ||||
-rw-r--r-- | gdbsupport/pathstuff.h | 23 |
8 files changed, 246 insertions, 93 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 4528b85..18b7fb0 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2020-11-02 Andrew Burgess <andrew.burgess@embecosm.com> + + * NEWS: Mention changes to config file search path. + * main.c + 2020-11-02 Tom Tromey <tromey@adacore.com> * python/python.c: Consolidate two HAVE_PYTHON blocks. @@ -15,6 +15,12 @@ * GDB now supports core file debugging for x86_64 Cygwin programs. +* GDB will now look for the .gdbinit file in a config directory before + looking for ~/.gdbinit. The file is searched for in the following + locations: $XDG_CONFIG_HOME/gdb/gdbinit, $HOME/.config/gdb/gdbinit, + $HOME/.gdbinit. On Apple hosts the search order is instead: + $HOME/Library/Preferences/gdb/gdbinit, $HOME/.gdbinit. + * New commands set debug event-loop diff --git a/gdb/auto-load.c b/gdb/auto-load.c index 71f0ecd..79011db 100644 --- a/gdb/auto-load.c +++ b/gdb/auto-load.c @@ -498,11 +498,26 @@ file_is_auto_load_safe (const char *filename, const char *debug_fmt, ...) if (!advice_printed) { - const char *homedir = getenv ("HOME"); - - if (homedir == NULL) - homedir = "$HOME"; - std::string homeinit = string_printf ("%s/%s", homedir, GDBINIT); + /* Find the existing home directory config file. */ + struct stat buf; + std::string home_config = find_gdb_home_config_file (GDBINIT, &buf); + if (home_config.empty ()) + { + /* The user doesn't have an existing home directory config file, + so we should suggest a suitable path for them to use. */ + std::string config_dir_file + = get_standard_config_filename (GDBINIT); + if (!config_dir_file.empty ()) + home_config = config_dir_file; + else + { + const char *homedir = getenv ("HOME"); + if (homedir == nullptr) + homedir = "$HOME"; + home_config = (std::string (homedir) + SLASH_STRING + + std::string (GDBINIT)); + } + } printf_filtered (_("\ To enable execution of this file add\n\ @@ -515,7 +530,7 @@ 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.get (), - homeinit.c_str (), homeinit.c_str ()); + home_config.c_str (), home_config.c_str ()); advice_printed = 1; } diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index b8a4429..a57a36a 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,12 @@ +2020-11-02 Andrew Burgess <andrew.burgess@embecosm.com> + + * gdb.texinfo (Mode Options): Descriptions of initialization files + has been moved to 'Initialization Files'. + (Startup): Likewise. + (Initialization Files): New node. + (gdb man): Update to mention alternative file paths. + (gdbinit man): Likewise. + 2020-10-27 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * gdb.texinfo (Set Breaks): Document the '-force-condition' flag diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index d779d4a..5270156 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -937,6 +937,7 @@ in sequential order. The order makes a difference when the * File Options:: Choosing files * Mode Options:: Choosing modes * Startup:: What @value{GDBN} does during startup +* Initialization Files:: Initialization Files @end menu @node File Options @@ -1077,47 +1078,16 @@ batch mode or quiet mode. @itemx -n @cindex @code{--nx} @cindex @code{-n} -Do not execute commands found in any initialization file. -There are three init files, loaded in the following order: - -@table @code -@item @file{system.gdbinit} -This is the system-wide init file. -Its location is specified with the @code{--with-system-gdbinit} -configure option (@pxref{System-wide configuration}). -It is loaded first when @value{GDBN} starts, before command line options -have been processed. -@item @file{system.gdbinit.d} -This is the system-wide init directory. -Its location is specified with the @code{--with-system-gdbinit-dir} -configure option (@pxref{System-wide configuration}). -Files in this directory are loaded in alphabetical order immediately after -system.gdbinit (if enabled) when @value{GDBN} starts, before command line -options have been processed. Files need to have a recognized scripting -language extension (@file{.py}/@file{.scm}) or be named with a @file{.gdb} -extension to be interpreted as regular @value{GDBN} commands. @value{GDBN} -will not recurse into any subdirectories of this directory. -@item @file{~/.gdbinit} -This is the init file in your home directory. -It is loaded next, after @file{system.gdbinit}, and before -command options have been processed. -@item @file{./.gdbinit} -This is the init file in the current directory. -It is loaded last, after command line options other than @code{-x} and -@code{-ex} have been processed. Command line options @code{-x} and -@code{-ex} are processed last, after @file{./.gdbinit} has been loaded. -@end table - -For further documentation on startup processing, @xref{Startup}. -For documentation on how to write command files, -@xref{Command Files,,Command Files}. +Do not execute commands found in any initialization files +(@pxref{Initialization Files}). @anchor{-nh} @item -nh @cindex @code{--nh} -Do not execute commands found in @file{~/.gdbinit}, the init file -in your home directory. -@xref{Startup}. +Do not execute commands found in any home directory initialization +file (@pxref{Initialization Files,,Home directory initialization +file}). The system wide and current directory initialization files +are still loaded. @item -quiet @itemx -silent @@ -1327,20 +1297,13 @@ Sets up the command interpreter as specified by the command line @item @cindex init file -Reads the system-wide @dfn{init file} (if @option{--with-system-gdbinit} was -used when building @value{GDBN}; @pxref{System-wide configuration, - ,System-wide configuration and settings}) and the files in the system-wide -gdbinit directory (if @option{--with-system-gdbinit-dir} was used) and executes -all the commands in those files. The files need to be named with a @file{.gdb} -extension to be interpreted as @value{GDBN} commands, or they can be written -in a supported scripting language with an appropriate file extension. +Reads the system wide initialization file and the files from the +system wide initialization directory, @pxref{System Wide Init Files}. -@anchor{Home Directory Init File} @item -Reads the init file (if any) in your home directory@footnote{On -DOS/Windows systems, the home directory is the one pointed to by the -@code{HOME} environment variable.} and executes all the commands in -that file. +Reads the initialization file (if any) in your home directory and +executes all the commands in that file, @pxref{Home Directory Init +File}. @anchor{Option -init-eval-command} @item @@ -1353,16 +1316,16 @@ gets loaded. @item Processes command line options and operands. -@anchor{Init File in the Current Directory during Startup} @item -Reads and executes the commands from init file (if any) in the current -working directory as long as @samp{set auto-load local-gdbinit} is set to -@samp{on} (@pxref{Init File in the Current Directory}). -This is only done if the current directory is -different from your home directory. Thus, you can have more than one -init file, one generic in your home directory, and another, specific -to the program you are debugging, in the directory where you invoke -@value{GDBN}. +Reads and executes the commands from the initialization file (if any) +in the current working directory as long as @samp{set auto-load +local-gdbinit} is set to @samp{on} (@pxref{Init File in the Current +Directory}). This is only done if the current directory is different +from your home directory. Thus, you can have more than one init file, +one generic in your home directory, and another, specific to the +program you are debugging, in the directory where you invoke +@value{GDBN}. @xref{Init File in the Current Directory during +Startup}. @item If the command line specified a program to debug, or a process to @@ -1391,26 +1354,115 @@ Reads the command history recorded in the @dfn{history file}. files where @value{GDBN} records it. @end enumerate -Init files use the same syntax as @dfn{command files} (@pxref{Command -Files}) and are processed by @value{GDBN} in the same way. The init -file in your home directory can set options (such as @samp{set -complaints}) that affect subsequent processing of command line options -and operands. Init files are not executed if you use the @samp{-nx} -option (@pxref{Mode Options, ,Choosing Modes}). +@node Initialization Files +@subsection Initialization Files +@cindex init file name -To display the list of init files loaded by gdb at startup, you -can use @kbd{gdb --help}. +During startup (@pxref{Startup}) @value{GDBN} will execute commands +from several initialization files. These initialization files use the +same syntax as @dfn{command files} (@pxref{Command Files}) and are +processed by @value{GDBN} in the same way. -@cindex init file name +To display the list of initialization files loaded by @value{GDBN} at +startup, in the order they will be loaded, you can use @kbd{gdb +--help}. + +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. + +@anchor{System Wide Init Files} +@subsubsection System wide initialization files + +There are two locations that are searched for system wide +initialization files. Both of these locations are always checked: + +@table @code + +@item @file{system.gdbinit} +This is a single system-wide initialization file. Its location is +specified with the @code{--with-system-gdbinit} configure option +(@pxref{System-wide configuration}). It is loaded first when +@value{GDBN} starts, before command line options have been processed. + +@item @file{system.gdbinit.d} +This is the system-wide initialization directory. Its location is +specified with the @code{--with-system-gdbinit-dir} configure option +(@pxref{System-wide configuration}). Files in this directory are +loaded in alphabetical order immediately after @file{system.gdbinit} +(if enabled) when @value{GDBN} starts, before command line options +have been processed. Files need to have a recognized scripting +language extension (@file{.py}/@file{.scm}) or be named with a +@file{.gdb} extension to be interpreted as regular @value{GDBN} +commands. @value{GDBN} will not recurse into any subdirectories of +this directory. + +@end table + +It is possible to prevent the system wide initialization files from +being loaded using the @samp{-nx} command line option, @pxref{Mode +Options,,Choosing Modes}. + +@anchor{Home Directory Init File} +@subsubsection Home directory initialization file +@cindex @file{gdbinit} @cindex @file{.gdbinit} @cindex @file{gdb.ini} -The @value{GDBN} init files are normally called @file{.gdbinit}. -The DJGPP port of @value{GDBN} uses the name @file{gdb.ini}, due to -the limitations of file names imposed by DOS filesystems. The Windows -port of @value{GDBN} uses the standard name, but if it finds a -@file{gdb.ini} file in your home directory, it warns you about that -and suggests to rename the file to the standard name. +After loading the system wide initialization files @value{GDBN} will +look for an 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-Apple hosts the locations searched are: +@table @file +@item $XDG_CONFIG_HOME/gdb/gdbinit +@item $HOME/.config/gdb/gdbinit +@item $HOME/.gdbinit +@end table + +While on Apple hosts the locations searched are: +@table @file +@item $HOME/Library/Preferences/gdb/gdbinit +@item $HOME/.gdbinit +@end table + +It is possible to prevent the home directory initialization file from +being loaded using the @samp{-nx} or @samp{-nh} command line options, +@pxref{Mode Options,,Choosing Modes}. + +The DJGPP port of @value{GDBN} uses the name @file{gdb.ini} instead of +@file{.gdbinit} or @file{gdbinit}, due to the limitations of file +names imposed by DOS filesystems. The Windows port of @value{GDBN} +uses the standard name, but if it finds a @file{gdb.ini} file in your +home directory, it warns you about that and suggests to rename the +file to the standard name. + +@anchor{Init File in the Current Directory during Startup} +@subsubsection Local directory initialization file + +@value{GDBN} will check the current directory for a file called +@file{.gdbinit}. It is loaded last, after command line options +other than @samp{-x} and @samp{-ex} have been processed. The command +line options @samp{-x} and @samp{-ex} are processed last, after +@file{.gdbinit} has been loaded, @pxref{File Options,,Choosing +Files}. + +If the file in the current directory was already loaded as the home +directory initialization file then it will not be loaded a second +time. + +It is possible to prevent the local directory initialization file from +being loaded using the @samp{-nx} command line option, @pxref{Mode +Options,,Choosing Modes}. @node Quitting GDB @section Quitting @value{GDBN} @@ -46470,7 +46522,8 @@ Execute given @value{GDBN} @var{command}. Add @var{directory} to the path to search for source files. @item -nh -Do not execute commands from @file{~/.gdbinit}. +Do not execute commands from @file{~/.config/gdb/gdbinit} or +@file{~/.gdbinit}. @item -nx @itemx -n @@ -46895,6 +46948,8 @@ Richard M. Stallman and Roland H. Pesch, July 1991. @value{SYSTEM_GDBINIT_DIR}/* @end ifset +~/.config/gdb/gdbinit + ~/.gdbinit ./.gdbinit @@ -46954,11 +47009,11 @@ the @value{GDBN} manual in node @code{System-wide configuration} @ref{System-wide configuration}. @end ifclear -@item ~/.gdbinit +@item @file{~/.config/gdb/gdbinit} or @file{~/.gdbinit} User initialization file. It is executed unless user specified @value{GDBN} options @code{-nx}, @code{-n} or @code{-nh}. -@item ./.gdbinit +@item @file{.gdbinit} Initialization file for current directory. It may need to be enabled with @value{GDBN} security command @code{set auto-load local-gdbinit}. See more in @@ -301,8 +301,6 @@ get_init_files (std::vector<std::string> *system_gdbinit, } } - const char *homedir = getenv ("HOME"); - /* If the .gdbinit file in the current directory is the same as the $HOME/.gdbinit file, it should not be sourced. homebuf and cwdbuf are used in that purpose. Make sure that the stats @@ -312,14 +310,7 @@ get_init_files (std::vector<std::string> *system_gdbinit, memset (&homebuf, 0, sizeof (struct stat)); memset (&cwdbuf, 0, sizeof (struct stat)); - if (homedir) - { - homeinit = std::string (homedir) + SLASH_STRING + GDBINIT; - if (stat (homeinit.c_str (), &homebuf) != 0) - { - homeinit = ""; - } - } + homeinit = find_gdb_home_config_file (GDBINIT, &homebuf); if (stat (GDBINIT, &cwdbuf) == 0) { @@ -328,7 +319,7 @@ get_init_files (std::vector<std::string> *system_gdbinit, sizeof (struct stat))) localinit = GDBINIT; } - + initialized = 1; } diff --git a/gdbsupport/pathstuff.cc b/gdbsupport/pathstuff.cc index 9fb5e5c..a52e53b 100644 --- a/gdbsupport/pathstuff.cc +++ b/gdbsupport/pathstuff.cc @@ -23,6 +23,10 @@ #include "filenames.h" #include "gdb_tilde_expand.h" +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + #ifdef USE_WIN32API #include <windows.h> #endif @@ -298,6 +302,51 @@ get_standard_config_dir () return {}; } +/* See pathstuff.h. */ + +std::string +get_standard_config_filename (const char *filename) +{ + std::string config_dir = get_standard_config_dir (); + if (config_dir != "") + { + const char *tmp = (*filename == '.') ? (filename + 1) : filename; + std::string path = config_dir + SLASH_STRING + std::string (tmp); + return path; + } + + return {}; +} + +/* See pathstuff.h. */ + +std::string +find_gdb_home_config_file (const char *name, struct stat *buf) +{ + gdb_assert (name != nullptr); + gdb_assert (*name != '\0'); + + std::string config_dir_file = get_standard_config_filename (name); + if (!config_dir_file.empty ()) + { + if (stat (config_dir_file.c_str (), buf) == 0) + return config_dir_file; + } + + const char *homedir = getenv ("HOME"); + if (homedir != nullptr) + { + /* Make sure the path is absolute and tilde-expanded. */ + gdb::unique_xmalloc_ptr<char> abs (gdb_abspath (homedir)); + std::string path = (std::string (abs.get ()) + SLASH_STRING + + std::string (name)); + if (stat (path.c_str (), buf) == 0) + return path; + } + + return {}; +} + /* See gdbsupport/pathstuff.h. */ const char * diff --git a/gdbsupport/pathstuff.h b/gdbsupport/pathstuff.h index 85241bc..996c8f2 100644 --- a/gdbsupport/pathstuff.h +++ b/gdbsupport/pathstuff.h @@ -99,6 +99,29 @@ extern std::string get_standard_temp_dir (); extern std::string get_standard_config_dir (); +/* Look for FILENAME in the standard configuration directory as returned by + GET_STANDARD_CONFIG_DIR and return the path to the file. No check is + performed that the file actually exists or not. + + If FILENAME begins with a '.' then the path returned will remove the + leading '.' character, for example passing '.gdbinit' could return the + path '/home/username/.config/gdb/gdbinit'. */ + +extern std::string get_standard_config_filename (const char *filename); + +/* Look for a file called NAME in either the standard config directory or + in the users home directory. If a suitable file is found then *BUF will + be filled with the contents of a call to 'stat' on the found file, + otherwise *BUF is undefined after this call. + + If NAME starts with a '.' character then, when looking in the standard + config directory the file searched for has the '.' removed. For + example, if NAME is '.gdbinit' then on a Linux target GDB might look for + '~/.config/gdb/gdbinit' and then '~/.gdbinit'. */ + +extern std::string find_gdb_home_config_file (const char *name, + struct stat *buf); + /* Return the file name of the user's shell. Normally this comes from the SHELL environment variable. */ |