Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* Re: RFC: handle new NT_SIGINFO note in gdb
       [not found] <878vanyj3k.fsf__16012.8015945249$1351617533$gmane$org@fleche.redhat.com>
@ 2012-11-01 19:01 ` Tom Tromey
  2012-11-02 18:21   ` Tom Tromey
  0 siblings, 1 reply; 9+ messages in thread
From: Tom Tromey @ 2012-11-01 19:01 UTC (permalink / raw)
  To: gdb-patches

>>>>> "Tom" == Tom Tromey <tromey@redhat.com> writes:

Tom> This patch adds support for the new Linux NT_SIGINFO core note to gdb.

Pedro pointed out that this patch doesn't ensure that $_siginfo is
attached to the correct thread.

I have a fix for this but I am looking into writing a multi-threaded
test case before resubmitting.

Tom


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: RFC: handle new NT_SIGINFO note in gdb
  2012-11-01 19:01 ` RFC: handle new NT_SIGINFO note in gdb Tom Tromey
@ 2012-11-02 18:21   ` Tom Tromey
  2012-11-02 19:02     ` Pedro Alves
  0 siblings, 1 reply; 9+ messages in thread
From: Tom Tromey @ 2012-11-02 18:21 UTC (permalink / raw)
  To: gdb-patches

>>>>> "Tom" == Tom Tromey <tromey@redhat.com> writes:

Tom> Pedro pointed out that this patch doesn't ensure that $_siginfo is
Tom> attached to the correct thread.

Tom> I have a fix for this but I am looking into writing a multi-threaded
Tom> test case before resubmitting.

Here is an updated patch.

It differs from the original patch in that it associates each NT_SIGINFO
note with the relevant thread.

There is a new multi-threaded test case included as well.  Note that
when a core is generated by gdb, each thread has a $_siginfo -- threads
stopped by gdb will show SIGSTOP.

Built and regtested on x86-64 Fedora 16.  I also tried this manually
against a kernel made by a relatively recent Linux kernel.

Tom

2012-11-02  Tom Tromey  <tromey@redhat.com>

	* elf.c (elfcore_grok_note) <NT_SIGINFO>: New case; make
	pseudosection.

2012-11-02  Tom Tromey  <tromey@redhat.com>

	* linux-tdep.c (linux_make_siginfo_note): New function.
	(linux_make_corefile_notes): Use it.
	* corelow.c (get_core_siginfo): New function.
	(core_xfer_partial) <TARGET_OBJECT_SIGNAL_INFO>: New case.

2012-11-02  Tom Tromey  <tromey@redhat.com>

	* gdb.base/siginfo-obj.exp: Create core file.  Test siginfo from
	core files, if possible.
	* gdb.base/siginfo-thread.c: New file
	* gdb.base/siginfo-thread.exp: New file

---
 bfd/ChangeLog                             |    5 +
 bfd/elf.c                                 |    4 +
 gdb/ChangeLog                             |    7 ++
 gdb/corelow.c                             |   35 ++++++++
 gdb/linux-tdep.c                          |   56 +++++++++++++
 gdb/testsuite/ChangeLog                   |    7 ++
 gdb/testsuite/gdb.base/siginfo-obj.exp    |   22 +++++
 gdb/testsuite/gdb.base/siginfo-thread.c   |   83 +++++++++++++++++++
 gdb/testsuite/gdb.base/siginfo-thread.exp |  122 +++++++++++++++++++++++++++++
 9 files changed, 341 insertions(+), 0 deletions(-)
 create mode 100644 gdb/testsuite/gdb.base/siginfo-thread.c
 create mode 100644 gdb/testsuite/gdb.base/siginfo-thread.exp

diff --git a/bfd/elf.c b/bfd/elf.c
index cab1cc7..4465f48 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -8604,6 +8604,10 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
 
 	return TRUE;
       }
+
+    case NT_SIGINFO:
+      return elfcore_make_note_pseudosection (abfd, ".note.linuxcore.siginfo",
+					      note);
     }
 }
 
diff --git a/gdb/corelow.c b/gdb/corelow.c
index 2080068..99611ba 100644
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -656,6 +656,36 @@ add_to_spuid_list (bfd *abfd, asection *asect, void *list_p)
   list->pos += 4;
 }
 
+/* Read siginfo data from the core, if possible.  Returns -1 on
+   failure.  Otherwise, returns the number of bytes read.  ABFD is the
+   core file's BFD; READBUF, OFFSET, and LEN are all as specified by
+   the to_xfer_partial interface.  */
+
+static LONGEST
+get_core_siginfo (bfd *abfd, gdb_byte *readbuf, ULONGEST offset, LONGEST len)
+{
+  asection *section;
+  long pid;
+  char *section_name;
+  const char *name = ".note.linuxcore.siginfo";
+
+  if (ptid_get_lwp (inferior_ptid))
+    section_name = xstrprintf ("%s/%ld", name,
+			       ptid_get_lwp (inferior_ptid));
+  else
+    section_name = xstrdup (name);
+
+  section = bfd_get_section_by_name (abfd, section_name);
+  xfree (section_name);
+  if (section == NULL)
+    return -1;
+
+  if (!bfd_get_section_contents (abfd, section, readbuf, offset, len))
+    return -1;
+
+  return len;
+}
+
 static LONGEST
 core_xfer_partial (struct target_ops *ops, enum target_object object,
 		   const char *annex, gdb_byte *readbuf,
@@ -794,6 +824,11 @@ core_xfer_partial (struct target_ops *ops, enum target_object object,
 	}
       return -1;
 
+    case TARGET_OBJECT_SIGNAL_INFO:
+      if (readbuf)
+	return get_core_siginfo (core_bfd, readbuf, offset, len);
+      return -1;
+
     default:
       if (ops->beneath != NULL)
 	return ops->beneath->to_xfer_partial (ops->beneath, object,
diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
index 65f5f97..f02d510 100644
--- a/gdb/linux-tdep.c
+++ b/gdb/linux-tdep.c
@@ -765,6 +765,44 @@ linux_collect_thread_registers (const struct regcache *regcache,
   return note_data;
 }
 
+/* Fetch the siginfo data for the current thread, if it exists.  If
+   there is no data, or we could not read it, return NULL.  Otherwise,
+   return a newly malloc'd buffer holding the data and fill in *SIZE
+   with the size of the data.  The caller is responsible for freeing
+   the data.  */
+
+static gdb_byte *
+linux_get_siginfo_data (struct gdbarch *gdbarch, LONGEST *size)
+{
+  struct type *siginfo_type;
+  gdb_byte *buf;
+  LONGEST bytes_read;
+  struct cleanup *cleanups;
+
+  if (!gdbarch_get_siginfo_type_p (gdbarch))
+    return NULL;
+  
+  siginfo_type = gdbarch_get_siginfo_type (gdbarch);
+
+  buf = xmalloc (TYPE_LENGTH (siginfo_type));
+  cleanups = make_cleanup (xfree, buf);
+
+  bytes_read = target_read (&current_target, TARGET_OBJECT_SIGNAL_INFO, NULL,
+			    buf, 0, TYPE_LENGTH (siginfo_type));
+  if (bytes_read == TYPE_LENGTH (siginfo_type))
+    {
+      discard_cleanups (cleanups);
+      *size = bytes_read;
+    }
+  else
+    {
+      do_cleanups (cleanups);
+      buf = NULL;
+    }
+
+  return buf;
+}
+
 struct linux_corefile_thread_data
 {
   struct gdbarch *gdbarch;
@@ -789,17 +827,35 @@ linux_corefile_thread_callback (struct thread_info *info, void *data)
     {
       struct cleanup *old_chain;
       struct regcache *regcache;
+      gdb_byte *siginfo_data;
+      LONGEST siginfo_size;
+
       regcache = get_thread_arch_regcache (info->ptid, args->gdbarch);
 
       old_chain = save_inferior_ptid ();
       inferior_ptid = info->ptid;
       target_fetch_registers (regcache, -1);
+      siginfo_data = linux_get_siginfo_data (args->gdbarch, &siginfo_size);
       do_cleanups (old_chain);
 
+      old_chain = make_cleanup (xfree, siginfo_data);
+
       args->note_data = args->collect (regcache, info->ptid, args->obfd,
 				       args->note_data, args->note_size,
 				       args->stop_signal);
       args->num_notes++;
+
+      if (siginfo_data != NULL)
+	{
+	  args->note_data = elfcore_write_note (args->obfd,
+						args->note_data,
+						args->note_size,
+						"CORE", NT_SIGINFO,
+						siginfo_data, siginfo_size);
+	  args->num_notes++;
+	}
+
+      do_cleanups (old_chain);
     }
 
   return !args->note_data;
diff --git a/gdb/testsuite/gdb.base/siginfo-obj.exp b/gdb/testsuite/gdb.base/siginfo-obj.exp
index 9ca649d..c6ab6ff 100644
--- a/gdb/testsuite/gdb.base/siginfo-obj.exp
+++ b/gdb/testsuite/gdb.base/siginfo-obj.exp
@@ -56,6 +56,10 @@ if { ![runto_main] } then {
 # Run to the signal.
 gdb_test "continue" ".*Program received signal SIGSEGV.*" "continue to signal"
 
+# Try to generate a core file, for a later test.
+set gcorefile [standard_output_file $testfile.gcore]
+set gcore_created [gdb_gcore_cmd $gcorefile "save a core file"]
+
 set ssi_addr ""
 set test "Extract si_addr"
 gdb_test_multiple "p \$_siginfo" "$test" {
@@ -123,3 +127,21 @@ gdb_test "p ssi_addr" " = \\(void \\*\\) 0x666"
 gdb_test "p ssi_errno" " = 666"
 gdb_test "p ssi_code" " = 999"
 gdb_test "p ssi_signo" " = 11"
+
+# Test siginfo preservation in core files.
+if {$gcore_created} {
+    clean_restart $binfile
+
+    gdb_test "core $gcorefile" "Core was generated by.*" \
+	"core [file tail $gcorefile]"
+
+    gdb_test "p \$_siginfo.si_signo" " = $ssi_signo" \
+	"p \$_siginfo.si_signo from core file"
+    gdb_test "p \$_siginfo.si_errno" " = $ssi_errno" \
+	"p \$_siginfo.si_errno from core file"
+    gdb_test "p \$_siginfo.si_code" " = $ssi_code" \
+	"p \$_siginfo.si_code from core file"
+    gdb_test "p \$_siginfo._sifields._sigfault.si_addr" \
+	" = \\(void \\*\\) $ssi_addr" \
+	"p \$_siginfo._sifields._sigfault.si_addr from core file"
+}
diff --git a/gdb/testsuite/gdb.base/siginfo-thread.c b/gdb/testsuite/gdb.base/siginfo-thread.c
new file mode 100644
index 0000000..a47bcb3
--- /dev/null
+++ b/gdb/testsuite/gdb.base/siginfo-thread.c
@@ -0,0 +1,83 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2004, 2007-2008, 2010-2012 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <pthread.h>
+
+static void *p;
+
+static void
+handler (int sig, siginfo_t *info, void *context)
+{
+  /* Copy to local vars, as the test wants to read them, and si_addr,
+     etc. may be preprocessor defines.  */
+  int ssi_errno = info->si_errno;
+  int ssi_signo = info->si_signo;
+  int ssi_code = info->si_code;
+  void *ssi_addr = info->si_addr;
+
+  _exit (0); /* set breakpoint here */
+}
+
+static void *
+segv_thread (void *ptr)
+{
+  *(int *)ptr = 0;
+}
+
+int
+main (void)
+{
+  pthread_t thr;
+
+  /* Set up unwritable memory.  */
+  {
+    size_t len;
+    len = sysconf(_SC_PAGESIZE);
+    p = mmap (0, len, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
+    if (p == MAP_FAILED)
+      {
+	perror ("mmap");
+	return 1;
+      }
+  }
+  /* Set up the signal handler.  */
+  {
+    struct sigaction action;
+    memset (&action, 0, sizeof (action));
+    action.sa_sigaction = handler;
+    action.sa_flags |= SA_SIGINFO;
+    if (sigaction (SIGSEGV, &action, NULL))
+      {
+	perror ("sigaction");
+	return 1;
+      }
+  }
+
+  /* Create a thread that will trigger SIGSEGV.  */
+  pthread_create (&thr, NULL, segv_thread, p);
+
+  pthread_join (thr, NULL);
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/siginfo-thread.exp b/gdb/testsuite/gdb.base/siginfo-thread.exp
new file mode 100644
index 0000000..194d856
--- /dev/null
+++ b/gdb/testsuite/gdb.base/siginfo-thread.exp
@@ -0,0 +1,122 @@
+# Copyright 2004, 2007-2008, 2010-2012 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+# Multi-threaded siginfo test.
+
+if [target_info exists gdb,nosignals] {
+    verbose "Skipping siginfo-thread.exp because of nosignals."
+    continue
+}
+
+if { ! [istarget "i?86-*-linux*"]
+     && ! [istarget "x86_64-*-linux*"]
+     && ! [istarget "arm*-*-linux*"] } {
+    verbose "Skipping siginfo-thread.exp because of lack of support."
+    return
+}
+
+standard_testfile .c
+
+if  {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" \
+	  "${binfile}" executable {debug}] != "" } {
+    return -1
+}
+
+clean_restart $binfile
+
+# Advance to main
+if { ![runto_main] } then {
+    gdb_suppress_tests
+}
+
+# Run to the signal.
+gdb_test "continue" ".*Program received signal SIGSEGV.*" "continue to signal"
+
+# Try to generate a core file, for a later test.
+set gcorefile [standard_output_file $testfile.gcore]
+set gcore_created [gdb_gcore_cmd $gcorefile "save a core file"]
+
+set ssi_addr ""
+set test "Extract si_addr"
+gdb_test_multiple "p \$_siginfo" "$test" {
+    -re "si_addr = ($hex).*$gdb_prompt $" {
+	set ssi_addr $expect_out(1,string)
+	pass "$test"
+    }
+}
+
+set test "Extract si_errno"
+gdb_test_multiple "p \$_siginfo" "$test" {
+    -re "si_errno = (\[0-9\]\+).*$gdb_prompt $" {
+	set ssi_errno $expect_out(1,string)
+	pass "$test"
+    }
+}
+
+set test "Extract si_code"
+gdb_test_multiple "p \$_siginfo" "$test" {
+    -re "si_code = (\[0-9\]\+).*$gdb_prompt $" {
+	set ssi_code $expect_out(1,string)
+	pass "$test"
+    }
+}
+
+set test "Extract si_signo"
+gdb_test_multiple "p \$_siginfo" "$test" {
+    -re "si_signo = (\[0-9\]\+).*$gdb_prompt $" {
+	set ssi_signo $expect_out(1,string)
+	pass "$test"
+    }
+}
+
+set bp_location [gdb_get_line_number "set breakpoint here"]
+
+gdb_test "break $bp_location"
+gdb_test "continue" ".* handler .*" "continue to handler"
+
+gdb_test "p ssi_addr" " = \\(void \\*\\) $ssi_addr"
+gdb_test "p ssi_errno" " = $ssi_errno"
+gdb_test "p ssi_code" " = $ssi_code"
+gdb_test "p ssi_signo" " = $ssi_signo"
+
+gdb_test "thread 1" ".*"
+# siginfo is available here -- it shows SIGSTOP -- so we test to make
+# sure that we have a different signal from the SEGV thread.
+gdb_test "p \$_siginfo.si_signo == $ssi_errno" " = 0" \
+    "test signal in main thread"
+
+# Test siginfo preservation in core files.
+if {$gcore_created} {
+    clean_restart $binfile
+
+    gdb_test "core $gcorefile" "Core was generated by.*" \
+	"core [file tail $gcorefile]"
+
+    gdb_test "p \$_siginfo.si_signo" " = $ssi_signo" \
+	"p \$_siginfo.si_signo from core file"
+    gdb_test "p \$_siginfo.si_errno" " = $ssi_errno" \
+	"p \$_siginfo.si_errno from core file"
+    gdb_test "p \$_siginfo.si_code" " = $ssi_code" \
+	"p \$_siginfo.si_code from core file"
+    gdb_test "p \$_siginfo._sifields._sigfault.si_addr" \
+	" = \\(void \\*\\) $ssi_addr" \
+	"p \$_siginfo._sifields._sigfault.si_addr from core file"
+
+    # The signalled thread always shows up as thread 1.
+    gdb_test "thread 2" ".*" "switch threads with core file"
+    gdb_test "p \$_siginfo.si_signo == $ssi_errno" " = 0" \
+	"test signal in main thread with core file"
+}
-- 
1.7.7.6


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: RFC: handle new NT_SIGINFO note in gdb
  2012-11-02 18:21   ` Tom Tromey
