From patchwork Mon Aug 26 00:33:10 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Terekhov, Mikhail via Gdb-patches" X-Patchwork-Id: 34266 Received: (qmail 109895 invoked by alias); 26 Aug 2019 00:33:20 -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 109886 invoked by uid 89); 26 Aug 2019 00:33:20 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-22.5 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=Home, Scripts, 1991, HX-Received:a81 X-HELO: mail-yb1-f201.google.com Received: from mail-yb1-f201.google.com (HELO mail-yb1-f201.google.com) (209.85.219.201) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 26 Aug 2019 00:33:15 +0000 Received: by mail-yb1-f201.google.com with SMTP id i199so11871821yba.1 for ; Sun, 25 Aug 2019 17:33:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=bLLmg94NbjWdOtFPwXa7dYKWDF/1lUXsxnlVMTf+wY0=; b=Z/4mP5b6ohiHHe8ylaAUWo3+sEZrUuUNE1awwNuMHJn3D07nB+wMHFLyLMb1sZJsnC xNth7BW+d0dRAThYol+NZYthI2Tdqf/0q0MSNH8i0s0O1PyTa/CNvcxqsCmQBog0oXwW SDp5HfravquX54ZR0UjQxihBglE4V51+nzPosnuWSQ1s5e0ehvH+lThlcvzKTnSRLd7L RGzw+QMUhM5VD8kZDdJwDvD1/20cT8abbB/j5kXC0gX6hfqqsPf3ElL8F6N/ymQRqzJ0 ptQ8NkKXuI7PX0tKzim7fPQ7EfQmpYMyZ3cqN8/2xfWjsxNtbXbD8eB4jgXZ6YcqNma4 7Z0A== Date: Sun, 25 Aug 2019 19:33:10 -0500 In-Reply-To: Message-Id: <20190826003310.86830-1-cbiesinger@google.com> Mime-Version: 1.0 References: Subject: [PATCH 3/3 v2] Load system gdbinit files from a directory X-Patchwork-Original-From: "Christian Biesinger via gdb-patches" From: "Terekhov, Mikhail via Gdb-patches" Reply-To: Christian Biesinger To: gdb-patches@sourceware.org Cc: Christian Biesinger X-IsSubscribed: yes [Adds NEWS entry, documentation, and fixes Sergio's review comments. This should also be suitable to replace Fedora's custom gdbinit because it does support loading .py files correctly, because it calls source_script (this was also the case in the previous version. I don't know how to write a test for this] Adds a configure option --with-system-gdbinit-dir to specify a directory in which to look for gdbinit files. All files in this directory are loaded on startup (subject to -n/-nx as usual). gdb/ChangeLog: 2019-08-20 Christian Biesinger * NEWS: Mention new --with-system-gdbinit-dir option. * config.in: Regenerate. * configure: Regenerate. * configure.ac: Add new option --with-system-gdbinit-dir. * main.c (get_init_files): Change system_gdbinit argument to a vector and return the files in SYSTEM_GDBINIT_DIR in addition to SYSTEM_GDBINIT. (captured_main_1): Update. (print_gdb_help): Update. gdb/doc/ChangeLog: 2019-08-25 Christian Biesinger * gdb.texinfo (many sections): Document new --with-system-gdbinit-dir option. --- gdb/NEWS | 5 ++++ gdb/config.in | 7 ++++++ gdb/configure | 51 +++++++++++++++++++++++++++++++++++++ gdb/configure.ac | 3 +++ gdb/doc/gdb.texinfo | 61 +++++++++++++++++++++++++++++++++++++++------ gdb/main.c | 56 ++++++++++++++++++++++++++++++++++------- 6 files changed, 166 insertions(+), 17 deletions(-) diff --git a/gdb/NEWS b/gdb/NEWS index 0a4e0f260f..fcc9c6f41f 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -27,6 +27,11 @@ provide the exitcode or exit status of the shell commands launched by GDB commands such as "shell", "pipe" and "make". +* If configured with --with-system-gdbinit-dir, GDB will now also load + all files in that directory as system gdbinit files, unless the -nx + or -n flag is provided. These files can be written in any supported + scripting language as long as they have a matching file extension. + * Python API ** The gdb.Value type has a new method 'format_string' which returns a diff --git a/gdb/config.in b/gdb/config.in index 26ca02f6a3..c0745c90a3 100644 --- a/gdb/config.in +++ b/gdb/config.in @@ -684,6 +684,13 @@ /* automatically load a system-wide gdbinit file */ #undef SYSTEM_GDBINIT +/* automatically load system-wide gdbinit files from this directory */ +#undef SYSTEM_GDBINIT_DIR + +/* Define if the system-gdbinit-dir directory should be relocated when GDB is + moved. */ +#undef SYSTEM_GDBINIT_DIR_RELOCATABLE + /* Define if the system-gdbinit directory should be relocated when GDB is moved. */ #undef SYSTEM_GDBINIT_RELOCATABLE diff --git a/gdb/configure b/gdb/configure index 22a5f6051d..8436f06c9f 100755 --- a/gdb/configure +++ b/gdb/configure @@ -693,6 +693,7 @@ WIN32LIBS SER_HARDWIRE WERROR_CFLAGS WARN_CFLAGS +SYSTEM_GDBINIT_DIR SYSTEM_GDBINIT TARGET_SYSTEM_ROOT CONFIG_LDFLAGS @@ -884,6 +885,7 @@ with_libipt_prefix with_included_regex with_sysroot with_system_gdbinit +with_system_gdbinit_dir enable_werror enable_build_warnings enable_gdb_build_warnings @@ -1618,6 +1620,9 @@ Optional Packages: --with-sysroot[=DIR] search for usr/lib et al within DIR --with-system-gdbinit=PATH automatically load a system-wide gdbinit file + --with-system-gdbinit-dir=PATH + automatically load system-wide gdbinit files from + this directory --with-lzma support lzma compression (auto/yes/no) --with-liblzma-prefix[=DIR] search for liblzma in DIR/include and DIR/lib --without-liblzma-prefix don't search for liblzma in includedir and libdir @@ -15238,6 +15243,52 @@ _ACEOF +# Check whether --with-system-gdbinit-dir was given. +if test "${with_system_gdbinit_dir+set}" = set; then : + withval=$with_system_gdbinit_dir; + SYSTEM_GDBINIT_DIR=$withval +else + SYSTEM_GDBINIT_DIR= +fi + + + test "x$prefix" = xNONE && prefix="$ac_default_prefix" + test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + ac_define_dir=`eval echo $SYSTEM_GDBINIT_DIR` + ac_define_dir=`eval echo $ac_define_dir` + +cat >>confdefs.h <<_ACEOF +#define SYSTEM_GDBINIT_DIR "$ac_define_dir" +_ACEOF + + + + + if test "x$exec_prefix" = xNONE || test "x$exec_prefix" = 'x${prefix}'; then + if test "x$prefix" = xNONE; then + test_prefix=/usr/local + else + test_prefix=$prefix + fi + else + test_prefix=$exec_prefix + fi + value=0 + case ${ac_define_dir} in + "${test_prefix}"|"${test_prefix}/"*|\ + '${exec_prefix}'|'${exec_prefix}/'*) + value=1 + ;; + esac + +cat >>confdefs.h <<_ACEOF +#define SYSTEM_GDBINIT_DIR_RELOCATABLE $value +_ACEOF + + + + + # Check whether --enable-werror was given. if test "${enable_werror+set}" = set; then : enableval=$enable_werror; case "${enableval}" in diff --git a/gdb/configure.ac b/gdb/configure.ac index 9da8818fb5..f3f5bd0635 100644 --- a/gdb/configure.ac +++ b/gdb/configure.ac @@ -1843,6 +1843,9 @@ GDB_AC_DEFINE_RELOCATABLE(TARGET_SYSTEM_ROOT, sysroot, ${ac_define_dir}) GDB_AC_WITH_DIR(SYSTEM_GDBINIT, system-gdbinit, [automatically load a system-wide gdbinit file], []) +GDB_AC_WITH_DIR(SYSTEM_GDBINIT_DIR, system-gdbinit-dir, + [automatically load system-wide gdbinit files from this directory], + []) AM_GDB_WARNINGS AM_GDB_UBSAN diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index bcf0420779..a43c4651c0 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -1083,6 +1083,13 @@ 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 immediately after system.gdbinit (if +enabled) when @value{GDBN} starts, before command line options have been +processed. @item @file{~/.gdbinit} This is the init file in your home directory. It is loaded next, after @file{system.gdbinit}, and before @@ -1315,8 +1322,11 @@ Sets up the command interpreter as specified by the command line @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 executes all the commands in -that file. + ,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. If scripting languages are enabled, the files +can be written in any of the supported languages as long as the extension matches +the language. @anchor{Home Directory Init File} @item @@ -37010,6 +37020,14 @@ directory under the configured prefix, and @value{GDBN} is moved to another location after being built, the location of the system-wide init file will be adjusted accordingly. +@item --with-system-gdbinit-dir=@var{directory} +Configure @value{GDBN} to automatically load init files from a +system-wide directory. @var{directory} should be an absolute path. +If @var{directory} is in a directory under the configured prefix, and +@value{GDBN} is moved to another location after being built, the +location of the system-wide init directory will be adjusted +accordingly. + @item --enable-build-warnings When building the @value{GDBN} sources, ask the compiler to warn about any code which looks even vaguely suspicious. It passes many @@ -37035,24 +37053,27 @@ was first introduced in GCC 4.9. @section System-wide configuration and settings @cindex system-wide init file -@value{GDBN} can be configured to have a system-wide init file; -this file will be read and executed at startup (@pxref{Startup, , What -@value{GDBN} does during startup}). +@value{GDBN} can be configured to have a system-wide init file and a system-wide +init file directory; this file and files in that directory will be read and +executed at startup (@pxref{Startup, , What @value{GDBN} does during startup}). -Here is the corresponding configure option: +Here are the corresponding configure options: @table @code @item --with-system-gdbinit=@var{file} Specify that the default location of the system-wide init file is @var{file}. +@item --with-system-gdbinit-dir=@var{directory} +Specify that the default location of the system-wide init file directory +is @var{directory}. @end table If @value{GDBN} has been configured with the option @option{--prefix=$prefix}, -it may be subject to relocation. Two possible cases: +they may be subject to relocation. Two possible cases: @itemize @bullet @item -If the default location of this init file contains @file{$prefix}, +If the default location of this init file/directory contains @file{$prefix}, it will be subject to relocation. Suppose that the configure options are @option{--prefix=$prefix --with-system-gdbinit=$prefix/etc/gdbinit}; if @value{GDBN} is moved from @file{$prefix} to @file{$install}, the system @@ -37078,6 +37099,12 @@ initialization. If the data-directory is changed after @value{GDBN} has started with the @code{set data-directory} command, the file will not be reread. +This applies similarly to the system-wide directory specified in +@option{--with-system-gdbinit-dir}. + +Any supported scripting language can be used for these init files, as long +as the file extension matches the scripting language. + @menu * System-wide Configuration Scripts:: Installed System-wide Configuration Scripts @end menu @@ -45598,6 +45625,10 @@ Richard M. Stallman and Roland H. Pesch, July 1991. @value{SYSTEM_GDBINIT} @end ifset +@ifset SYSTEM_GDBINIT +@value{SYSTEM_GDBINIT_DIR}/* +@end ifset + ~/.gdbinit ./.gdbinit @@ -45639,6 +45670,20 @@ See more in the @value{GDBN} manual in node @code{System-wide configuration} -- shell command @code{info -f gdb -n 'System-wide configuration'}. @end ifset +@ifset SYSTEM_GDBINIT_DIR +@item @value{SYSTEM_GDBINIT_DIR} +@end ifset +@ifclear SYSTEM_GDBINIT_DIR +@item (not enabled with @code{--with-system-gdbinit-dir} during compilation) +@end ifclear +System-wide initialization directory. All files in this directory are +executed on startup unless user specified @value{GDBN} option @code{-nx} or +@code{-n}. +See more in +@ifset man +the @value{GDBN} manual in node @code{System-wide configuration} +-- shell command @code{info -f gdb -n 'System-wide configuration'}. +@end ifset @ifclear man @ref{System-wide configuration}. @end ifclear diff --git a/gdb/main.c b/gdb/main.c index 089a7628e5..19cd723ba8 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -45,6 +45,7 @@ #include "event-top.h" #include "infrun.h" #include "gdbsupport/signals-state-save-restore.h" +#include #include #include "gdbsupport/pathstuff.h" #include "cli/cli-style.h" @@ -234,11 +235,11 @@ relocate_gdbinit_path_maybe_in_datadir (const std::string& file) to be loaded, then SYSTEM_GDBINIT (resp. HOME_GDBINIT and LOCAL_GDBINIT) is set to the empty string. */ static void -get_init_files (std::string *system_gdbinit, +get_init_files (std::vector *system_gdbinit, std::string *home_gdbinit, std::string *local_gdbinit) { - static std::string sysgdbinit; + static std::vector sysgdbinit; static std::string homeinit; static std::string localinit; static int initialized = 0; @@ -253,7 +254,32 @@ get_init_files (std::string *system_gdbinit, relocate_gdbinit_path_maybe_in_datadir (SYSTEM_GDBINIT); if (!relocated_sysgdbinit.empty () && stat (relocated_sysgdbinit.c_str (), &s) == 0) - sysgdbinit = relocated_sysgdbinit; + sysgdbinit.push_back(relocated_sysgdbinit); + } + if (SYSTEM_GDBINIT_DIR[0]) + { + std::string relocated_gdbinit_dir = + relocate_gdbinit_path_maybe_in_datadir (SYSTEM_GDBINIT_DIR); + DIR* dir = nullptr; + if (!relocated_gdbinit_dir.empty ()) + dir = opendir (relocated_gdbinit_dir.c_str ()); + if (dir != nullptr) + { + std::vector files; + struct dirent* ent; + for (;;) + { + ent = readdir (dir); + if (ent == nullptr) + break; + if (ent->d_type == DT_REG && ent->d_name[0] != '.') + files.push_back (relocated_gdbinit_dir + SLASH_STRING + + ent->d_name); + } + closedir (dir); + std::sort (files.begin (), files.end ()); + sysgdbinit.insert (sysgdbinit.end (), files.begin (), files.end ()); + } } const char *homedir = getenv ("HOME"); @@ -911,7 +937,7 @@ captured_main_1 (struct captured_main_args *context) /* Lookup gdbinit files. Note that the gdbinit file name may be overriden during file initialization, so get_init_files should be called after gdb_init. */ - std::string system_gdbinit; + std::vector system_gdbinit; std::string home_gdbinit; std::string local_gdbinit; get_init_files (&system_gdbinit, &home_gdbinit, &local_gdbinit); @@ -991,7 +1017,10 @@ captured_main_1 (struct captured_main_args *context) processed; it sets global parameters, which are independent of what file you are debugging or what directory you are in. */ if (!system_gdbinit.empty () && !inhibit_gdbinit) - ret = catch_command_errors (source_script, system_gdbinit.c_str (), 0); + { + for (const std::string& file : system_gdbinit) + ret = catch_command_errors (source_script, file.c_str (), 0); + } /* Read and execute $HOME/.gdbinit file, if it exists. This is done *before* all the command line arguments are processed; it sets @@ -1209,7 +1238,7 @@ gdb_main (struct captured_main_args *args) static void print_gdb_help (struct ui_file *stream) { - std::string system_gdbinit; + std::vector system_gdbinit; std::string home_gdbinit; std::string local_gdbinit; @@ -1290,9 +1319,18 @@ Other options:\n\n\ At startup, GDB reads the following init files and executes their commands:\n\ "), stream); if (!system_gdbinit.empty ()) - fprintf_unfiltered (stream, _("\ - * system-wide init file: %s\n\ -"), system_gdbinit.c_str ()); + { + std::string output; + for (size_t idx = 0; idx < system_gdbinit.size (); ++idx) + { + output += system_gdbinit[idx]; + if (idx < system_gdbinit.size () - 1) + output += ", "; + } + fprintf_unfiltered (stream, _("\ + * system-wide init files: %s\n\ +"), output.c_str ()); + } if (!home_gdbinit.empty ()) fprintf_unfiltered (stream, _("\ * user-specific init file: %s\n\