This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch 8/9]#2 Fix $_siginfo content for multiple threads


series #2 of: http://sourceware.org/ml/gdb-patches/2010-07/msg00411.html

Hi,

here is a fix of $_siginfo to contain the real signal information.  With the
various resubmits of signals across threads I found when I am interested in
$_siginfo it unfortunately contains incorrect information (commonly about
SIGSTOP).


Thanks,
Jan


gdb/
2010-08-30  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* linux-nat.c (linux_xfer_siginfo): Remove variables pid, siginfo and
	inf_siginfo.  New variables siginfop, siginfop_len, gdbarch.  Use
	inferior_thread ()->stop_signal instead of ptrace.  No longer call
	siginfo_fixup.

gdb/testsuite/
2010-08-30  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.threads/siginfo-threads.exp (handle SIGUSR1 nostop print pass)
	(handle SIGUSR2 nostop print pass): Set them to stop.
	(get pid, catch signal $sigcount, signal $sigcount si_signo)
	(signal $sigcount si_code is SI_TKILL, signal $sigcount si_pid): New
	tests.

--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -4069,52 +4069,31 @@ linux_xfer_siginfo (struct target_ops *ops, enum target_object object,
                     const char *annex, gdb_byte *readbuf,
 		    const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
 {
-  int pid;
-  struct siginfo siginfo;
-  gdb_byte inf_siginfo[MAX_SIGINFO_SIZE];
+  gdb_byte *siginfop;
+  size_t siginfop_len;
+  struct gdbarch *gdbarch;
 
   gdb_assert (object == TARGET_OBJECT_SIGNAL_INFO);
   gdb_assert (readbuf || writebuf);
 
-  pid = GET_LWP (inferior_ptid);
-  if (pid == 0)
-    pid = GET_PID (inferior_ptid);
-
-  if (offset > sizeof (siginfo))
+  if (! target_signal_siginfo_p (&inferior_thread ()->stop_signal))
     return -1;
 
-  errno = 0;
-  ptrace (PTRACE_GETSIGINFO, pid, (PTRACE_TYPE_ARG3) 0, &siginfo);
-  if (errno != 0)
-    return -1;
+  gdbarch = target_thread_architecture (inferior_ptid);
+  siginfop = target_signal_siginfo_get (&inferior_thread ()->stop_signal,
+					gdbarch);
+  siginfop_len = target_signal_siginfo_len (gdbarch);
 
-  /* When GDB is built as a 64-bit application, ptrace writes into
-     SIGINFO an object with 64-bit layout.  Since debugging a 32-bit
-     inferior with a 64-bit GDB should look the same as debugging it
-     with a 32-bit GDB, we need to convert it.  GDB core always sees
-     the converted layout, so any read/write will have to be done
-     post-conversion.  */
-  siginfo_fixup (&siginfo, inf_siginfo, 0,
-		 get_frame_arch (get_current_frame ()));
+  if (offset > siginfop_len)
+    return -1;
 
-  if (offset + len > sizeof (siginfo))
-    len = sizeof (siginfo) - offset;
+  if (offset + len > siginfop_len)
+    len = siginfop_len - offset;
 
   if (readbuf != NULL)
-    memcpy (readbuf, inf_siginfo + offset, len);
+    memcpy (readbuf, siginfop + offset, len);
   else
-    {
-      memcpy (inf_siginfo + offset, writebuf, len);
-
-      /* Convert back to ptrace layout before flushing it out.  */
-      siginfo_fixup (&siginfo, inf_siginfo, 1,
-		     get_frame_arch (get_current_frame ()));
-
-      errno = 0;
-      ptrace (PTRACE_SETSIGINFO, pid, (PTRACE_TYPE_ARG3) 0, &siginfo);
-      if (errno != 0)
-	return -1;
-    }
+    memcpy (siginfop + offset, writebuf, len);
 
   return len;
 }
--- a/gdb/testsuite/gdb.threads/siginfo-threads.exp
+++ b/gdb/testsuite/gdb.threads/siginfo-threads.exp
@@ -29,8 +29,8 @@ if ![runto_main] {
 # `nostop noprint pass' could in some cases report false PASS due to the
 # (preempt 'handle') code path.
 
-gdb_test "handle SIGUSR1 nostop print pass" "Signal\[ \t\]+Stop\[ \t\]+Print\[ \t\]+Pass to program\[ \t\]+Description\r\nSIGUSR1\[ \t\]+No\[ \t\]+Yes\[ \t\]+Yes\[ \t\]+User defined signal 1"
-gdb_test "handle SIGUSR2 nostop print pass" "Signal\[ \t\]+Stop\[ \t\]+Print\[ \t\]+Pass to program\[ \t\]+Description\r\nSIGUSR2\[ \t\]+No\[ \t\]+Yes\[ \t\]+Yes\[ \t\]+User defined signal 2"
+gdb_test "handle SIGUSR1 stop print pass" "Signal\[ \t\]+Stop\[ \t\]+Print\[ \t\]+Pass to program\[ \t\]+Description\r\nSIGUSR1\[ \t\]+Yes\[ \t\]+Yes\[ \t\]+Yes\[ \t\]+User defined signal 1"
+gdb_test "handle SIGUSR2 stop print pass" "Signal\[ \t\]+Stop\[ \t\]+Print\[ \t\]+Pass to program\[ \t\]+Description\r\nSIGUSR2\[ \t\]+Yes\[ \t\]+Yes\[ \t\]+Yes\[ \t\]+User defined signal 2"
 
 gdb_breakpoint [gdb_get_line_number "break-at-exit"]
 
@@ -38,6 +38,67 @@ gdb_breakpoint [gdb_get_line_number "break-at-exit"]
 # Ignore possible: Undefined set debug command: "lin-lwp 1" ...
 gdb_test "set debug lin-lwp 1" ".*"
 
+set test "get pid"
+gdb_test_multiple "p getpid ()" $test {
+    -re " = (\[0-9\]+)\r\n$gdb_prompt $" {
+	set pid $expect_out(1,string)
+	pass $test
+    }
+}
+
+for {set sigcount 0} {$sigcount < 4} {incr sigcount} {
+    set test "catch signal $sigcount"
+    set sigusr ""
+    gdb_test_multiple "continue" $test {
+	-re "KLS: \[^\r\n\]*rt_tgsigqueueinfo" {
+	    unsupported "Missing rt_tgsigqueueinfo kernel support"
+	    set result -1
+	}
+	-re "Program received signal SIGUSR(\[12\]), User defined signal \[12\]\\.\r\n.*\r\n$gdb_prompt $" {
+	    set sigusr $expect_out(1,string)
+	    pass $test
+	}
+    }
+    if {$sigusr == ""} {
+	return -1
+    }
+
+    set test "signal $sigcount si_signo"
+    if {$sigusr == 1} {
+	set signo 10
+    } else {
+	set signo 12
+    }
+    gdb_test_multiple {p $_siginfo.si_signo} $test {
+	-re " = $signo\r\n$gdb_prompt $" {
+	    pass $test
+	}
+	-re "Attempt to extract a component of a value that is not a structure\\.\r\n$gdb_prompt $" {
+	    unsupported $test
+	}
+    }
+
+    set test "signal $sigcount si_code is SI_TKILL"
+    gdb_test_multiple {p $_siginfo.si_code} $test {
+	-re " = -6\r\n$gdb_prompt $" {
+	    pass $test
+	}
+	-re "Attempt to extract a component of a value that is not a structure\\.\r\n$gdb_prompt $" {
+	    unsupported $test
+	}
+    }
+
+    set test "signal $sigcount si_pid"
+    gdb_test_multiple {p $_siginfo._sifields._kill.si_pid} $test {
+	-re " = $pid\r\n$gdb_prompt $" {
+	    pass $test
+	}
+	-re "Attempt to extract a component of a value that is not a structure\\.\r\n$gdb_prompt $" {
+	    unsupported $test
+	}
+    }
+}
+
 set test "continue to break-at-exit"
 gdb_test_multiple "continue" $test {
     -re "KLS: \[^\r\n\]*rt_tgsigqueueinfo" {


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]