@ 2012-11-02 19:02     ` Pedro Alves
  2012-11-02 19:32       ` Tom Tromey
  0 siblings, 1 reply; 9+ messages in thread
From: Pedro Alves @ 2012-11-02 19:02 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

Looks mostly good to me.  Thanks.

On 11/02/2012 06:21 PM, Tom Tromey wrote:> +gdb_test "thread 1" ".*"
> +# siginfo is available here -- it shows SIGSTOP -- so we test to make
> +# sure that we have a different signal from the SEGV thread.
> +gdb_test "p \$_siginfo.si_signo == $ssi_errno" " = 0" \
> +    "test signal in main thread"

I think here should be $ssi_signo, not $ssi_errno.

> +    # The signalled thread always shows up as thread 1.
> +    gdb_test "thread 2" ".*" "switch threads with core file"
> +    gdb_test "p \$_siginfo.si_signo == $ssi_errno" " = 0" \
> +	"test signal in main thread with core file"

Ditto.

> +    # The signalled thread always shows up as thread 1.
> +    gdb_test "thread 2" ".*" "switch threads with core file"

Note this is actually more of an accident than GDB making sure that
always happens.  GDB makes no effort to make sure the the signaled thread
is the first dumped thread.  GDB's internal thread list is ordered
newer->older, and since thread 2 is the one that crashes, and is
the newest, that thread ends up appearing first in the core, and hence
when gdb loads the core, it ends up as selected thread.  If it was
thread 1 that crashed, thread 2 in the running program would
still end up as thread 1 in the core.  (It just tried that, with a
pristine mainline).

