From: John Baldwin <jhb@freebsd.org>
To: gdb-patches@sourceware.org, binutils@sourceware.org
Subject: [PATCH 6/6] Dump register notes for each thread when generating a FreeBSD core.
Date: Mon, 11 Jan 2016 23:25:00 -0000 [thread overview]
Message-ID: <1825615.K1HYhKRaB2@ralph.baldwin.cx> (raw)
gdb/ChangeLog:
* fbsd-tdep.c (find_stop_signal): Remove.
(struct fbsd_collect_regset_section_cb) <lwp>: New field.
<stop_signal>: New field.
<abort_iteration>: New field.
(fbsd_collect_regset_section_cb): Use new fields.
(fbsd_collect_thread_registers): New function.
(struct fbsd_corefile_thread_data): New structure.
(fbsd_corefile_thread): New function.
(fbsd_make_corefile_notes): Use new function to dump notes for each
non-exited thread in a process.
---
gdb/ChangeLog | 13 +++++
gdb/fbsd-tdep.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++----------
2 files changed, 131 insertions(+), 26 deletions(-)
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 4e911f8..af99b10 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,18 @@
2016-01-10 John Baldwin <jhb@FreeBSD.org>
+ * fbsd-tdep.c (find_stop_signal): Remove.
+ (struct fbsd_collect_regset_section_cb) <lwp>: New field.
+ <stop_signal>: New field.
+ <abort_iteration>: New field.
+ (fbsd_collect_regset_section_cb): Use new fields.
+ (fbsd_collect_thread_registers): New function.
+ (struct fbsd_corefile_thread_data): New structure.
+ (fbsd_corefile_thread): New function.
+ (fbsd_make_corefile_notes): Use new function to dump notes for each
+ non-exited thread in a process.
+
+2016-01-10 John Baldwin <jhb@FreeBSD.org>
+
* configure.ac: Check for support for LWP names on FreeBSD.
* fbsd-nat.c [PT_LWPINFO] New variable debug_fbsd_lwp.
[TDP_RFPPWAIT || HAVE_STRUCT_PTRACE_LWPINFO_PL_TDNAME]
diff --git a/gdb/fbsd-tdep.c b/gdb/fbsd-tdep.c
index 6851cc1..be3350e 100644
--- a/gdb/fbsd-tdep.c
+++ b/gdb/fbsd-tdep.c
@@ -78,17 +78,9 @@ find_signalled_thread (struct thread_info *info, void *data)
return 0;
}
-static enum gdb_signal
-find_stop_signal (void)
-{
- struct thread_info *info =
- iterate_over_threads (find_signalled_thread, NULL);
-
- if (info)
- return info->suspend.stop_signal;
- else
- return GDB_SIGNAL_0;
-}
+/* Structure for passing information from
+ fbsd_collect_thread_registers via an iterator to
+ fbsd_collect_regset_section_cb. */
struct fbsd_collect_regset_section_cb_data
{
@@ -96,6 +88,9 @@ struct fbsd_collect_regset_section_cb_data
bfd *obfd;
char *note_data;
int *note_size;
+ unsigned long lwp;
+ enum gdb_signal stop_signal;
+ int abort_iteration;
};
static void
@@ -107,6 +102,9 @@ fbsd_collect_regset_section_cb (const char *sect_name, int size,
struct fbsd_collect_regset_section_cb_data *data
= (struct fbsd_collect_regset_section_cb_data *) cb_data;
+ if (data->abort_iteration)
+ return;
+
gdb_assert (regset->collect_regset);
buf = (char *) xmalloc (size);
@@ -115,13 +113,73 @@ fbsd_collect_regset_section_cb (const char *sect_name, int size,
/* PRSTATUS still needs to be treated specially. */
if (strcmp (sect_name, ".reg") == 0)
data->note_data = (char *) elfcore_write_prstatus
- (data->obfd, data->note_data, data->note_size,
- ptid_get_pid (inferior_ptid), find_stop_signal (), buf);
+ (data->obfd, data->note_data, data->note_size, data->lwp,
+ gdb_signal_to_host (data->stop_signal), buf);
else
data->note_data = (char *) elfcore_write_register_note
(data->obfd, data->note_data, data->note_size,
sect_name, buf, size);
xfree (buf);
+
+ if (data->note_data == NULL)
+ data->abort_iteration = 1;
+}
+
+/* Records the thread's register state for the corefile note
+ section. */
+
+static char *
+fbsd_collect_thread_registers (const struct regcache *regcache,
+ ptid_t ptid, bfd *obfd,
+ char *note_data, int *note_size,
+ enum gdb_signal stop_signal)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct fbsd_collect_regset_section_cb_data data;
+
+ data.regcache = regcache;
+ data.obfd = obfd;
+ data.note_data = note_data;
+ data.note_size = note_size;
+ data.stop_signal = stop_signal;
+ data.abort_iteration = 0;
+ data.lwp = ptid_get_lwp (ptid);
+
+ gdbarch_iterate_over_regset_sections (gdbarch,
+ fbsd_collect_regset_section_cb,
+ &data, regcache);
+ return data.note_data;
+}
+
+struct fbsd_corefile_thread_data
+{
+ struct gdbarch *gdbarch;
+ bfd *obfd;
+ char *note_data;
+ int *note_size;
+ enum gdb_signal stop_signal;
+};
+
+/* Records the thread's register state for the corefile note
+ section. */
+
+static void
+fbsd_corefile_thread (struct thread_info *info,
+ struct fbsd_corefile_thread_data *args)
+{
+ struct cleanup *old_chain;
+ struct regcache *regcache;
+
+ regcache = get_thread_arch_regcache (info->ptid, args->gdbarch);
+
+ old_chain = save_inferior_ptid ();
+ inferior_ptid = info->ptid;
+ target_fetch_registers (regcache, -1);
+ do_cleanups (old_chain);
+
+ args->note_data = fbsd_collect_thread_registers
+ (regcache, info->ptid, args->obfd, args->note_data,
+ args->note_size, args->stop_signal);
}
/* Create appropriate note sections for a corefile, returning them in
@@ -130,10 +188,10 @@ fbsd_collect_regset_section_cb (const char *sect_name, int size,
static char *
fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
{
- struct regcache *regcache = get_current_regcache ();
- char *note_data;
+ struct fbsd_corefile_thread_data thread_args;
+ char *note_data = NULL;
Elf_Internal_Ehdr *i_ehdrp;
- struct fbsd_collect_regset_section_cb_data data;
+ struct thread_info *curr_thr, *signalled_thr, *thr;
/* Put a "FreeBSD" label in the ELF header. */
i_ehdrp = elf_elfheader (obfd);
@@ -141,16 +199,6 @@ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
gdb_assert (gdbarch_iterate_over_regset_sections_p (gdbarch));
- data.regcache = regcache;
- data.obfd = obfd;
- data.note_data = NULL;
- data.note_size = note_size;
- target_fetch_registers (regcache, -1);
- gdbarch_iterate_over_regset_sections (gdbarch,
- fbsd_collect_regset_section_cb,
- &data, regcache);
- note_data = data.note_data;
-
if (get_exec_file (0))
{
const char *fname = lbasename (get_exec_file (0));
@@ -164,6 +212,50 @@ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
fname, psargs);
}
+ /* Thread register information. */
+ TRY
+ {
+ update_thread_list ();
+ }
+ CATCH (e, RETURN_MASK_ERROR)
+ {
+ exception_print (gdb_stderr, e);
+ }
+ END_CATCH
+
+ /* Like the kernel, prefer dumping the signalled thread first.
+ "First thread" is what tools use to infer the signalled thread.
+ In case there's more than one signalled thread, prefer the
+ current thread, if it is signalled. */
+ curr_thr = inferior_thread ();
+ if (curr_thr->suspend.stop_signal != GDB_SIGNAL_0)
+ signalled_thr = curr_thr;
+ else
+ {
+ signalled_thr = iterate_over_threads (find_signalled_thread, NULL);
+ if (signalled_thr == NULL)
+ signalled_thr = curr_thr;
+ }
+
+ thread_args.gdbarch = gdbarch;
+ thread_args.obfd = obfd;
+ thread_args.note_data = note_data;
+ thread_args.note_size = note_size;
+ thread_args.stop_signal = signalled_thr->suspend.stop_signal;
+
+ fbsd_corefile_thread (signalled_thr, &thread_args);
+ ALL_NON_EXITED_THREADS (thr)
+ {
+ if (thr == signalled_thr)
+ continue;
+ if (ptid_get_pid (thr->ptid) != ptid_get_pid (inferior_ptid))
+ continue;
+
+ fbsd_corefile_thread (thr, &thread_args);
+ }
+
+ note_data = thread_args.note_data;
+
return note_data;
}
--
2.7.0
reply other threads:[~2016-01-11 23:25 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1825615.K1HYhKRaB2@ralph.baldwin.cx \
--to=jhb@freebsd.org \
--cc=binutils@sourceware.org \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).