diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 96 | ||||
-rw-r--r-- | gdb/NEWS | 35 | ||||
-rw-r--r-- | gdb/auto-load.c | 358 | ||||
-rw-r--r-- | gdb/auto-load.h | 27 | ||||
-rw-r--r-- | gdb/doc/ChangeLog | 25 | ||||
-rw-r--r-- | gdb/doc/gdb.texinfo | 278 | ||||
-rw-r--r-- | gdb/linux-thread-db.c | 194 | ||||
-rw-r--r-- | gdb/main.c | 22 | ||||
-rw-r--r-- | gdb/python/py-auto-load.c | 153 | ||||
-rw-r--r-- | gdb/python/python.h | 2 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 11 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/help.exp | 2 | ||||
-rw-r--r-- | gdb/testsuite/gdb.python/py-objfile-script.exp | 2 | ||||
-rw-r--r-- | gdb/testsuite/gdb.python/py-section-script.exp | 6 |
14 files changed, 1096 insertions, 115 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 0f209dd..98ca2eb 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,101 @@ 2012-04-17 Jan Kratochvil <jan.kratochvil@redhat.com> + auto-load: Implementation. + * NEWS: New descriptions for "info auto-load", + "info auto-load gdb-scripts", "info auto-load python-scripts", + "info auto-load local-gdbinit" and "info auto-load libthread-db". + Deprecate "info auto-load-scripts", "set auto-load-scripts on|off" + and "show auto-load-scripts". New description for "set auto-load", + "show auto-load", "set auto-load gdb-scripts", + "show auto-load gdb-scripts", "set auto-load python-scripts", + "show auto-load python-scripts", "set auto-load local-gdbinit", + "show auto-load local-gdbinit", "set auto-load libthread-db" and + "show auto-load libthread-db". + * auto-load.c: Remove include python/python-internal.h. Add includes + exceptions.h, cli/cli-script.h, gdbcmd.h, cli/cli-decode.h and + cli/cli-setshow.h. + (GDB_AUTO_FILE_NAME, source_gdb_script_for_objfile) + (auto_load_gdb_scripts, show_auto_load_gdb_scripts): New. + (gdbpy_global_auto_load): Rename to ... + (global_auto_load): ... here. + (auto_load_local_gdbinit, auto_load_local_gdbinit_pathname) + (auto_load_local_gdbinit_loaded, show_auto_load_local_gdbinit) + (script_language_gdb, source_gdb_script_for_objfile): New. + (struct loaded_script): New field language. + (hash_loaded_script_entry, eq_loaded_script_entry): Calculate also + LANGUAGE. + (maybe_add_script): Add parameter language. Drop redundant + entry.full_path initialization. Initialize entry.language and + (*slot)->language. + (auto_load_objfile_script): Change parameter suffix to language. + Remove the call of maybe_add_script. + Call language->source_script_for_objfile. + (load_auto_scripts_for_objfile, struct collect_matching_scripts_data): + New. + (collect_matching_scripts): Adjust it for + struct collect_matching_scripts_data. + (auto_load_info_scripts_pattern_nl): New variable. + (info_auto_load_scripts): Rename to ... + (auto_load_info_scripts): ... here, add parameter language. Adjust it + for struct collect_matching_scripts_data. + (info_auto_load_gdb_scripts, info_auto_load_local_gdbinit) + (set_auto_load_cmd, auto_load_set_cmdlist_get, show_auto_load_cmd) + (auto_load_show_cmdlist_get, info_auto_load_cmd) + (auto_load_info_cmdlist_get): New. + (_initialize_auto_load): Move add_info of "auto-load-scripts" to + python/py-auto-load.c. New installment for "set auto-load gdb-scripts", + "info auto-load gdb-scripts", "set auto-load local-gdbinit" and + "info auto-load local-gdbinit". + * auto-load.h (struct script_language): New. + (gdbpy_global_auto_load): Rename to ... + (global_auto_load): ... here. + (auto_load_local_gdbinit, auto_load_local_gdbinit_pathname) + (auto_load_local_gdbinit_loaded): New declarations. + (maybe_add_script): New parameter language. + (auto_load_objfile_script): Change parameter suffix to language. + (load_auto_scripts_for_objfile, auto_load_info_scripts_pattern_nl) + (auto_load_info_scripts, auto_load_set_cmdlist_get) + (auto_load_show_cmdlist_get, auto_load_info_cmdlist_get): New + declarations. + * linux-thread-db.c: Include auto-load.h and ctype.h. + (auto_load_thread_db, show_auto_load_thread_db): New. + (struct thread_db_info): New field filename. + (delete_thread_db_info): Call xfree for FILENAME. + (try_thread_db_load): Initialize FILENAME. + (try_thread_db_load_from_pdir, try_thread_db_load_from_dir): Return + if !AUTO_LOAD_THREAD_DB. + (info_auto_load_libthread_db_compare, info_auto_load_libthread_db): New. + (_initialize_thread_db): Install auto_load_thread_db + as "set auto-load libthread-db" and install info_auto_load_libthread_db + as "info auto-load libthread-db". + * main.c (captured_main): Rename gdbpy_global_auto_load to + global_auto_load. Initialize AUTO_LOAD_LOCAL_GDBINIT_PATHNAME and + AUTO_LOAD_LOCAL_GDBINIT_LOADED. + (print_gdb_help): Extend the help for 'local init file'. + * python/py-auto-load.c: Remove a comment about gdb scripts extension. + (GDBPY_AUTO_SECTION_NAME): Extend the comment it is Python specific. + (auto_load_scripts): Rename to ... + (auto_load_python_scripts): ... here, update the comment. + (gdbpy_load_auto_script_for_objfile): New declaration. + (show_auto_load_python_scripts, script_language_python) + (gdbpy_load_auto_script_for_objfile): New. + (source_section_scripts): Refactor the code. + (load_auto_scripts_for_objfile): Rename to ... + (gdbpy_load_auto_scripts_for_objfile): ... here, update the + auto_load_objfile_script caller, drop GDBPY_GLOBAL_AUTO_LOAD checking. + (info_auto_load_python_scripts): New. + (gdbpy_initialize_auto_load): New variables cmd and cmd_name. + Rename "set auto-load-scripts" to "set auto-load python-scripts". + Register "set auto-load-scripts" as its deprecated alias. Register + "info auto-load python-scripts". Register "info auto-load-scripts" as + its deprecated alias. + (load_auto_scripts_for_objfile): Rename to ... + (gdbpy_load_auto_scripts_for_objfile): ... here. + * python/python.h (load_auto_scripts_for_objfile): Rename to ... + (gdbpy_load_auto_scripts_for_objfile): ... here. + +2012-04-17 Jan Kratochvil <jan.kratochvil@redhat.com> + auto-load: Move files. * Makefile.in (SFILES): Add auto-load.c. (HFILES_NO_SRCDIR): Add auto-load.h. @@ -98,6 +98,19 @@ expressions. These commands are available only if GDB is configured with '--with-python'. + ** "info auto-load" shows status of all kinds of auto-loaded files, + "info auto-load gdb-scripts" shows status of auto-loading GDB canned + sequences of commands files, "info auto-load python-scripts" + shows status of auto-loading Python script files, + "info auto-load local-gdbinit" shows status of loading init file + (.gdbinit) from current directory and "info auto-load libthread-db" shows + status of inferior specific thread debugging shared library loading. + + ** "info auto-load-scripts", "set auto-load-scripts on|off" + and "show auto-load-scripts" commands have been deprecated, use their + "info auto-load python-scripts", "set auto-load python-scripts on|off" + and "show auto-load python-scripts" counterparts instead. + * New targets Renesas RL78 rl78-*-elf @@ -119,6 +132,28 @@ show breakpoint condition-evaluation This option can improve debugger efficiency depending on the speed of the target. +set auto-load off + Disable auto-loading globally. + +show auto-load + Show auto-loading setting of all kinds of auto-loaded files. + +set auto-load gdb-scripts on|off +show auto-load gdb-scripts + Control auto-loading of GDB canned sequences of commands files. + +set auto-load python-scripts on|off +show auto-load python-scripts + Control auto-loading of Python script files. + +set auto-load local-gdbinit on|off +show auto-load local-gdbinit + Control loading of init file (.gdbinit) from current directory. + +set auto-load libthread-db on|off +show auto-load libthread-db + Control auto-loading of inferior specific thread debugging shared library. + * New remote packets z0/z1 conditional breakpoints extension diff --git a/gdb/auto-load.c b/gdb/auto-load.c index 1a8f72f..c10d45a 100644 --- a/gdb/auto-load.c +++ b/gdb/auto-load.c @@ -27,19 +27,92 @@ #include "command.h" #include "observer.h" #include "objfiles.h" -#include "python/python-internal.h" +#include "exceptions.h" +#include "cli/cli-script.h" +#include "gdbcmd.h" +#include "cli/cli-decode.h" +#include "cli/cli-setshow.h" + +/* The suffix of per-objfile scripts to auto-load as non-Python command files. + E.g. When the program loads libfoo.so, look for libfoo-gdb.gdb. */ +#define GDB_AUTO_FILE_NAME "-gdb.gdb" + +static void source_gdb_script_for_objfile (struct objfile *objfile, FILE *file, + const char *filename); + +/* User-settable option to enable/disable auto-loading of GDB_AUTO_FILE_NAME + scripts: + set auto-load gdb-scripts on|off + This is true if we should auto-load associated scripts when an objfile + is opened, false otherwise. */ +static int auto_load_gdb_scripts = 1; + +/* "show" command for the auto_load_gdb_scripts configuration variable. */ + +static void +show_auto_load_gdb_scripts (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + fprintf_filtered (file, _("Auto-loading of canned sequences of commands " + "scripts is %s.\n"), + value); +} /* Internal-use flag to enable/disable auto-loading. This is true if we should auto-load python code when an objfile is opened, false otherwise. - Both auto_load_scripts && gdbpy_global_auto_load must be true to enable + Both auto_load_scripts && global_auto_load must be true to enable auto-loading. This flag exists to facilitate deferring auto-loading during start-up until after ./.gdbinit has been read; it may augment the search directories used to find the scripts. */ -int gdbpy_global_auto_load = 1; +int global_auto_load = 1; + +/* Auto-load .gdbinit file from the current directory? */ +int auto_load_local_gdbinit = 1; + +/* Absolute pathname to the current directory .gdbinit, if it exists. */ +char *auto_load_local_gdbinit_pathname = NULL; + +/* Boolean value if AUTO_LOAD_LOCAL_GDBINIT_PATHNAME has been loaded. */ +int auto_load_local_gdbinit_loaded = 0; + +/* "show" command for the auto_load_local_gdbinit configuration variable. */ + +static void +show_auto_load_local_gdbinit (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + fprintf_filtered (file, _("Auto-loading of .gdbinit script from current " + "directory is %s.\n"), + value); +} + +/* Definition of script language for GDB canned sequences of commands. */ + +static const struct script_language script_language_gdb + = { GDB_AUTO_FILE_NAME, source_gdb_script_for_objfile }; + +static void +source_gdb_script_for_objfile (struct objfile *objfile, FILE *file, + const char *filename) +{ + struct auto_load_pspace_info *pspace_info; + volatile struct gdb_exception e; + + /* Add this script to the hash table too so "info auto-load gdb-scripts" + can print it. */ + pspace_info = get_auto_load_pspace_data_for_loading (current_program_space); + maybe_add_script (pspace_info, filename, filename, &script_language_gdb); + + TRY_CATCH (e, RETURN_MASK_ALL) + { + script_from_file (file, filename); + } + exception_print (gdb_stderr, e); +} /* For scripts specified in .debug_gdb_scripts, multiple objfiles may load the same script. There's no point in loading the script multiple times, @@ -62,9 +135,12 @@ struct loaded_script { /* Name as provided by the objfile. */ const char *name; + /* Full path name or NULL if script wasn't found (or was otherwise inaccessible). */ const char *full_path; + + const struct script_language *language; }; /* Per-program-space data key. */ @@ -109,7 +185,7 @@ hash_loaded_script_entry (const void *data) { const struct loaded_script *e = data; - return htab_hash_string (e->name); + return htab_hash_string (e->name) ^ htab_hash_pointer (e->language); } /* Equality function for the loaded script hash. */ @@ -120,7 +196,7 @@ eq_loaded_script_entry (const void *a, const void *b) const struct loaded_script *ea = a; const struct loaded_script *eb = b; - return strcmp (ea->name, eb->name) == 0; + return strcmp (ea->name, eb->name) == 0 && ea->language == eb->language; } /* Initialize the table to track loaded scripts. @@ -156,20 +232,21 @@ get_auto_load_pspace_data_for_loading (struct program_space *pspace) return info; } -/* Add script NAME to hash table of PSPACE_INFO. - FULL_PATH is NULL if the script wasn't found. - The result is true if the script was already in the hash table. */ +/* Add script NAME in LANGUAGE to hash table of PSPACE_INFO. + FULL_PATH is NULL if the script wasn't found. The result is + true if the script was already in the hash table. */ int -maybe_add_script (struct auto_load_pspace_info *pspace_info, const char *name, - const char *full_path) +maybe_add_script (struct auto_load_pspace_info *pspace_info, + const char *name, const char *full_path, + const struct script_language *language) { struct htab *htab = pspace_info->loaded_scripts; struct loaded_script **slot, entry; int in_hash_table; entry.name = name; - entry.full_path = full_path; + entry.language = language; slot = (struct loaded_script **) htab_find_slot (htab, &entry, INSERT); in_hash_table = *slot != NULL; @@ -194,6 +271,7 @@ maybe_add_script (struct auto_load_pspace_info *pspace_info, const char *name, } else (*slot)->full_path = NULL; + (*slot)->language = language; } return in_hash_table; @@ -216,10 +294,12 @@ clear_section_scripts (void) } } -/* Look for the auto-load script associated with OBJFILE and load it. */ +/* Look for the auto-load script in LANGUAGE associated with OBJFILE and load + it. */ void -auto_load_objfile_script (struct objfile *objfile, const char *suffix) +auto_load_objfile_script (struct objfile *objfile, + const struct script_language *language) { char *realname; char *filename, *debugfile; @@ -229,9 +309,9 @@ auto_load_objfile_script (struct objfile *objfile, const char *suffix) realname = gdb_realpath (objfile->name); len = strlen (realname); - filename = xmalloc (len + strlen (suffix) + 1); + filename = xmalloc (len + strlen (language->suffix) + 1); memcpy (filename, realname, len); - strcpy (filename + len, suffix); + strcpy (filename + len, language->suffix); cleanups = make_cleanup (xfree, filename); make_cleanup (xfree, realname); @@ -269,27 +349,33 @@ auto_load_objfile_script (struct objfile *objfile, const char *suffix) if (input) { - struct auto_load_pspace_info *pspace_info; - make_cleanup_fclose (input); - /* Add this script to the hash table too so "info auto-load-scripts" - can print it. */ - pspace_info = - get_auto_load_pspace_data_for_loading (current_program_space); - maybe_add_script (pspace_info, debugfile, debugfile); - /* To preserve existing behaviour we don't check for whether the script was already in the table, and always load it. It's highly unlikely that we'd ever load it twice, and these scripts are required to be idempotent under multiple loads anyway. */ - source_python_script_for_objfile (objfile, input, debugfile); + language->source_script_for_objfile (objfile, input, debugfile); } do_cleanups (cleanups); } +/* Load any auto-loaded scripts for OBJFILE. */ + +void +load_auto_scripts_for_objfile (struct objfile *objfile) +{ + if (!global_auto_load) + return; + + if (auto_load_gdb_scripts) + auto_load_objfile_script (objfile, &script_language_gdb); + + gdbpy_load_auto_scripts_for_objfile (objfile); +} + /* This is a new_objfile observer callback to auto-load scripts. Two flavors of auto-loaded scripts are supported. @@ -314,6 +400,13 @@ auto_load_new_objfile (struct objfile *objfile) typedef struct loaded_script *loaded_script_ptr; DEF_VEC_P (loaded_script_ptr); +struct collect_matching_scripts_data +{ + VEC (loaded_script_ptr) **scripts_p; + + const struct script_language *language; +}; + /* Traversal function for htab_traverse. Collect the entry if it matches the regexp. */ @@ -321,10 +414,10 @@ static int collect_matching_scripts (void **slot, void *info) { struct loaded_script *script = *slot; - VEC (loaded_script_ptr) **scripts_ptr = info; + struct collect_matching_scripts_data *data = info; - if (re_exec (script->name)) - VEC_safe_push (loaded_script_ptr, *scripts_ptr, script); + if (script->language == data->language && re_exec (script->name)) + VEC_safe_push (loaded_script_ptr, *data->scripts_p, script); return 1; } @@ -366,10 +459,18 @@ sort_scripts_by_name (const void *ap, const void *bp) return FILENAME_CMP (a->name, b->name); } -/* "info auto-load-scripts" command. */ +/* Special internal GDB value of auto_load_info_scripts's PATTERN identify + the "info auto-load XXX" command has been executed through the general + "info auto-load" invocation. Extra newline will be printed if needed. */ +char auto_load_info_scripts_pattern_nl[] = ""; -static void -info_auto_load_scripts (char *pattern, int from_tty) +/* Implementation for "info auto-load gdb-scripts" + (and "info auto-load python-scripts"). List scripts in LANGUAGE matching + PATTERN. FROM_TTY is the usual GDB boolean for user interactivity. */ + +void +auto_load_info_scripts (char *pattern, int from_tty, + const struct script_language *language) { struct ui_out *uiout = current_uiout; struct auto_load_pspace_info *pspace_info; @@ -402,14 +503,22 @@ info_auto_load_scripts (char *pattern, int from_tty) if (pspace_info != NULL && pspace_info->loaded_scripts != NULL) { + struct collect_matching_scripts_data data = { &scripts, language }; + immediate_quit++; /* Pass a pointer to scripts as VEC_safe_push can realloc space. */ htab_traverse_noresize (pspace_info->loaded_scripts, - collect_matching_scripts, &scripts); + collect_matching_scripts, &data); immediate_quit--; } nr_scripts = VEC_length (loaded_script_ptr, scripts); + + /* Table header shifted right by preceding "gdb-scripts: " would not match + its columns. */ + if (nr_scripts > 0 && pattern == auto_load_info_scripts_pattern_nl) + ui_out_text (uiout, "\n"); + make_cleanup_ui_out_table_begin_end (uiout, 2, nr_scripts, "AutoLoadedScriptsTable"); @@ -441,6 +550,29 @@ info_auto_load_scripts (char *pattern, int from_tty) } } +/* Wrapper for "info auto-load gdb-scripts". */ + +static void +info_auto_load_gdb_scripts (char *pattern, int from_tty) +{ + auto_load_info_scripts (pattern, from_tty, &script_language_gdb); +} + +/* Implement 'info auto-load local-gdbinit'. */ + +static void +info_auto_load_local_gdbinit (char *args, int from_tty) +{ + if (auto_load_local_gdbinit_pathname == NULL) + printf_filtered (_("Local .gdbinit file was not found.\n")); + else if (auto_load_local_gdbinit_loaded) + printf_filtered (_("Local .gdbinit file \"%s\" has been loaded.\n"), + auto_load_local_gdbinit_pathname); + else + printf_filtered (_("Local .gdbinit file \"%s\" has not been loaded.\n"), + auto_load_local_gdbinit_pathname); +} + /* Return non-zero if SCRIPT_NOT_FOUND_WARNING_PRINTED of PSPACE_INFO was unset before calling this function. Always set SCRIPT_NOT_FOUND_WARNING_PRINTED of PSPACE_INFO. */ @@ -455,6 +587,132 @@ script_not_found_warning_print (struct auto_load_pspace_info *pspace_info) return retval; } +/* The only valid "set auto-load" argument is off|0|no|disable. */ + +static void +set_auto_load_cmd (char *args, int from_tty) +{ + struct cmd_list_element *list; + size_t length; + + /* See parse_binary_operation in use by the sub-commands. */ + + length = args ? strlen (args) : 0; + + while (length > 0 && (args[length - 1] == ' ' || args[length - 1] == '\t')) + length--; + + if (length == 0 || (strncmp (args, "off", length) != 0 + && strncmp (args, "0", length) != 0 + && strncmp (args, "no", length) != 0 + && strncmp (args, "disable", length) != 0)) + error (_("Valid is only global 'set auto-load no'; " + "otherwise check the auto-load sub-commands.")); + + for (list = *auto_load_set_cmdlist_get (); list != NULL; list = list->next) + if (list->var_type == var_boolean) + { + gdb_assert (list->type == set_cmd); + do_setshow_command (args, from_tty, list); + } +} + +/* Initialize "set auto-load " commands prefix and return it. */ + +struct cmd_list_element ** +auto_load_set_cmdlist_get (void) +{ + static struct cmd_list_element *retval; + + if (retval == NULL) + add_prefix_cmd ("auto-load", class_maintenance, set_auto_load_cmd, _("\ +Auto-loading specific settings.\n\ +Configure various auto-load-specific variables such as\n\ +automatic loading of Python scripts."), + &retval, "set auto-load ", + 1/*allow-unknown*/, &setlist); + + return &retval; +} + +/* Command "show auto-load" displays summary of all the current + "show auto-load " settings. */ + +static void +show_auto_load_cmd (char *args, int from_tty) +{ + cmd_show_list (*auto_load_show_cmdlist_get (), from_tty, ""); +} + +/* Initialize "show auto-load " commands prefix and return it. */ + +struct cmd_list_element ** +auto_load_show_cmdlist_get (void) +{ + static struct cmd_list_element *retval; + + if (retval == NULL) + add_prefix_cmd ("auto-load", class_maintenance, show_auto_load_cmd, _("\ +Show auto-loading specific settings.\n\ +Show configuration of various auto-load-specific variables such as\n\ +automatic loading of Python scripts."), + &retval, "show auto-load ", + 0/*allow-unknown*/, &showlist); + + return &retval; +} + +/* Command "info auto-load" displays whether the various auto-load files have + been loaded. This is reimplementation of cmd_show_list which inserts + newlines at proper places. */ + +static void +info_auto_load_cmd (char *args, int from_tty) +{ + struct cmd_list_element *list; + struct cleanup *infolist_chain; + struct ui_out *uiout = current_uiout; + + infolist_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "infolist"); + + for (list = *auto_load_info_cmdlist_get (); list != NULL; list = list->next) + { + struct cleanup *option_chain + = make_cleanup_ui_out_tuple_begin_end (uiout, "option"); + + gdb_assert (!list->prefixlist); + gdb_assert (list->type == not_set_cmd); + + ui_out_field_string (uiout, "name", list->name); + ui_out_text (uiout, ": "); + cmd_func (list, auto_load_info_scripts_pattern_nl, from_tty); + + /* Close the tuple. */ + do_cleanups (option_chain); + } + + /* Close the tuple. */ + do_cleanups (infolist_chain); +} + +/* Initialize "info auto-load " commands prefix and return it. */ + +struct cmd_list_element ** +auto_load_info_cmdlist_get (void) +{ + static struct cmd_list_element *retval; + + if (retval == NULL) + add_prefix_cmd ("auto-load", class_info, info_auto_load_cmd, _("\ +Print current status of auto-loaded files.\n\ +Print whether various files like Python scripts or .gdbinit files have been\n\ +found and/or loaded."), + &retval, "info auto-load ", + 0/*allow-unknown*/, &infolist); + + return &retval; +} + void _initialize_auto_load (void); void @@ -465,8 +723,38 @@ _initialize_auto_load (void) observer_attach_new_objfile (auto_load_new_objfile); - add_info ("auto-load-scripts", - info_auto_load_scripts, - _("Print the list of automatically loaded scripts.\n\ -Usage: info auto-load-scripts [REGEXP]")); + add_setshow_boolean_cmd ("gdb-scripts", class_support, + &auto_load_gdb_scripts, _("\ +Enable or disable auto-loading of canned sequences of commands scripts."), _("\ +Show whether auto-loading of canned sequences of commands scripts is enabled."), + _("\ +If enabled, canned sequences of commands are loaded when the debugger reads\n\ +an executable or shared library.\n\ +This options has security implications for untrusted inferiors."), + NULL, show_auto_load_gdb_scripts, + auto_load_set_cmdlist_get (), + auto_load_show_cmdlist_get ()); + + add_cmd ("gdb-scripts", class_info, info_auto_load_gdb_scripts, + _("Print the list of automatically loaded sequences of commands.\n\ +Usage: info auto-load gdb-scripts [REGEXP]"), + auto_load_info_cmdlist_get ()); + + add_setshow_boolean_cmd ("local-gdbinit", class_support, + &auto_load_local_gdbinit, _("\ +Enable or disable auto-loading of .gdbinit script in current directory."), _("\ +Show whether auto-loading .gdbinit script in current directory is enabled."), + _("\ +If enabled, canned sequences of commands are loaded when debugger starts\n\ +from .gdbinit file in current directory. Such files are deprecated,\n\ +use a script associated with inferior executable file instead.\n\ +This options has security implications for untrusted inferiors."), + NULL, show_auto_load_local_gdbinit, + auto_load_set_cmdlist_get (), + auto_load_show_cmdlist_get ()); + + add_cmd ("local-gdbinit", class_info, info_auto_load_local_gdbinit, + _("Print whether current directory .gdbinit file has been loaded.\n\ +Usage: info auto-load local-gdbinit"), + auto_load_info_cmdlist_get ()); } diff --git a/gdb/auto-load.h b/gdb/auto-load.h index c026696..98bcb63 100644 --- a/gdb/auto-load.h +++ b/gdb/auto-load.h @@ -22,15 +22,36 @@ struct program_space; -extern int gdbpy_global_auto_load; +struct script_language +{ + const char *suffix; + + void (*source_script_for_objfile) (struct objfile *objfile, FILE *file, + const char *filename); +}; + +extern int global_auto_load; + +extern int auto_load_local_gdbinit; +extern char *auto_load_local_gdbinit_pathname; +extern int auto_load_local_gdbinit_loaded; extern struct auto_load_pspace_info * get_auto_load_pspace_data_for_loading (struct program_space *pspace); extern int maybe_add_script (struct auto_load_pspace_info *pspace_info, - const char *name, const char *full_path); + const char *name, const char *full_path, + const struct script_language *language); extern void auto_load_objfile_script (struct objfile *objfile, - const char *suffix); + const struct script_language *language); +extern void load_auto_scripts_for_objfile (struct objfile *objfile); extern int script_not_found_warning_print (struct auto_load_pspace_info *pspace_info); +extern char auto_load_info_scripts_pattern_nl[]; +extern void auto_load_info_scripts (char *pattern, int from_tty, + const struct script_language *language); + +extern struct cmd_list_element **auto_load_set_cmdlist_get (void); +extern struct cmd_list_element **auto_load_show_cmdlist_get (void); +extern struct cmd_list_element **auto_load_info_cmdlist_get (void); #endif /* AUTO_LOAD_H */ diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index e288b9e..65a627d 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,28 @@ +2012-04-17 Jan Kratochvil <jan.kratochvil@redhat.com> + + auto-load: Implementation. + * gdb.texinfo (Mode Options): New anchor for -nx. + (Startup): New anchors for Option -init-eval-command, + Home Directory Init File + and Init File in the Current Directory during Startup. + Mention set auto-load local-gdbinit with a reference. + Change the sample code to "set auto-load python-scripts". + (Threads): New anchor set libthread-db-search-path. + Provide references to libthread_db.so.1 file. + (Controlling GDB): New menu item for Auto-loading. + (Auto-loading, Init File in the Current Directory) + (libthread_db.so.1 file, objfile-gdb.gdb file): New nodes. + (Python): Rename the menu item Auto-loading to Python Auto-loading. + (Writing a Pretty-Printer, Objfiles In Python): Update the renamed + reference. + (Auto-loading): Rename to ... + (Python Auto-loading): ... here. Change "set auto-load-scripts" to + "set auto-load python-scripts", new anchor for it. Change + "show auto-load-scripts" to "show auto-load python-scripts", new anchor + for it. Change "info auto-load-scripts" + to "info auto-load python-scripts", new anchor for it. Change "scripts" + to "Python scripts". + 2012-04-14 Anton Gorenkov <xgsa@yandex.ru> PR mi/13393 diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 613782e..0ef9163 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -1029,6 +1029,7 @@ You can run @value{GDBN} in various alternative modes---for example, in batch mode or quiet mode. @table @code +@anchor{-nx} @item -nx @itemx -n @cindex @code{--nx} @@ -1257,6 +1258,7 @@ Here's the description of what @value{GDBN} does during session startup: Sets up the command interpreter as specified by the command line (@pxref{Mode Options, interpreter}). +@anchor{Option -init-eval-command} @item Executes commands and command files specified by the @samp{-iex} and @samp{-ix} options in their specified order. Usually you should use the @@ -1271,6 +1273,7 @@ used when building @value{GDBN}; @pxref{System-wide configuration, ,System-wide configuration and settings}) and executes all the commands in that file. +@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 @@ -1280,9 +1283,12 @@ that file. @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. This is only done if the current directory is +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 @@ -1298,7 +1304,7 @@ If you wish to disable the auto-loading during startup, you must do something like the following: @smallexample -$ gdb -iex "set auto-load-scripts off" myprogram +$ gdb -iex "set auto-load python-scripts off" myprogram @end smallexample Option @samp{-ex} does not work because the auto-loading is then turned @@ -2885,6 +2891,7 @@ programs with multiple threads. @xref{Set Watchpoints,,Setting Watchpoints}, for information about watchpoints in programs with multiple threads. +@anchor{set libthread-db-search-path} @table @code @kindex set libthread-db-search-path @cindex search path for @code{libthread_db} @@ -2899,11 +2906,15 @@ macro. On @sc{gnu}/Linux and Solaris systems, @value{GDBN} uses a ``helper'' @code{libthread_db} library to obtain information about threads in the inferior process. @value{GDBN} will use @samp{libthread-db-search-path} -to find @code{libthread_db}. +to find @code{libthread_db}. @value{GDBN} also consults first if inferior +specific thread debugging library loading is enabled +by @samp{set auto-load libthread-db} (@pxref{libthread_db.so.1 file}). A special entry @samp{$sdir} for @samp{libthread-db-search-path} refers to the default system directories that are -normally searched for loading shared libraries. +normally searched for loading shared libraries. The @samp{$sdir} entry +is the only kind not needing to be enabled by @samp{set auto-load libthread-db} +(@pxref{libthread_db.so.1 file}). A special entry @samp{$pdir} for @samp{libthread-db-search-path} refers to the directory from which @code{libpthread} @@ -20411,6 +20422,7 @@ described here. * Screen Size:: Screen size * Numbers:: Numbers * ABI:: Configuring the current ABI +* Auto-loading:: Automatically loading associated files * Messages/Warnings:: Optional warnings and messages * Debugging Output:: Optional messages about internal happenings * Other Misc Settings:: Other Miscellaneous Settings @@ -20836,6 +20848,227 @@ With no argument, show the list of supported C@t{++} ABI's. Set the current C@t{++} ABI to @var{abi}, or return to automatic detection. @end table +@node Auto-loading +@section Automatically loading associated files +@cindex auto-loading + +@value{GDBN} sometimes reads files with commands and settings automatically, +without being explicitly told so by the user. We call this feature +@dfn{auto-loading}. While auto-loading is useful for automatically adapting +@value{GDBN} to the needs of your project, it can sometimes produce unexpected +results or introduce security risks (e.g., if the file comes from untrusted +sources). + +For these reasons, @value{GDBN} includes commands and options to let you +control when to auto-load files and which files should be auto-loaded. + +@table @code +@anchor{set auto-load off} +@kindex set auto-load off +@item set auto-load off +Globally disable loading of all auto-loaded files. +You may want to use this command with the @samp{-iex} option +(@pxref{Option -init-eval-command}) such as: +@smallexample +$ @kbd{gdb -iex "set auto-load off" untrusted-executable corefile} +@end smallexample + +Be aware that system init file (@pxref{System-wide configuration}) +and init files from your home directory (@pxref{Home Directory Init File}) +still get read (as they come from generally trusted directories). +To prevent @value{GDBN} from auto-loading even those init files, use the +@option{-nx} option (@pxref{Mode Options}), in addition to +@code{set auto-load no}. + +@anchor{show auto-load} +@kindex show auto-load +@item show auto-load +Show whether auto-loading of each specific @samp{auto-load} file(s) is enabled +or disabled. + +@smallexample +(gdb) show auto-load +gdb-scripts: Auto-loading of canned sequences of commands scripts is on. +libthread-db: Auto-loading of inferior specific libthread_db is on. +local-gdbinit: Auto-loading of .gdbinit script from current directory is on. +python-scripts: Auto-loading of Python scripts is on. +@end smallexample + +@anchor{info auto-load} +@kindex info auto-load +@item info auto-load +Print whether each specific @samp{auto-load} file(s) have been auto-loaded or +not. + +@smallexample +(gdb) info auto-load +gdb-scripts: +Loaded Script +Yes /home/user/gdb/gdb-gdb.gdb +libthread-db: No auto-loaded libthread-db. +local-gdbinit: Local .gdbinit file "/home/user/gdb/.gdbinit" has been loaded. +python-scripts: +Loaded Script +Yes /home/user/gdb/gdb-gdb.py +@end smallexample +@end table + +These are various kinds of files @value{GDBN} can automatically load: + +@itemize @bullet +@item +@xref{objfile-gdb.py file}, controlled by @ref{set auto-load python-scripts}. +@item +@xref{objfile-gdb.gdb file}, controlled by @ref{set auto-load gdb-scripts}. +@item +@xref{dotdebug_gdb_scripts section}, +controlled by @ref{set auto-load python-scripts}. +@item +@xref{Init File in the Current Directory}, +controlled by @ref{set auto-load local-gdbinit}. +@item +@xref{libthread_db.so.1 file}, controlled by @ref{set auto-load libthread-db}. +@end itemize + +These are @value{GDBN} control commands for the auto-loading: + +@multitable @columnfractions .5 .5 +@item @xref{set auto-load off}. +@tab Disable auto-loading globally. +@item @xref{show auto-load}. +@tab Show setting of all kinds of files. +@item @xref{info auto-load}. +@tab Show state of all kinds of files. +@item @xref{set auto-load gdb-scripts}. +@tab Control for @value{GDBN} command scripts. +@item @xref{show auto-load gdb-scripts}. +@tab Show setting of @value{GDBN} command scripts. +@item @xref{info auto-load gdb-scripts}. +@tab Show state of @value{GDBN} command scripts. +@item @xref{set auto-load python-scripts}. +@tab Control for @value{GDBN} Python scripts. +@item @xref{show auto-load python-scripts}. +@tab Show setting of @value{GDBN} Python scripts. +@item @xref{info auto-load python-scripts}. +@tab Show state of @value{GDBN} Python scripts. +@item @xref{set auto-load local-gdbinit}. +@tab Control for init file in the current directory. +@item @xref{show auto-load local-gdbinit}. +@tab Show setting of init file in the current directory. +@item @xref{info auto-load local-gdbinit}. +@tab Show state of init file in the current directory. +@item @xref{set auto-load libthread-db}. +@tab Control for thread debugging library. +@item @xref{show auto-load libthread-db}. +@tab Show setting of thread debugging library. +@item @xref{info auto-load libthread-db}. +@tab Show state of thread debugging library. +@end multitable + +@menu +* Init File in the Current Directory:: @samp{set/show/info auto-load local-gdbinit} +* libthread_db.so.1 file:: @samp{set/show/info auto-load libthread-db} +* objfile-gdb.gdb file:: @samp{set/show/info auto-load gdb-script} +@xref{Python Auto-loading}. +@end menu + +@node Init File in the Current Directory +@subsection Automatically loading init file in the current directory +@cindex auto-loading init file in the current directory + +By default, @value{GDBN} reads and executes the canned sequences of commands +from init file (if any) in the current working directory, +see @ref{Init File in the Current Directory during Startup}. + +@table @code +@anchor{set auto-load local-gdbinit} +@kindex set auto-load local-gdbinit +@item set auto-load local-gdbinit [on|off] +Enable or disable the auto-loading of canned sequences of commands +(@pxref{Sequences}) found in init file in the current directory. + +@anchor{show auto-load local-gdbinit} +@kindex show auto-load local-gdbinit +@item show auto-load local-gdbinit +Show whether auto-loading of canned sequences of commands from init file in the +current directory is enabled or disabled. + +@anchor{info auto-load local-gdbinit} +@kindex info auto-load local-gdbinit +@item info auto-load local-gdbinit +Print whether canned sequences of commands from init file in the +current directory have been auto-loaded. +@end table + +@node libthread_db.so.1 file +@subsection Automatically loading thread debugging library +@cindex auto-loading libthread_db.so.1 + +This feature is currently present only on @sc{gnu}/Linux native hosts. + +@value{GDBN} reads in some cases thread debugging library from places specific +to the inferior (@pxref{set libthread-db-search-path}). + +The special @samp{libthread-db-search-path} entry @samp{$sdir} is processed +without checking this @samp{set auto-load libthread-db} switch as system +libraries have to be trusted in general. In all other cases of +@samp{libthread-db-search-path} entries @value{GDBN} checks first if @samp{set +auto-load libthread-db} is enabled before trying to open such thread debugging +library. + +@table @code +@anchor{set auto-load libthread-db} +@kindex set auto-load libthread-db +@item set auto-load libthread-db [on|off] +Enable or disable the auto-loading of inferior specific thread debugging library. + +@anchor{show auto-load libthread-db} +@kindex show auto-load libthread-db +@item show auto-load libthread-db +Show whether auto-loading of inferior specific thread debugging library is +enabled or disabled. + +@anchor{info auto-load libthread-db} +@kindex info auto-load libthread-db +@item info auto-load libthread-db +Print the list of all loaded inferior specific thread debugging libraries and +for each such library print list of inferior @var{pid}s using it. +@end table + +@node objfile-gdb.gdb file +@subsection The @file{@var{objfile}-gdb.gdb} file +@cindex auto-loading @file{@var{objfile}-gdb.gdb} + +@value{GDBN} tries to load an @file{@var{objfile}-gdb.gdb} file containing +canned sequences of commands (@pxref{Sequences}), as long as @samp{set +auto-load gdb-scripts} is set to @samp{on}. + +For more background refer to the similar Python scripts auto-loading +description (@pxref{objfile-gdb.py file}). + +@table @code +@anchor{set auto-load gdb-scripts} +@kindex set auto-load gdb-scripts +@item set auto-load gdb-scripts [on|off] +Enable or disable the auto-loading of canned sequences of commands scripts. + +@anchor{show auto-load gdb-scripts} +@kindex show auto-load gdb-scripts +@item show auto-load gdb-scripts +Show whether auto-loading of canned sequences of commands scripts is enabled or +disabled. + +@anchor{info auto-load gdb-scripts} +@kindex info auto-load gdb-scripts +@cindex print list of auto-loaded canned sequences of commands scripts +@item info auto-load gdb-scripts [@var{regexp}] +Print the list of all canned sequences of commands scripts that @value{GDBN} +auto-loaded. +@end table + +If @var{regexp} is supplied only canned sequences of commands scripts with +matching names are printed. + @node Messages/Warnings @section Optional Warnings and Messages @@ -21710,7 +21943,7 @@ automatically imported when @value{GDBN} starts. @menu * Python Commands:: Accessing Python from @value{GDBN}. * Python API:: Accessing @value{GDBN} from Python. -* Auto-loading:: Automatically loading Python code. +* Python Auto-loading:: Automatically loading Python code. * Python modules:: Python modules provided by @value{GDBN}. @end menu @@ -22952,7 +23185,7 @@ This practice will enable @value{GDBN} to load multiple versions of your pretty-printers at the same time, because they will have different names. -You should write auto-loaded code (@pxref{Auto-loading}) such that it +You should write auto-loaded code (@pxref{Python Auto-loading}) such that it can be evaluated multiple times without changing its meaning. An ideal auto-load file will consist solely of @code{import}s of your printer modules, followed by a call to a register pretty-printers with @@ -23922,7 +24155,7 @@ The following objfile-related functions are available in the @findex gdb.current_objfile @defun gdb.current_objfile () -When auto-loading a Python script (@pxref{Auto-loading}), @value{GDBN} +When auto-loading a Python script (@pxref{Python Auto-loading}), @value{GDBN} sets the ``current objfile'' to the corresponding objfile. This function returns the current objfile. If there is no current objfile, this function returns @code{None}. @@ -24855,9 +25088,9 @@ resolve this to the lazy string's character type, use the type's writable. @end defvar -@node Auto-loading -@subsection Auto-loading -@cindex auto-loading, Python +@node Python Auto-loading +@subsection Python Auto-loading +@cindex Python auto-loading When a new object file is read (for example, due to the @code{file} command, or because the inferior has loaded a shared library), @@ -24873,32 +25106,35 @@ Auto-loading can be enabled or disabled, and the list of auto-loaded scripts can be printed. @table @code -@kindex set auto-load-scripts -@item set auto-load-scripts [yes|no] +@anchor{set auto-load python-scripts} +@kindex set auto-load python-scripts +@item set auto-load python-scripts [on|off] Enable or disable the auto-loading of Python scripts. -@kindex show auto-load-scripts -@item show auto-load-scripts +@anchor{show auto-load python-scripts} +@kindex show auto-load python-scripts +@item show auto-load python-scripts Show whether auto-loading of Python scripts is enabled or disabled. -@kindex info auto-load-scripts -@cindex print list of auto-loaded scripts -@item info auto-load-scripts [@var{regexp}] -Print the list of all scripts that @value{GDBN} auto-loaded. +@anchor{info auto-load python-scripts} +@kindex info auto-load python-scripts +@cindex print list of auto-loaded Python scripts +@item info auto-load python-scripts [@var{regexp}] +Print the list of all Python scripts that @value{GDBN} auto-loaded. -Also printed is the list of scripts that were mentioned in +Also printed is the list of Python scripts that were mentioned in the @code{.debug_gdb_scripts} section and were not found (@pxref{dotdebug_gdb_scripts section}). This is useful because their names are not printed when @value{GDBN} tries to load them and fails. There may be many of them, and printing an error message for each one is problematic. -If @var{regexp} is supplied only scripts with matching names are printed. +If @var{regexp} is supplied only Python scripts with matching names are printed. Example: @smallexample -(gdb) info auto-load-scripts +(gdb) info auto-load python-scripts Loaded Script Yes py-section-script.py full name: /tmp/py-section-script.py diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c index 4d09c6e..4499b8f 100644 --- a/gdb/linux-thread-db.c +++ b/gdb/linux-thread-db.c @@ -41,8 +41,10 @@ #include "linux-nat.h" #include "linux-procfs.h" #include "linux-osdata.h" +#include "auto-load.h" #include <signal.h> +#include <ctype.h> #ifdef HAVE_GNU_LIBC_VERSION_H #include <gnu/libc-version.h> @@ -76,6 +78,21 @@ static char *libthread_db_search_path; +/* Set to non-zero if thread_db auto-loading is enabled + by the "set auto-load libthread-db" command. */ +static int auto_load_thread_db = 1; + +/* "show" command for the auto_load_thread_db configuration variable. */ + +static void +show_auto_load_thread_db (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + fprintf_filtered (file, _("Auto-loading of inferior specific libthread_db " + "is %s.\n"), + value); +} + static void set_libthread_db_search_path (char *ignored, int from_tty, struct cmd_list_element *c) @@ -120,6 +137,10 @@ struct thread_db_info /* Handle from dlopen for libthread_db.so. */ void *handle; + /* Absolute pathname from gdb_realpath to disk file used for dlopen-ing + HANDLE. It may be NULL for system library. */ + char *filename; + /* Structure that identifies the child process for the <proc_service.h> interface. */ struct ps_prochandle proc_handle; @@ -249,6 +270,8 @@ delete_thread_db_info (int pid) if (info->handle != NULL) dlclose (info->handle); + xfree (info->filename); + if (info_prev) info_prev->next = info->next; else @@ -808,6 +831,10 @@ try_thread_db_load (const char *library) info = add_thread_db_info (handle); + /* Do not save system library name, that one is always trusted. */ + if (strchr (library, '/') != NULL) + info->filename = gdb_realpath (library); + if (try_thread_db_load_1 (info)) return 1; @@ -857,6 +884,9 @@ try_thread_db_load_from_pdir (void) { struct objfile *obj; + if (!auto_load_thread_db) + return 0; + ALL_OBJFILES (obj) if (libpthread_name_p (obj->name)) { @@ -896,6 +926,9 @@ try_thread_db_load_from_dir (const char *dir, size_t dir_len) char *path; int result; + if (!auto_load_thread_db) + return 0; + path = xmalloc (dir_len + 1 + strlen (LIBTHREAD_DB_SO) + 1); cleanup = make_cleanup (xfree, path); @@ -1801,6 +1834,150 @@ thread_db_resume (struct target_ops *ops, beneath->to_resume (beneath, ptid, step, signo); } +/* qsort helper function for info_auto_load_libthread_db, sort the + thread_db_info pointers primarily by their FILENAME and secondarily by their + PID, both in ascending order. */ + +static int +info_auto_load_libthread_db_compare (const void *ap, const void *bp) +{ + struct thread_db_info *a = *(struct thread_db_info **) ap; + struct thread_db_info *b = *(struct thread_db_info **) bp; + int retval; + + retval = strcmp (a->filename, b->filename); + if (retval) + return retval; + + return (a->pid > b->pid) - (a->pid - b->pid); +} + +/* Implement 'info auto-load libthread-db'. */ + +static void +info_auto_load_libthread_db (char *args, int from_tty) +{ + struct ui_out *uiout = current_uiout; + const char *cs = args ? args : ""; + struct thread_db_info *info, **array; + unsigned info_count, unique_filenames; + size_t max_filename_len, max_pids_len, pids_len; + struct cleanup *back_to; + char *pids; + int i; + + while (isspace (*cs)) + cs++; + if (*cs) + error (_("'info auto-load libthread-db' does not accept any parameters")); + + info_count = 0; + for (info = thread_db_list; info; info = info->next) + if (info->filename != NULL) + info_count++; + + array = xmalloc (sizeof (*array) * info_count); + back_to = make_cleanup (xfree, array); + + info_count = 0; + for (info = thread_db_list; info; info = info->next) + if (info->filename != NULL) + array[info_count++] = info; + + /* Sort ARRAY by filenames and PIDs. */ + + qsort (array, info_count, sizeof (*array), + info_auto_load_libthread_db_compare); + + /* Calculate the number of unique filenames (rows) and the maximum string + length of PIDs list for the unique filenames (columns). */ + + unique_filenames = 0; + max_filename_len = 0; + max_pids_len = 0; + pids_len = 0; + for (i = 0; i < info_count; i++) + { + int pid = array[i]->pid; + size_t this_pid_len; + + for (this_pid_len = 0; pid != 0; pid /= 10) + this_pid_len++; + + if (i == 0 || strcmp (array[i - 1]->filename, array[i]->filename) != 0) + { + unique_filenames++; + max_filename_len = max (max_filename_len, + strlen (array[i]->filename)); + + if (i > 0) + { + pids_len -= strlen (", "); + max_pids_len = max (max_pids_len, pids_len); + } + pids_len = 0; + } + pids_len += this_pid_len + strlen (", "); + } + if (i) + { + pids_len -= strlen (", "); + max_pids_len = max (max_pids_len, pids_len); + } + + /* Table header shifted right by preceding "libthread-db: " would not match + its columns. */ + if (info_count > 0 && args == auto_load_info_scripts_pattern_nl) + ui_out_text (uiout, "\n"); + + make_cleanup_ui_out_table_begin_end (uiout, 2, unique_filenames, + "LinuxThreadDbTable"); + + ui_out_table_header (uiout, max_filename_len, ui_left, "filename", + "Filename"); + ui_out_table_header (uiout, pids_len, ui_left, "PIDs", "Pids"); + ui_out_table_body (uiout); + + pids = xmalloc (max_pids_len + 1); + make_cleanup (xfree, pids); + + /* Note I is incremented inside the cycle, not at its end. */ + for (i = 0; i < info_count;) + { + struct cleanup *chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); + char *pids_end; + + info = array[i]; + ui_out_field_string (uiout, "filename", info->filename); + pids_end = pids; + + while (i < info_count && strcmp (info->filename, array[i]->filename) == 0) + { + if (pids_end != pids) + { + *pids_end++ = ','; + *pids_end++ = ' '; + } + pids_end += xsnprintf (pids_end, &pids[max_pids_len + 1] - pids_end, + "%u", array[i]->pid); + gdb_assert (pids_end < &pids[max_pids_len + 1]); + + i++; + } + *pids_end = '\0'; + + ui_out_field_string (uiout, "pids", pids); + + ui_out_text (uiout, "\n"); + do_cleanups (chain); + } + + do_cleanups (back_to); + + if (info_count == 0) + ui_out_message (uiout, 0, _("No auto-loaded libthread-db.\n")); +} + static void init_thread_db_ops (void) { @@ -1862,6 +2039,23 @@ When non-zero, libthread-db debugging is enabled."), show_libthread_db_debug, &setdebuglist, &showdebuglist); + add_setshow_boolean_cmd ("libthread-db", class_support, + &auto_load_thread_db, _("\ +Enable or disable auto-loading of inferior specific libthread_db."), _("\ +Show whether auto-loading inferior specific libthread_db is enabled."), _("\ +If enabled, libthread_db will be searched in 'set libthread-db-search-path'\n\ +locations to load libthread_db compatible with the inferior.\n\ +Standard system libthread_db still gets loaded even with this option off.\n\ +This options has security implications for untrusted inferiors."), + NULL, show_auto_load_thread_db, + auto_load_set_cmdlist_get (), + auto_load_show_cmdlist_get ()); + + add_cmd ("libthread-db", class_info, info_auto_load_libthread_db, + _("Print the list of loaded inferior specific libthread_db.\n\ +Usage: info auto-load libthread-db"), + auto_load_info_cmdlist_get ()); + /* Add ourselves to objfile event chain. */ observer_attach_new_objfile (thread_db_new_objfile); @@ -877,8 +877,8 @@ captured_main (void *data) /* Skip auto-loading section-specified scripts until we've sourced local_gdbinit (which is often used to augment the source search path). */ - save_auto_load = gdbpy_global_auto_load; - gdbpy_global_auto_load = 0; + save_auto_load = global_auto_load; + global_auto_load = 0; if (execarg != NULL && symarg != NULL @@ -940,14 +940,24 @@ captured_main (void *data) /* Read the .gdbinit file in the current directory, *if* it isn't the same as the $HOME/.gdbinit file (it should exist, also). */ - if (local_gdbinit && !inhibit_gdbinit) - catch_command_errors (source_script, local_gdbinit, 0, RETURN_MASK_ALL); + if (local_gdbinit) + { + auto_load_local_gdbinit_pathname = gdb_realpath (local_gdbinit); + + if (!inhibit_gdbinit && auto_load_local_gdbinit) + { + auto_load_local_gdbinit_loaded = 1; + + catch_command_errors (source_script, local_gdbinit, 0, + RETURN_MASK_ALL); + } + } /* Now that all .gdbinit's have been read and all -d options have been processed, we can read any scripts mentioned in SYMARG. We wait until now because it is common to add to the source search path in local_gdbinit. */ - gdbpy_global_auto_load = save_auto_load; + global_auto_load = save_auto_load; ALL_OBJFILES (objfile) load_auto_scripts_for_objfile (objfile); @@ -1093,7 +1103,7 @@ At startup, GDB reads the following init files and executes their commands:\n\ "), home_gdbinit); if (local_gdbinit) fprintf_unfiltered (stream, _("\ - * local init file: ./%s\n\ + * local init file (see also 'set auto-load local-gdbinit'): ./%s\n\ "), local_gdbinit); fputs_unfiltered (_("\n\ For more information, type \"help\" from within GDB, or consult the\n\ diff --git a/gdb/python/py-auto-load.c b/gdb/python/py-auto-load.c index a80960b..7eb021c 100644 --- a/gdb/python/py-auto-load.c +++ b/gdb/python/py-auto-load.c @@ -31,29 +31,56 @@ #include "python-internal.h" -/* NOTE: It's trivial to also support auto-loading normal gdb scripts. - There has yet to be a need so it's not implemented. */ - /* The suffix of per-objfile scripts to auto-load. E.g. When the program loads libfoo.so, look for libfoo-gdb.py. */ #define GDBPY_AUTO_FILE_NAME "-gdb.py" -/* The section to look for scripts (in file formats that support sections). +/* The section to look for Python auto-loaded scripts (in file formats that + support sections). Each entry in this section is a byte of value 1, and then the nul-terminated name of the script. The script name may include a directory. The leading byte is to allow upward compatible extensions. */ #define GDBPY_AUTO_SECTION_NAME ".debug_gdb_scripts" -/* User-settable option to enable/disable auto-loading: - set auto-load-scripts on|off - This is true if we should auto-load associated scripts when an objfile - is opened, false otherwise. - At the moment, this only affects python scripts, but there's no reason - one couldn't also have other kinds of auto-loaded scripts, and there's - no reason to have them each controlled by a separate flag. - So we elide "python" from the name here and in the option. - The fact that it lives here is just an implementation detail. */ -static int auto_load_scripts = 1; +/* User-settable option to enable/disable auto-loading of Python scripts: + set auto-load python-scripts on|off + This is true if we should auto-load associated Python scripts when an + objfile is opened, false otherwise. */ +static int auto_load_python_scripts = 1; + +static void gdbpy_load_auto_script_for_objfile (struct objfile *objfile, + FILE *file, + const char *filename); + +/* "show" command for the auto_load_python_scripts configuration variable. */ + +static void +show_auto_load_python_scripts (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + fprintf_filtered (file, _("Auto-loading of Python scripts is %s.\n"), value); +} + +/* Definition of script language for Python scripts. */ + +static const struct script_language script_language_python + = { GDBPY_AUTO_FILE_NAME, gdbpy_load_auto_script_for_objfile }; + +/* Wrapper of source_python_script_for_objfile for script_language_python. */ + +static void +gdbpy_load_auto_script_for_objfile (struct objfile *objfile, FILE *file, + const char *filename) +{ + struct auto_load_pspace_info *pspace_info; + + /* Add this script to the hash table too so "info auto-load python-scripts" + can print it. */ + pspace_info = get_auto_load_pspace_data_for_loading (current_program_space); + maybe_add_script (pspace_info, filename, filename, &script_language_python); + + source_python_script_for_objfile (objfile, file, filename); +} /* Load scripts specified in OBJFILE. START,END delimit a buffer containing a list of nul-terminated @@ -121,6 +148,17 @@ source_section_scripts (struct objfile *objfile, const char *source_name, make_cleanup_fclose (stream); make_cleanup (xfree, full_path); } + else + { + full_path = NULL; + + /* We don't throw an error, the program is still debuggable. */ + if (script_not_found_warning_print (pspace_info)) + warning (_("Missing auto-load scripts referenced in section %s\n\ +of file %s\n\ +Use `info auto-load python [REGEXP]' to list them."), + GDBPY_AUTO_SECTION_NAME, objfile->name); + } /* If one script isn't found it's not uncommon for more to not be found either. We don't want to print an error message for each @@ -129,24 +167,12 @@ source_section_scripts (struct objfile *objfile, const char *source_name, IWBN if complaints.c were more general-purpose. */ - in_hash_table = maybe_add_script (pspace_info, file, - opened ? full_path : NULL); + in_hash_table = maybe_add_script (pspace_info, file, full_path, + &script_language_python); - if (! opened) - { - /* We don't throw an error, the program is still debuggable. */ - if (script_not_found_warning_print (pspace_info)) - warning (_("Missing auto-load scripts referenced in section %s\n\ -of file %s\n\ -Use `info auto-load-scripts [REGEXP]' to list them."), - GDBPY_AUTO_SECTION_NAME, objfile->name); - } - else - { - /* If this file is not currently loaded, load it. */ - if (! in_hash_table) - source_python_script_for_objfile (objfile, stream, full_path); - } + /* If this file is not currently loaded, load it. */ + if (opened && !in_hash_table) + source_python_script_for_objfile (objfile, stream, full_path); do_cleanups (back_to); } @@ -181,36 +207,75 @@ auto_load_section_scripts (struct objfile *objfile, const char *section_name) do_cleanups (cleanups); } -/* Load any auto-loaded scripts for OBJFILE. */ +/* Load any Python auto-loaded scripts for OBJFILE. */ void -load_auto_scripts_for_objfile (struct objfile *objfile) +gdbpy_load_auto_scripts_for_objfile (struct objfile *objfile) { - if (auto_load_scripts && gdbpy_global_auto_load) + if (auto_load_python_scripts) { - auto_load_objfile_script (objfile, GDBPY_AUTO_FILE_NAME); + auto_load_objfile_script (objfile, &script_language_python); auto_load_section_scripts (objfile, GDBPY_AUTO_SECTION_NAME); } } + +/* Wrapper for "info auto-load python-scripts". */ + +static void +info_auto_load_python_scripts (char *pattern, int from_tty) +{ + auto_load_info_scripts (pattern, from_tty, &script_language_python); +} void gdbpy_initialize_auto_load (void) { + struct cmd_list_element *cmd; + char *cmd_name; + + add_setshow_boolean_cmd ("python-scripts", class_support, + &auto_load_python_scripts, _("\ +Set the debugger's behaviour regarding auto-loaded Python scripts."), _("\ +Show the debugger's behaviour regarding auto-loaded Python scripts."), _("\ +If enabled, auto-loaded Python scripts are loaded when the debugger reads\n\ +an executable or shared library.\n\ +This options has security implications for untrusted inferiors."), + NULL, show_auto_load_python_scripts, + auto_load_set_cmdlist_get (), + auto_load_show_cmdlist_get ()); + add_setshow_boolean_cmd ("auto-load-scripts", class_support, - &auto_load_scripts, _("\ -Set the debugger's behaviour regarding auto-loaded scripts."), _("\ -Show the debugger's behaviour regarding auto-loaded scripts."), _("\ -If enabled, auto-loaded scripts are loaded when the debugger reads\n\ -an executable or shared library."), - NULL, NULL, - &setlist, - &showlist); + &auto_load_python_scripts, _("\ +Set the debugger's behaviour regarding auto-loaded Python scripts, " + "deprecated."), + _("\ +Show the debugger's behaviour regarding auto-loaded Python scripts, " + "deprecated."), + NULL, NULL, show_auto_load_python_scripts, + &setlist, &showlist); + cmd_name = "auto-load-scripts"; + cmd = lookup_cmd (&cmd_name, setlist, "", -1, 1); + deprecate_cmd (cmd, "set auto-load python-scripts"); + + /* It is needed because lookup_cmd updates the CMD_NAME pointer. */ + cmd_name = "auto-load-scripts"; + cmd = lookup_cmd (&cmd_name, showlist, "", -1, 1); + deprecate_cmd (cmd, "show auto-load python-scripts"); + + add_cmd ("python-scripts", class_info, info_auto_load_python_scripts, + _("Print the list of automatically loaded Python scripts.\n\ +Usage: info auto-load python-scripts [REGEXP]"), + auto_load_info_cmdlist_get ()); + + cmd = add_info ("auto-load-scripts", info_auto_load_python_scripts, _("\ +Print the list of automatically loaded Python scripts, deprecated.")); + deprecate_cmd (cmd, "info auto-load python-scripts"); } #else /* ! HAVE_PYTHON */ void -load_auto_scripts_for_objfile (struct objfile *objfile) +gdbpy_load_auto_scripts_for_objfile (struct objfile *objfile) { } diff --git a/gdb/python/python.h b/gdb/python/python.h index 08eb29e..dd7066f 100644 --- a/gdb/python/python.h +++ b/gdb/python/python.h @@ -39,7 +39,7 @@ int apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr, void preserve_python_values (struct objfile *objfile, htab_t copied_types); -void load_auto_scripts_for_objfile (struct objfile *objfile); +void gdbpy_load_auto_scripts_for_objfile (struct objfile *objfile); int gdbpy_should_stop (struct breakpoint_object *bp_obj); diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index c276178..249bb43 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2012-04-17 Jan Kratochvil <jan.kratochvil@redhat.com> + + auto-load: Implementation. + * gdb.base/help.exp (test set height): Increase the height. + * gdb.python/py-objfile-script.exp (info auto-load-scripts): Change + to ... + (info auto-load python-scripts): ... here. + * gdb.python/py-section-script.exp (info auto-load-scripts *): Change + to ... + (info auto-load python-scripts *): ... here. + 2012-04-16 Yao Qi <yao@codesourcery.com> * lib/trace-support.exp (get_in_proc_agent): New. diff --git a/gdb/testsuite/gdb.base/help.exp b/gdb/testsuite/gdb.base/help.exp index b5d350e..7e48aef 100644 --- a/gdb/testsuite/gdb.base/help.exp +++ b/gdb/testsuite/gdb.base/help.exp @@ -24,7 +24,7 @@ gdb_start # force the height of the debugger to be pretty large so no pagers get used -gdb_test_no_output "set height 400" "test set height" +gdb_test_no_output "set height 500" "test set height" # use a larger expect input buffer for long help outputs. # test help add-symbol-file diff --git a/gdb/testsuite/gdb.python/py-objfile-script.exp b/gdb/testsuite/gdb.python/py-objfile-script.exp index 4963206..0143838 100644 --- a/gdb/testsuite/gdb.python/py-objfile-script.exp +++ b/gdb/testsuite/gdb.python/py-objfile-script.exp @@ -40,7 +40,7 @@ gdb_reinitialize_dir $srcdir/$subdir gdb_load ${binfile} # Verify gdb loaded the script. -gdb_test "info auto-load-scripts" "Yes.*/${testfile}-gdb.py.*" +gdb_test "info auto-load python-scripts" "Yes.*/${testfile}-gdb.py.*" if ![runto_main] { perror "couldn't run to main" diff --git a/gdb/testsuite/gdb.python/py-section-script.exp b/gdb/testsuite/gdb.python/py-section-script.exp index 9846ce8..0b4b46b 100644 --- a/gdb/testsuite/gdb.python/py-section-script.exp +++ b/gdb/testsuite/gdb.python/py-section-script.exp @@ -52,11 +52,11 @@ gdb_reinitialize_dir $srcdir/$subdir gdb_load ${binfile} # Verify gdb loaded the script. -gdb_test "info auto-load-scripts" "Yes.*${testfile}.py.*full name: .*/${testfile}.py.*" +gdb_test "info auto-load python-scripts" "Yes.*${testfile}.py.*full name: .*/${testfile}.py.*" # Again, with a regexp this time. -gdb_test "info auto-load-scripts ${testfile}" "Yes.*${testfile}.py.*full name: .*/${testfile}.py.*" +gdb_test "info auto-load python-scripts ${testfile}" "Yes.*${testfile}.py.*full name: .*/${testfile}.py.*" # Again, with a regexp that matches no scripts. -gdb_test "info auto-load-scripts no-script-matches-this" \ +gdb_test "info auto-load python-scripts no-script-matches-this" \ "No auto-load scripts matching no-script-matches-this." if ![runto_main] { |