-- 
Pedro Alves


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: RFC: handle new NT_SIGINFO note in gdb
  2012-11-02 19:02     ` Pedro Alves
@ 2012-11-02 19:32       ` Tom Tromey
  2012-11-05 18:11         ` Pedro Alves
  0 siblings, 1 reply; 9+ messages in thread
From: Tom Tromey @ 2012-11-02 19:32 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:

Pedro> I think here should be $ssi_signo, not $ssi_errno.

Sad oversight on my part.  Thanks.

Pedro> GDB makes no effort to make sure the the signaled thread
Pedro> is the first dumped thread.

Thanks.

Here's an update.  This takes a bit of a brute force approach to testing
that just one thread got a SEGV.

Tom

2012-11-02  Tom Tromey  <tromey@redhat.com>

	* elf.c (elfcore_grok_note) <NT_SIGINFO>: New case; make
	pseudosection.

2012-11-02  Tom Tromey  <tromey@redhat.com>

	* linux-tdep.c (linux_make_siginfo_note): New function.
	(linux_make_corefile_notes): Use it.
	* corelow.c (get_core_siginfo): New function.
	(core_xfer_partial) <TARGET_OBJECT_SIGNAL_INFO>: New case.

2012-11-02  Tom Tromey  <tromey@redhat.com>

	* gdb.base/siginfo-obj.exp: Create core file.  Test siginfo from
	core files, if possible.
	* gdb.base/siginfo-thread.c: New file
	* gdb.base/siginfo-thread.exp: New file

---
 bfd/ChangeLog                             |    5 +
 bfd/elf.c                                 |    4 +
 gdb/ChangeLog                             |    7 ++
 gdb/corelow.c                             |   35 ++++++++
 gdb/linux-tdep.c                          |   56 +++++++++++++
 gdb/testsuite/ChangeLog                   |    7 ++
 gdb/testsuite/gdb.base/siginfo-obj.exp    |   22 +++++
 gdb/testsuite/gdb.base/siginfo-thread.c   |   83 +++++++++++++++++++
 gdb/testsuite/gdb.base/siginfo-thread.exp |  128 +++++++++++++++++++++++++++++
 9 files changed, 347 insertions(+), 0 deletions(-)
 create mode 100644 gdb/testsuite/gdb.base/siginfo-thread.c
 create mode 100644 gdb/testsuite/gdb.base/siginfo-thread.exp

diff --git a/bfd/elf.c b/bfd/elf.c
index cab1cc7..4465f48 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -8604,6 +8604,10 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
 
 	return TRUE;
       }
+
+    case NT_SIGINFO:
+      return elfcore_make_note_pseudosection (abfd, ".note.linuxcore.siginfo",
+					      note);
     }
 }
 
diff --git a/gdb/corelow.c b/gdb/corelow.c
index 2080068..99611ba 100644
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -656,6 +656,36 @@ add_to_spuid_list (bfd *abfd, asection *asect, void *list_p)
   list->pos += 4;
 }
 
+/* Read siginfo data from the core, if possible.  Returns -1 on
+   failure.  Otherwise, returns the number of bytes read.  ABFD is the
+   core file's BFD; READBUF, OFFSET, and LEN are all as specified by
+   the to_xfer_partial interface.  */
+
+static LONGEST
+get_core_siginfo (bfd *abfd, gdb_byte *readbuf, ULONGEST offset, LONGEST len)
+{
+  asection *section;
+  long pid;
+  char *section_name;
+  const char *name = ".note.linuxcore.siginfo";
+
+  if (ptid_get_lwp (inferior_ptid))
+    section_name = xstrprintf ("%s/%ld", name,
+			       ptid_get_lwp (inferior_ptid));
+  else
+    section_name = xstrdup (name);
+
+  section = bfd_get_section_by_name (abfd, section_name);
+  xfree (section_name);
+  if (section == NULL)
+    return -1;
+
+  if (!bfd_get_section_contents (abfd, section, readbuf, offset, len))
+    return -1;
+
+  return len;
+}
+
 static LONGEST
 core_xfer_partial (struct target_ops *ops, enum target_object object,
 		   const char *annex, gdb_byte *readbuf,
@@ -794,6 +824,11 @@ core_xfer_partial (struct target_ops *ops, enum target_object object,
 	}
       return -1;
 
+    case TARGET_OBJECT_SIGNAL_INFO:
+      if (readbuf)
+	return get_core_siginfo (core_bfd, readbuf, offset, len);
+      return -1;
+
     default:
       if (ops->beneath != NULL)
 	return ops->beneath->to_xfer_partial (ops->beneath, object,
diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
index 65f5f97..f02d510 100644
--- a/gdb/linux-tdep.c
+++ b/gdb/linux-tdep.c
@@ -765,6 +765,44 @@ linux_collect_thread_registers (const struct regcache *regcache,
   return note_data;
 }
 
+/* Fetch the siginfo data for the current thread, if it exists.  If
+   there is no data, or we could not read it, return NULL.  Otherwise,
+   return a newly malloc'd buffer holding the data and fill in *SIZE
+   with the size of the data.  The caller is responsible for freeing
+   the data.  */
+
+static gdb_byte *
+linux_get_siginfo_data (struct gdbarch *gdbarch, LONGEST *size)
+{
+  struct type *siginfo_type;
+  gdb_byte *buf;
+  LONGEST bytes_read;
+  struct cleanup *cleanups;
+
+  if (!gdbarch_get_siginfo_type_p (gdbarch))
+    return NULL;
+  
+  siginfo_type = gdbarch_get_siginfo_type (gdbarch);
+
+  buf = xmalloc (TYPE_LENGTH (siginfo_type));
+  cleanups = make_cleanup (xfree, buf);
+
+  bytes_read = target_read (&current_target, TARGET_OBJECT_SIGNAL_INFO, NULL,
+			    buf, 0, TYPE_LENGTH (siginfo_type));
+  if (bytes_read == TYPE_LENGTH (siginfo_type))
+    {
+      discard_cleanups (cleanups);
+      *size = bytes_read;
+    }
+  else
+    {
+      do_cleanups (cleanups);
+      buf = NULL;
+    }
+
+  return buf;
+}
+
 struct linux_corefile_thread_data
 {
   struct gdbarch *gdbarch;
@@ -789,17 +827,35 @@ linux_corefile_thread_callback (struct thread_info *info, void *data)
     {
       struct cleanup *old_chain;
       struct regcache *regcache;
+      gdb_byte *siginfo_data;
+      LONGEST siginfo_size;
+
       regcache = get_thread_arch_regcache (info->ptid, args->gdbarch);
 
       old_chain = save_inferior_ptid ();
       inferior_ptid = info->ptid;
       target_fetch_registers (regcache, -1);
+      siginfo_data = linux_get_siginfo_data (args->gdbarch, &siginfo_size);
       do_cleanups (old_chain);
 
+      old_chain = make_cleanup (xfree, siginfo_data);
+
       args->note_data = args->collect (regcache, info->ptid, args->obfd,
 				       args->note_data, args->note_size,
 				       args->stop_signal);
       args->num_notes++;
+
+      if (siginfo_data != NULL)
+	{
+	  args->note_data = elfcore_write_note (args->obfd,
+						args->note_data,
+						args->note_size,
+						"CORE", NT_SIGINFO,
+						siginfo_data, siginfo_size);
+	  args->num_notes++;
+	}
+
+      do_cleanups (old_chain);
     }
 
   return !args->note_data;
diff --git a/gdb/testsuite/gdb.base/siginfo-obj.exp b/gdb/testsuite/gdb.base/siginfo-obj.exp
index 9ca649d..c6ab6ff 100644
--- a/gdb/testsuite/gdb.base/siginfo-obj.exp
+++ b/gdb/testsuite/gdb.base/siginfo-obj.exp
@@ -56,6 +56,10 @@ if { ![runto_main] } then {
 # Run to the signal.
 gdb_test "continue" ".*Program received signal SIGSEGV.*" "continue to signal"
 
+# Try to generate a core file, for a later test.
+set gcorefile [standard_output_file $testfile.gcore]
+set gcore_created [gdb_gcore_cmd $gcorefile "save a core file"]
+
 set ssi_addr ""
 set test "Extract si_addr"
 gdb_test_multiple "p \$_siginfo" "$test" {
@@ -123,3 +127,21 @@ gdb_test "p ssi_addr" " = \\(void \\*\\) 0x666"
 gdb_test "p ssi_errno" " = 666"
 gdb_test "p ssi_code" " = 999"
 gdb_test "p ssi_signo" " = 11"
+
+# Test siginfo preservation in core files.
+if {$gcore_created} {
+    clean_restart $binfile
+
+    gdb_test "core $gcorefile" "Core was generated by.*" \
+	"core [file tail $gcorefile]"
+
+    gdb_test "p \$_siginfo.si_signo" " = $ssi_signo" \
+	"p \$_siginfo.si_signo from core file"
+    gdb_test "p \$_siginfo.si_errno" " = $ssi_errno" \
+	"p \$_siginfo.si_errno from core file"
+    gdb_test "p \$_siginfo.si_code" " = $ssi_code" \
+	"p \$_siginfo.si_code from core file"
+    gdb_test "p \$_siginfo._sifields._sigfault.si_addr" \
+	" = \\(void \\*\\) $ssi_addr" \
+	"p \$_siginfo._sifields._sigfault.si_addr from core file"
+}
diff --git a/gdb/testsuite/gdb.base/siginfo-thread.c b/gdb/testsuite/gdb.base/siginfo-thread.c
new file mode 100644
index 0000000..a47bcb3
--- /dev/null
+++ b/gdb/testsuite/gdb.base/siginfo-thread.c
@@ -0,0 +1,83 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2004, 2007-2008, 2010-2012 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <pthread.h>
+
+static void *p;
+
+static void
+handler (int sig, siginfo_t *info, void *context)
+{
+  /* Copy to local vars, as the test wants to read them, and si_addr,
+     etc. may be preprocessor defines.  */
+  int ssi_errno = info->si_errno;
+  int ssi_signo = info->si_signo;
+  int ssi_code = info->si_code;
+  void *ssi_addr = info->si_addr;
+
+  _exit (0); /* set breakpoint here */
+}
+
+static void *
+segv_thread (void *ptr)
+{
+  *(int *)ptr = 0;
+}
+
+int
+main (void)
+{
+  pthread_t thr;
+
+  /* Set up unwritable memory.  */
+  {
+    size_t len;
+    len = sysconf(_SC_PAGESIZE);
+    p = mmap (0, len, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
+    if (p == MAP_FAILED)
+      {
+	perror ("mmap");
+	return 1;
+      }
+  }
+  /* Set up the signal handler.  */
+  {
+    struct sigaction action;
+    memset (&action, 0, sizeof (action));
+    action.sa_sigaction = handler;
+    action.sa_flags |= SA_SIGINFO;
+    if (sigaction (SIGSEGV, &action, NULL))
+      {
+	perror ("sigaction");
+	return 1;
+      }
+  }
+
+  /* Create a thread that will trigger SIGSEGV.  */
+  pthread_create (&thr, NULL, segv_thread, p);
+
+  pthread_join (thr, NULL);
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/siginfo-thread.exp b/gdb/testsuite/gdb.base/siginfo-thread.exp
new file mode 100644
index 0000000..315ac01
--- /dev/null
+++ b/gdb/testsuite/gdb.base/siginfo-thread.exp
@@ -0,0 +1,128 @@
+# Copyright 2004, 2007-2008, 2010-2012 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+# Multi-threaded siginfo test.
+
+if [target_info exists gdb,nosignals] {
+    verbose "Skipping siginfo-thread.exp because of nosignals."
+    continue
+}
+
+if { ! [istarget "i?86-*-linux*"]
+     && ! [istarget "x86_64-*-linux*"]
+     && ! [istarget "arm*-*-linux*"] } {
+    verbose "Skipping siginfo-thread.exp because of lack of support."
+    return
+}
+
+standard_testfile .c
+
+if  {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" \
+	  "${binfile}" executable {debug}] != "" } {
+    return -1
+}
+
+clean_restart $binfile
+
+# Advance to main
+if { ![runto_main] } then {
+    gdb_suppress_tests
+}
+
+# Run to the signal.
+gdb_test "continue" ".*Program received signal SIGSEGV.*" "continue to signal"
+
+# Try to generate a core file, for a later test.
+set gcorefile [standard_output_file $testfile.gcore]
+set gcore_created [gdb_gcore_cmd $gcorefile "save a core file"]
+
+set ssi_addr ""
+set test "Extract si_addr"
+gdb_test_multiple "p \$_siginfo" "$test" {
+    -re "si_addr = ($hex).*$gdb_prompt $" {
+	set ssi_addr $expect_out(1,string)
+	pass "$test"
+    }
+}
+
+set test "Extract si_errno"
+gdb_test_multiple "p \$_siginfo" "$test" {
+    -re "si_errno = (\[0-9\]\+).*$gdb_prompt $" {
+	set ssi_errno $expect_out(1,string)
+	pass "$test"
+    }
+}
+
+set test "Extract si_code"
+gdb_test_multiple "p \$_siginfo" "$test" {
+    -re "si_code = (\[0-9\]\+).*$gdb_prompt $" {
+	set ssi_code $expect_out(1,string)
+	pass "$test"
+    }
+}
+
+set test "Extract si_signo"
+gdb_test_multiple "p \$_siginfo" "$test" {
+    -re "si_signo = (\[0-9\]\+).*$gdb_prompt $" {
+	set ssi_signo $expect_out(1,string)
+	pass "$test"
+    }
+}
+
+set bp_location [gdb_get_line_number "set breakpoint here"]
+
+gdb_test "break $bp_location"
+gdb_test "continue" ".* handler .*" "continue to handler"
+
+gdb_test "p ssi_addr" " = \\(void \\*\\) $ssi_addr"
+gdb_test "p ssi_errno" " = $ssi_errno"
+gdb_test "p ssi_code" " = $ssi_code"
+gdb_test "p ssi_signo" " = $ssi_signo"
+
+gdb_test "thread 1" ".*"
+# siginfo is available here -- it shows SIGSTOP -- so we test to make
+# sure that we have a different signal from the SEGV thread.
+gdb_test "p \$_siginfo.si_signo == $ssi_signo" " = 0" \
+    "test signal in main thread"
+
+# Test siginfo preservation in core files.
+if {$gcore_created} {
+    clean_restart $binfile
+
+    gdb_test "core $gcorefile" "Core was generated by.*" \
+	"core [file tail $gcorefile]"
+
+    gdb_test "p \$_siginfo.si_signo" " = $ssi_signo" \
+	"p \$_siginfo.si_signo from core file"
+    gdb_test "p \$_siginfo.si_errno" " = $ssi_errno" \
+	"p \$_siginfo.si_errno from core file"
+    gdb_test "p \$_siginfo.si_code" " = $ssi_code" \
+	"p \$_siginfo.si_code from core file"
+    gdb_test "p \$_siginfo._sifields._sigfault.si_addr" \
+	" = \\(void \\*\\) $ssi_addr" \
+	"p \$_siginfo._sifields._sigfault.si_addr from core file"
+
+    # We don't know which thread will be signalled, so we simply
+    # ensure that only one thread got a SEGV.
+    gdb_test_no_output "set variable \$count = 0"
+    foreach thread {1 2} {
+	gdb_test "thread $thread" ".*" "select thread $thread with core file"
+	gdb_test_no_output \
+	    "set variable \$count += (\$_siginfo.si_signo == $ssi_signo)" \
+	    "update counter in thread $thread"
+    }
+    gdb_test "print \$count" " = 1"
+}
-- 
1.7.7.6


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: RFC: handle new NT_SIGINFO note in gdb
  2012-11-02 19:32       ` Tom Tromey
