/* libthread_db assisted debugging support, generic parts.
- Copyright (C) 1999-2016 Free Software Foundation, Inc.
+ Copyright (C) 1999-2017 Free Software Foundation, Inc.
This file is part of GDB.
#include <signal.h>
#include <ctype.h>
#include "nat/linux-namespaces.h"
+#include <algorithm>
/* GNU/Linux libthread_db support.
td_ta_new_ftype *td_ta_new_p;
td_ta_map_lwp2thr_ftype *td_ta_map_lwp2thr_p;
td_ta_thr_iter_ftype *td_ta_thr_iter_p;
- td_thr_validate_ftype *td_thr_validate_p;
td_thr_get_info_ftype *td_thr_get_info_p;
td_thr_tls_get_addr_ftype *td_thr_tls_get_addr_p;
td_thr_tlsbase_ftype *td_thr_tlsbase_p;
};
\f
-static char *
+static const char *
thread_db_err_str (td_err_e err)
{
static char buf[64];
int
thread_db_notice_clone (ptid_t parent, ptid_t child)
{
- td_thrhandle_t th;
- td_thrinfo_t ti;
- td_err_e err;
struct thread_db_info *info;
info = get_thread_db_info (ptid_get_pid (child));
/* These are essential. */
CHK (TDB_VERBOSE_DLSYM (info, td_ta_map_lwp2thr));
- CHK (TDB_VERBOSE_DLSYM (info, td_thr_validate));
CHK (TDB_VERBOSE_DLSYM (info, td_thr_get_info));
/* These are not essential. */
/* Do not save system library name, that one is always trusted. */
if (strchr (library, '/') != NULL)
- info->filename = gdb_realpath (library);
+ info->filename = gdb_realpath (library).release ();
if (try_thread_db_load_1 (info))
return 1;
{
warning (_ ("Target and debugger are in different PID "
"namespaces; thread lists and other data are "
- "likely unreliable"));
+ "likely unreliable. "
+ "Connect to gdbserver inside the container."));
}
}
}
ptid_t ptid, const td_thrhandle_t *th_p,
const td_thrinfo_t *ti_p)
{
- td_err_e err;
struct private_thread_info *priv;
- int new_thread = (tp == NULL);
/* A thread ID of zero may mean the thread library has not
initialized yet. Leave private == NULL until the thread library
ptid = beneath->to_wait (beneath, ptid, ourstatus, options);
- if (ourstatus->kind == TARGET_WAITKIND_IGNORE)
- return ptid;
-
- if (ourstatus->kind == TARGET_WAITKIND_EXITED
- || ourstatus->kind == TARGET_WAITKIND_SIGNALLED)
- return ptid;
+ switch (ourstatus->kind)
+ {
+ case TARGET_WAITKIND_IGNORE:
+ case TARGET_WAITKIND_EXITED:
+ case TARGET_WAITKIND_THREAD_EXITED:
+ case TARGET_WAITKIND_SIGNALLED:
+ return ptid;
+ }
info = get_thread_db_info (ptid_get_pid (ptid));
ops->beneath->to_update_thread_list (ops->beneath);
}
-static char *
+static const char *
thread_db_pid_to_str (struct target_ops *ops, ptid_t ptid)
{
struct thread_info *thread_info = find_thread_ptid (ptid);
/* Return a string describing the state of the thread specified by
INFO. */
-static char *
+static const char *
thread_db_extra_thread_info (struct target_ops *self,
struct thread_info *info)
{
char *pids;
int i;
- cs = skip_spaces_const (cs);
+ cs = skip_spaces (cs);
if (*cs)
error (_("'info auto-load libthread-db' does not accept any parameters"));
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));
+ max_filename_len = std::max (max_filename_len,
+ strlen (array[i]->filename));
if (i > 0)
{
pids_len -= strlen (", ");
- max_pids_len = max (max_pids_len, pids_len);
+ max_pids_len = std::max (max_pids_len, pids_len);
}
pids_len = 0;
}
if (i)
{
pids_len -= strlen (", ");
- max_pids_len = max (max_pids_len, pids_len);
+ max_pids_len = std::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");
+ uiout->text ("\n");
- make_cleanup_ui_out_table_begin_end (uiout, 2, unique_filenames,
- "LinuxThreadDbTable");
+ {
+ ui_out_emit_table table_emitter (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);
+ uiout->table_header (max_filename_len, ui_left, "filename", "Filename");
+ uiout->table_header (pids_len, ui_left, "PIDs", "Pids");
+ uiout->table_body ();
- pids = (char *) xmalloc (max_pids_len + 1);
- make_cleanup (xfree, pids);
+ pids = (char *) 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;
+ /* Note I is incremented inside the cycle, not at its end. */
+ for (i = 0; i < info_count;)
+ {
+ ui_out_emit_tuple tuple_emitter (uiout, NULL);
+ char *pids_end;
- 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]);
+ info = array[i];
+ uiout->field_string ("filename", info->filename);
+ pids_end = pids;
- i++;
- }
- *pids_end = '\0';
+ 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);
+ uiout->field_string ("pids", pids);
- ui_out_text (uiout, "\n");
- do_cleanups (chain);
- }
+ uiout->text ("\n");
+ }
+ }
do_cleanups (back_to);
if (info_count == 0)
- ui_out_message (uiout, 0, _("No auto-loaded libthread-db.\n"));
+ uiout->message (_("No auto-loaded libthread-db.\n"));
}
static void
complete_target_initialization (&thread_db_ops);
}
-/* Provide a prototype to silence -Wmissing-prototypes. */
-extern initialize_file_ftype _initialize_thread_db;
-
void
_initialize_thread_db (void)
{