X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fmain.c;h=d5e5a678baa729d7b9210fecf9ef650f5c5233e9;hb=735fc2ca685b55bf1debbfcea6d2ab544e58a530;hp=7f873630d63fbda7bd4c23af2cacf60ade98f5a9;hpb=26344e0c532379477be3a203c80722051521a55e;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/main.c b/gdb/main.c index 7f873630d6..d5e5a678ba 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -1,6 +1,6 @@ /* Top level stuff for GDB, the GNU debugger. - Copyright (C) 1986-2019 Free Software Foundation, Inc. + Copyright (C) 1986-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -45,12 +45,14 @@ #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" #ifdef GDBTK #include "gdbtk/generic/gdbtk.h" #endif +#include "gdbsupport/alt-stack.h" /* The selected interpreter. This will be used as a set command variable, so it should always be malloc'ed - since @@ -122,7 +124,8 @@ set_gdb_data_directory (const char *new_datadir) print_sys_errmsg (new_datadir, save_errno); } else if (!S_ISDIR (st.st_mode)) - warning (_("%s is not a directory."), new_datadir); + warning (_("%ps is not a directory."), + styled_string (file_name_style.style (), new_datadir)); gdb_datadir = gdb_realpath (new_datadir).get (); @@ -198,7 +201,8 @@ relocate_gdb_directory (const char *initial, bool relocatable) otherwise. */ static std::string -relocate_gdbinit_path_maybe_in_datadir (const std::string& file) +relocate_gdbinit_path_maybe_in_datadir (const std::string &file, + bool relocatable) { size_t datadir_len = strlen (GDB_DATADIR); @@ -221,9 +225,8 @@ relocate_gdbinit_path_maybe_in_datadir (const std::string& file) } else { - relocated_path = relocate_path (gdb_program_name, - file.c_str (), - SYSTEM_GDBINIT_RELOCATABLE); + relocated_path = relocate_path (gdb_program_name, file.c_str (), + relocatable); } return relocated_path; } @@ -234,11 +237,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; @@ -250,10 +253,51 @@ get_init_files (std::string *system_gdbinit, if (SYSTEM_GDBINIT[0]) { std::string relocated_sysgdbinit - = relocate_gdbinit_path_maybe_in_datadir (SYSTEM_GDBINIT); + = relocate_gdbinit_path_maybe_in_datadir + (SYSTEM_GDBINIT, SYSTEM_GDBINIT_RELOCATABLE); 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, SYSTEM_GDBINIT_DIR_RELOCATABLE); + if (!relocated_gdbinit_dir.empty ()) { + gdb_dir_up dir (opendir (relocated_gdbinit_dir.c_str ())); + if (dir != nullptr) + { + std::vector files; + for (;;) + { + struct dirent *ent = readdir (dir.get ()); + if (ent == nullptr) + break; + std::string name (ent->d_name); + if (name == "." || name == "..") + continue; + /* ent->d_type is not available on all systems (e.g. mingw, + Solaris), so we have to call stat(). */ + std::string filename + = relocated_gdbinit_dir + SLASH_STRING + name; + if (stat (filename.c_str (), &s) != 0 + || !S_ISREG (s.st_mode)) + continue; + const struct extension_language_defn *extlang + = get_ext_lang_of_file (filename.c_str ()); + /* We effectively don't support "set script-extension + off/soft", because we are loading system init files here, + so it does not really make sense to depend on a + setting. */ + if (extlang != nullptr && ext_lang_present_p (extlang)) + files.push_back (std::move (filename)); + } + std::sort (files.begin (), files.end ()); + sysgdbinit.insert (sysgdbinit.end (), + files.begin (), files.end ()); + } + } } const char *homedir = getenv ("HOME"); @@ -292,29 +336,6 @@ get_init_files (std::string *system_gdbinit, *local_gdbinit = localinit; } -/* Try to set up an alternate signal stack for SIGSEGV handlers. - This allows us to handle SIGSEGV signals generated when the - normal process stack is exhausted. If this stack is not set - up (sigaltstack is unavailable or fails) and a SIGSEGV is - generated when the normal stack is exhausted then the program - will behave as though no SIGSEGV handler was installed. */ - -static void -setup_alternate_signal_stack (void) -{ -#ifdef HAVE_SIGALTSTACK - stack_t ss; - - /* FreeBSD versions older than 11.0 use char * for ss_sp instead of - void *. This cast works with both types. */ - ss.ss_sp = (char *) xmalloc (SIGSTKSZ); - ss.ss_size = SIGSTKSZ; - ss.ss_flags = 0; - - sigaltstack(&ss, NULL); -#endif -} - /* Call command_loop. */ /* Prevent inlining this function for the benefit of GDB's selftests @@ -856,7 +877,7 @@ captured_main_1 (struct captured_main_args *context) save_original_signals_state (quiet); /* Try to set up an alternate signal stack for SIGSEGV handlers. */ - setup_alternate_signal_stack (); + gdb::alternate_signal_stack signal_stack; /* Initialize all files. */ gdb_init (gdb_program_name); @@ -911,9 +932,9 @@ 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 + overridden 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); @@ -993,7 +1014,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 @@ -1211,7 +1235,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; @@ -1292,9 +1316,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\