@ 2012-11-05 18:11         ` Pedro Alves
  2012-11-08 21:10           ` Tom Tromey
  0 siblings, 1 reply; 9+ messages in thread
From: Pedro Alves @ 2012-11-05 18:11 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

On 11/02/2012 07:32 PM, Tom Tromey wrote:

> Here's an update.  This takes a bit of a brute force approach to testing
> that just one thread got a SEGV.

Thanks.  Looks fine to me.

-- 
Pedro Alves


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: RFC: handle new NT_SIGINFO note in gdb
  2012-11-05 18:11         ` Pedro Alves
@ 2012-11-08 21:10           ` Tom Tromey
  0 siblings, 0 replies; 9+ messages in thread
From: Tom Tromey @ 2012-11-08 21:10 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

>>>>> "Pedro" == Pedro Alves <palves@redhat.com> writes:

Pedro> On 11/02/2012 07:32 PM, Tom Tromey wrote:
>> Here's an update.  This takes a bit of a brute force approach to testing
>> that just one thread got a SEGV.

Pedro> Thanks.  Looks fine to me.

Thanks.  I am checking it in now.

Tom


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: RFC: handle new NT_SIGINFO note in gdb
  2012-10-30 17:18 Tom Tromey
  2012-10-30 18:31 ` Pedro Alves
@ 2012-11-01  1:12 ` Alan Modra
  1 sibling, 0 replies; 9+ messages in thread
