diff options
author | Jan Kratochvil <jan.kratochvil@redhat.com> | 2012-04-17 15:51:48 +0000 |
---|---|---|
committer | Jan Kratochvil <jan.kratochvil@redhat.com> | 2012-04-17 15:51:48 +0000 |
commit | bf88dd68493db2b646b42165e6258573d3a597b5 (patch) | |
tree | a9c9e16ed3b0072eaac4836512d215438de46ab4 /gdb/linux-thread-db.c | |
parent | e2207b9a2828674a1deaf98db4ab4d0079b96d34 (diff) | |
download | gdb-bf88dd68493db2b646b42165e6258573d3a597b5.zip gdb-bf88dd68493db2b646b42165e6258573d3a597b5.tar.gz gdb-bf88dd68493db2b646b42165e6258573d3a597b5.tar.bz2 |
gdb/
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.
gdb/doc/
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".
gdb/testsuite/
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.
Diffstat (limited to 'gdb/linux-thread-db.c')
-rw-r--r-- | gdb/linux-thread-db.c | 194 |
1 files changed, 194 insertions, 0 deletions
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); |