From: Alan Modra @ 2012-11-01  1:12 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches, Binutils Development

On Tue, Oct 30, 2012 at 11:18:07AM -0600, Tom Tromey wrote:
> 	* elf.c (elfcore_grok_note) <NT_SIGINFO>: New case; make
> 	pseudosection.

OK.

-- 
Alan Modra
Australia Development Lab, IBM


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: RFC: handle new NT_SIGINFO note in gdb
  2012-10-30 17:18 Tom Tromey
@ 2012-10-30 18:31 ` Pedro Alves
  2012-11-01  1:12 ` Alan Modra
  1 sibling, 0 replies; 9+ messages in thread
From: Pedro Alves @ 2012-10-30 18:31 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches, Binutils Development

On 10/30/2012 05:18 PM, Tom Tromey wrote:
> This patch adds support for the new Linux NT_SIGINFO core note to gdb.
> 
> First, I've CCd the binutils list because this includes a BFD change.
> In particular, in order to access the note data, I changed BFD to make a
> pseudosection for this new note's data.  This seemed ok based on
> surrounding code; but if some other method is preferred, just let me
> know and I will implement that instead.
> 
> On the gdb side the support is relatively straightforward.
> 

All looks great to me.  Thanks Tom.

> I chose to implement the support directly in corelow, since adding a new
> hook just for this functionality seemed like overkill.
> 
> A new test case is included.  It uses "gcore" and then re-reads the
> siginfo data from the generated core.
> 
> Built and regtested on x86-64 Fedora 16.
> On the binutils side, I remembered this time to run the test suite in
> binutils, gas, and ld.

-- 
Pedro Alves


^ permalink raw reply	[flat|nested] 9+ messages in thread

* RFC: handle new NT_SIGINFO note in gdb
@ 2012-10-30 17:18 Tom Tromey
  2012-10-30 18:31 ` Pedro Alves
  2012-11-01  1:12 ` Alan Modra
  0 siblings, 2 replies; 9+ messages in thread
From: Tom Tromey @ 2012-10-30 17:18 UTC (permalink / raw)
  To: gdb-patches; +Cc: Binutils Development

This patch adds support for the new Linux NT_SIGINFO core note to gdb.

First, I've CCd the binutils list because this includes a BFD change.
In particular, in order to access the note data, I changed BFD to make a
pseudosection for this new note's data.  This seemed ok based on
surrounding code; but if some other method is preferred, just let me
know and I will implement that instead.

On the gdb side the support is relatively straightforward.

I chose to implement the support directly in corelow, since adding a new
hook just for this functionality seemed like overkill.

A new test case is included.  It uses "gcore" and then re-reads the
siginfo data from the generated core.

Built and regtested on x86-64 Fedora 16.
On the binutils side, I remembered this time to run the test suite in
binutils, gas, and ld.

Tom

2012-10-30  Tom Tromey  <tromey@redhat.com>

	* elf.c (elfcore_grok_note) <NT_SIGINFO>: New case; make
	pseudosection.

2012-10-30  Tom Tromey  <tromey@redhat.com>

	* linux-tdep.c (linux_make_siginfo_note): New function.
	(linux_make_corefile_notes): Use it.
	* corelow.c (get_core_siginfo): New function.
	(core_xfer_partial) <TARGET_OBJECT_SIGNAL_INFO>: New case.

2012-10-30  Tom Tromey  <tromey@redhat.com>

	* gdb.base/siginfo-obj.exp: Create core file.  Test siginfo from
	core files, if possible.

---
 bfd/ChangeLog                          |    5 ++++
 bfd/elf.c                              |    4 +++
 gdb/ChangeLog                          |    7 ++++++
 gdb/corelow.c                          |   25 +++++++++++++++++++++
 gdb/linux-tdep.c                       |   38 ++++++++++++++++++++++++++++++++
 gdb/testsuite/ChangeLog                |    5 ++++
 gdb/testsuite/gdb.base/siginfo-obj.exp |   17 ++++++++++++++
 7 files changed, 101 insertions(+), 0 deletions(-)

diff --git a/bfd/elf.c b/bfd/elf.c
index cab1cc7..4465f48 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -8604,6 +8604,10 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
 
 	return TRUE;
       }
+
+    case NT_SIGINFO:
+      return elfcore_make_note_pseudosection (abfd, ".note.linuxcore.siginfo",
+					      note);
     }
 }
 
diff --git a/gdb/corelow.c b/gdb/corelow.c
index 340b149..d2f87cb 100644
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -662,6 +662,26 @@ add_to_spuid_list (bfd *abfd, asection *asect, void *list_p)
   list->pos += 4;
 }
 
+/* Read siginfo data from the core, if possible.  Returns -1 on
+   failure.  Otherwise, returns the number of bytes read.  ABFD is the
+   core file's BFD; READBUF, OFFSET, and LEN are all as specified by
+   the to_xfer_partial interface.  */
+
+static LONGEST
+get_core_siginfo (bfd *abfd, gdb_byte *readbuf, ULONGEST offset, LONGEST len)
+{
+  asection *section;
+
+  section = bfd_get_section_by_name (abfd, ".note.linuxcore.siginfo");
+  if (section == NULL)
+    return -1;
+
+  if (!bfd_get_section_contents (abfd, section, readbuf, offset, len))
+    return -1;
+
+  return len;
+}
+
 static LONGEST
 core_xfer_partial (struct target_ops *ops, enum target_object object,
 		   const char *annex, gdb_byte *readbuf,
@@ -800,6 +820,11 @@ core_xfer_partial (struct target_ops *ops, enum target_object object,
 	}
       return -1;
 
+    case TARGET_OBJECT_SIGNAL_INFO:
+      if (readbuf)
+	return get_core_siginfo (core_bfd, readbuf, offset, len);
+      return -1;
+
     default:
       if (ops->beneath != NULL)
 	return ops->beneath->to_xfer_partial (ops->beneath, object,
diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
index 65f5f97..f6408b6 100644
--- a/gdb/linux-tdep.c
+++ b/gdb/linux-tdep.c
@@ -712,6 +712,41 @@ linux_spu_make_corefile_notes (bfd *obfd, char *note_data, int *note_size)
   return note_data;
 }
 
+/* Write the core note for siginfo data, if it exists.
+   GDBARCH is the architecture to use.
+   OBFD is the output BFD.
+   NOTE_DATA is the current note data.
+   NOTE_SIZE is an in-out parameter holding the current note size.
+   This returns the new note data pointer.  */
+
+static char *
+linux_make_siginfo_note (struct gdbarch *gdbarch, bfd *obfd,
+			 char *note_data, int *note_size)
+{
+  struct type *siginfo_type;
+  gdb_byte *buf;
+  LONGEST bytes_read;
+  struct cleanup *cleanups;
+
+  if (!gdbarch_get_siginfo_type_p (gdbarch))
+    return note_data;
+  
+  siginfo_type = gdbarch_get_siginfo_type (gdbarch);
+
+  buf = xmalloc (TYPE_LENGTH (siginfo_type));
+  cleanups = make_cleanup (xfree, buf);
+
+  bytes_read = target_read (&current_target, TARGET_OBJECT_SIGNAL_INFO, NULL,
+			    buf, 0, TYPE_LENGTH (siginfo_type));
+  if (bytes_read == TYPE_LENGTH (siginfo_type))
+    note_data = elfcore_write_note (obfd, note_data, note_size,
+				    "CORE", NT_SIGINFO,
+				    buf, bytes_read);
+
+  do_cleanups (cleanups);
+  return note_data;
+}
+
 /* Records the thread's register state for the corefile note
    section.  */
 
@@ -867,6 +902,9 @@ linux_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size,
   if (!note_data)
     return NULL;
 
+  /* Siginfo.  */
+  note_data = linux_make_siginfo_note (gdbarch, obfd, note_data, note_size);
+
   make_cleanup (xfree, note_data);
   return note_data;
 }
diff --git a/gdb/testsuite/gdb.base/siginfo-obj.exp b/gdb/testsuite/gdb.base/siginfo-obj.exp
index 9ca649d..75e76ff 100644
--- a/gdb/testsuite/gdb.base/siginfo-obj.exp
+++ b/gdb/testsuite/gdb.base/siginfo-obj.exp
@@ -56,6 +56,10 @@ if { ![runto_main] } then {
 # Run to the signal.
 gdb_test "continue" ".*Program received signal SIGSEGV.*" "continue to signal"
 
+# Try to generate a core file, for a later test.
+set gcorefile [standard_output_file $testfile.gcore]
+set gcore_created [gdb_gcore_cmd $gcorefile "save a core file"]
+
 set ssi_addr ""
 set test "Extract si_addr"
 gdb_test_multiple "p \$_siginfo" "$test" {
@@ -123,3 +127,16 @@ gdb_test "p ssi_addr" " = \\(void \\*\\) 0x666"
 gdb_test "p ssi_errno" " = 666"
 gdb_test "p ssi_code" " = 999"
 gdb_test "p ssi_signo" " = 11"
+
+# Test siginfo preservation in core files.
+if {$gcore_created} {
+    clean_restart $binfile
+
+    gdb_test "core $gcorefile" "Core was generated by.*"
+
+    gdb_test "p \$_siginfo.si_signo" " = $ssi_signo"
+    gdb_test "p \$_siginfo.si_errno" " = $ssi_errno"
+    gdb_test "p \$_siginfo.si_code" " = $ssi_code"
+    gdb_test "p \$_siginfo._sifields._sigfault.si_addr" \
+	" = \\(void \\*\\) $ssi_addr"
+}
-- 
1.7.7.6


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2012-11-08 21:10 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <878vanyj3k.fsf__16012.8015945249$1351617533$gmane$org@fleche.redhat.com>
2012-11-01 19:01 ` RFC: handle new NT_SIGINFO note in gdb Tom Tromey
2012-11-02 18:21   ` Tom Tromey
2012-11-02 19:02     ` Pedro Alves
2012-11-02 19:32       ` Tom Tromey
2012-11-05 18:11         ` Pedro Alves
2012-11-08 21:10           ` Tom Tromey
2012-10-30 17:18 Tom Tromey
2012-10-30 18:31 ` Pedro Alves
2012-11-01  1:12 ` Alan Modra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox