rpms/gdb/devel gdb-6.6-bz233852-attach-signalled.patch, NONE, 1.1 gdb.spec, 1.232, 1.233 gdb-6.5-attach-stop.patch, 1.3, NONE

Jan Kratochvil (jkratoch) fedora-extras-commits at redhat.com
Wed Jun 20 14:26:22 UTC 2007


Author: jkratoch

Update of /cvs/pkgs/rpms/gdb/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv18705

Modified Files:
	gdb.spec 
Added Files:
	gdb-6.6-bz233852-attach-signalled.patch 
Removed Files:
	gdb-6.5-attach-stop.patch 
Log Message:
* Wed Jun 20 2007 Jan Kratochvil <jan.kratochvil at redhat.com> - 6.6-16
- Fix attaching a stopped process on expected + upstream kernels (BZ 233852).
 - Fix attaching during a pending signal being delivered.


gdb-6.6-bz233852-attach-signalled.patch:

--- NEW FILE gdb-6.6-bz233852-attach-signalled.patch ---
diff -u -rup gdb-6.6-orig/gdb/inf-ptrace.c gdb-6.6/gdb/inf-ptrace.c
--- gdb-6.6-orig/gdb/inf-ptrace.c	2006-01-24 23:34:34.000000000 +0100
+++ gdb-6.6/gdb/inf-ptrace.c	2007-06-06 13:33:11.000000000 +0200
@@ -38,6 +38,9 @@
 
 /* HACK: Save the ptrace ops returned by inf_ptrace_target.  */
 static struct target_ops *ptrace_ops_hack;
+
+/* Stored PID of the process being stopped during attach.  */
+static pid_t stopped_pid;
 
 
 #ifdef PT_GET_PROCESS_STATE
@@ -69,14 +72,20 @@ inf_ptrace_follow_fork (struct target_op
 
   if (follow_child)
     {
+      unsigned long sig = 0;
+
       inferior_ptid = pid_to_ptid (fpid);
       detach_breakpoints (pid);
 
       /* Reset breakpoints in the child as appropriate.  */
       follow_inferior_reset_breakpoints ();
 
-      if (ptrace (PT_DETACH, pid, (PTRACE_TYPE_ARG3)1, 0) == -1)
-	perror_with_name (("ptrace"));
+      /* Stop the process again if it was stopped during the attachment.  */
+      if (pid == stopped_pid)
+	sig = target_signal_to_host (TARGET_SIGNAL_STOP));
+
+      if (ptrace (PT_DETACH, pid, (PTRACE_TYPE_ARG3)1, (void *) sig) == -1)
+	perror_with_name (("ptrace PT_DETACH"));
     }
   else
     {
@@ -173,6 +182,21 @@ inf_ptrace_mourn_inferior (void)
   generic_mourn_inferior ();
 }
 
+/* Wrapper function for waitpid which handles EINTR.  */
+
+static int
+my_waitpid (int pid, int *status, int flags)
+{
+  int ret;
+  do
+    {
+      ret = waitpid (pid, status, flags);
+    }
+  while (ret == -1 && errno == EINTR);
+
+  return ret;
+}
+
 /* Attach to the process specified by ARGS.  If FROM_TTY is non-zero,
    be chatty about it.  */
 
@@ -180,8 +204,14 @@ static void
 inf_ptrace_attach (char *args, int from_tty)
 {
   char *exec_file;
-  pid_t pid;
+  pid_t pid, got_pid;
   char *dummy;
+  int status;
+  unsigned long sig;
+  FILE *status_file;
+  char name[40];
+  char buf[100]; 
+  int sigstop = target_signal_to_host (TARGET_SIGNAL_STOP);
 
   if (!args)
     error_no_arg (_("process-id to attach"));
@@ -210,11 +240,64 @@ inf_ptrace_attach (char *args, int from_
     }
 
 #ifdef PT_ATTACH
+  stopped_pid = 0;
+  /* There is a small moment after PTRACE_ATTACH where PTRACE_CONT will
+     succeed only for originally stopped processes.  Unfortunately in a moment
+     PTRACE_ATTACH will deliver its SIGSTOP and PTRACE_CONT shows no difference
+     since that moment.
+     "/proc/%d/status" is also a race but it is safe for unstopped cases.  */
+  sprintf (name, "/proc/%d/status", (int) pid);
+  status_file = fopen (name, "r");
+  if (status_file != NULL)
+    {
+      int have_state = 0;
+
+      while (fgets (buf, 100, status_file))
+	{
+	  if (strncmp (buf, "State:", 6) == 0)
+	    {
+	      have_state = 1;
+	      break;
+	    }
+	} 
+      if (have_state != 0 && strstr (buf, "T (stopped)") != NULL)
+	stopped_pid = pid;
+      fclose (status_file);
+    }
+
   errno = 0;
   ptrace (PT_ATTACH, pid, (PTRACE_TYPE_ARG3)0, 0);
   if (errno != 0)
     perror_with_name (("ptrace"));
   attach_flag = 1;
+
+  /* Deliver one SIGSTOP just for sure.
+     If the process was already stopped AND some other process (like shell)
+     has already waited for it we would get stuck in waitpid ().  */
+  sig = sigstop;
+  do
+    {
+      if (sig != sigstop)
+	printf_unfiltered (_("Redelivering pending %s.\n"),
+		       target_signal_to_string (target_signal_from_host (sig)));
+      errno = 0;
+      ptrace (PT_CONTINUE, pid, (PTRACE_TYPE_ARG3)1, (void *) sig);
+      /* For unstopped processes the preventive signal may ESRCH.  */
+      if (errno != 0 && sig != sigstop)
+	perror_with_name ("ptrace PT_CONTINUE");
+
+      got_pid = my_waitpid (pid, &status, 0);
+      gdb_assert (got_pid == pid);
+
+      /* Check if the thread has exited.  */
+      if (WIFEXITED (status) || WIFSIGNALED (status))
+	error (_("Program %s exited.\n"),
+	       target_pid_to_str (pid_to_ptid (pid)));
+      gdb_assert (WIFSTOPPED (status));
+      sig = WSTOPSIG (status);
+      gdb_assert (sig != 0);
+    }
+  while (sig != sigstop);
 #else
   error (_("This system does not support attaching to a process"));
 #endif
@@ -240,14 +323,16 @@ inf_ptrace_post_attach (int pid)
 
 #endif
 
-/* Detach from the inferior, optionally passing it the signal
-   specified by ARGS.  If FROM_TTY is non-zero, be chatty about it.  */
+/* Detach from the inferior.  If FROM_TTY is non-zero, be chatty about it.  */
 
 static void
 inf_ptrace_detach (char *args, int from_tty)
 {
   pid_t pid = ptid_get_pid (inferior_ptid);
-  int sig = 0;
+  unsigned long sig = 0;
+
+  if (args)
+    error (_("Too many arguments"));
 
   if (from_tty)
     {
@@ -258,18 +343,19 @@ inf_ptrace_detach (char *args, int from_
 			 target_pid_to_str (pid_to_ptid (pid)));
       gdb_flush (gdb_stdout);
     }
-  if (args)
-    sig = atoi (args);
 
 #ifdef PT_DETACH
   /* We'd better not have left any breakpoints in the program or it'll
      die when it hits one.  Also note that this may only work if we
      previously attached to the inferior.  It *might* work if we
      started the process ourselves.  */
+  /* Stop the process again if it was stopped during the attachment.  */
+  if (pid == stopped_pid)
+    sig = target_signal_to_host (TARGET_SIGNAL_STOP);
   errno = 0;
-  ptrace (PT_DETACH, pid, (PTRACE_TYPE_ARG3)1, sig);
+  ptrace (PT_DETACH, pid, (PTRACE_TYPE_ARG3)1, (void *) sig);
   if (errno != 0)
-    perror_with_name (("ptrace"));
+    perror_with_name (("ptrace PT_DETACH"));
   attach_flag = 0;
 #else
   error (_("This system does not support detaching from a process"));
@@ -324,6 +410,12 @@ inf_ptrace_resume (ptid_t ptid, int step
        single-threaded processes, so simply resume the inferior.  */
     pid = ptid_get_pid (inferior_ptid);
 
+  /* At this point, we are going to resume the inferior and if we
+     have attached to a stopped process, we no longer should leave
+     it as stopped if the user detaches.  */
+  if (!step && pid == stopped_pid)
+    stopped_pid = 0;
+
   if (step)
     {
       /* If this system does not support PT_STEP, a higher level
diff -u -rup gdb-6.6-orig/gdb/linux-nat.c gdb-6.6/gdb/linux-nat.c
--- gdb-6.6-orig/gdb/linux-nat.c	2007-06-06 13:30:52.000000000 +0200
+++ gdb-6.6/gdb/linux-nat.c	2007-06-06 13:57:18.000000000 +0200
@@ -994,6 +994,7 @@ lin_lwp_attach_lwp (ptid_t ptid, int ver
     {
       pid_t pid;
       int status;
+      unsigned long sig;
 
       if (ptrace (PTRACE_ATTACH, GET_LWP (ptid), 0, 0) < 0)
 	{
@@ -1015,32 +1016,54 @@ lin_lwp_attach_lwp (ptid_t ptid, int ver
 			    "LLAL: PTRACE_ATTACH %s, 0, 0 (OK)\n",
 			    target_pid_to_str (ptid));
 
-      pid = my_waitpid (GET_LWP (ptid), &status, 0);
-      if (pid == -1 && errno == ECHILD)
+      sig = SIGSTOP;
+      do
 	{
-	  /* Try again with __WCLONE to check cloned processes.  */
-	  pid = my_waitpid (GET_LWP (ptid), &status, __WCLONE);
+	  if (sig != SIGSTOP)
+	    printf_unfiltered (_("Redelivering pending %s.\n"),
+		       target_signal_to_string (target_signal_from_host (sig)));
+	  /* For unstopped processes the preventive signal may ESRCH.  */
+	  if (ptrace (PTRACE_CONT, GET_LWP (ptid), (PTRACE_TYPE_ARG3)1,
+		      (void *) sig) != 0 && sig != SIGSTOP)
+	    perror_with_name ("ptrace");
+
+	  pid = my_waitpid (GET_LWP (ptid), &status, 0);
 	  if (pid == -1 && errno == ECHILD)
-	    error (_("Can't attach %s (%s) - possible SELinux denial,"
-		     " check your /var/log/messages for `avc: denied'"),
-		   target_pid_to_str (ptid), safe_strerror (errno));
-	  lp->cloned = 1;
-	}
+	    {
+	      /* Try again with __WCLONE to check cloned processes.  */
+	      pid = my_waitpid (GET_LWP (ptid), &status, __WCLONE);
+	      if (pid == -1 && errno == ECHILD)
+		error (_("Can't attach %s (%s) - possible SELinux denial,"
+			 " check your /var/log/messages for `avc: denied'"),
+		       target_pid_to_str (ptid), safe_strerror (errno));
+	      lp->cloned = 1;
+	    }
+	  gdb_assert (pid == GET_LWP (ptid));
 
-      gdb_assert (pid == GET_LWP (ptid)
-		  && WIFSTOPPED (status) && WSTOPSIG (status));
+	  if (debug_linux_nat)
+	    {
+	      fprintf_unfiltered (gdb_stdlog,
+				  "LLAL: waitpid %s received %s\n",
+				  target_pid_to_str (ptid),
+				  status_to_str (status));
+	    }
+
+	  /* Check if the thread has exited.  */
+	  if (WIFEXITED (status) || WIFSIGNALED (status))
+	    {
+	      warning (_("Thread %s exited: %s"), target_pid_to_str (ptid),
+		       status_to_str (status));
+	      return -1;
+	    }
+	  gdb_assert (WIFSTOPPED (status));
+	  sig = WSTOPSIG (status);
+	  gdb_assert (sig != 0);
+	}
+      while (sig != SIGSTOP);
 
       target_post_attach (pid);
 
       lp->stopped = 1;
-
-      if (debug_linux_nat)
-	{
-	  fprintf_unfiltered (gdb_stdlog,
-			      "LLAL: waitpid %s received %s\n",
-			      target_pid_to_str (ptid),
-			      status_to_str (status));
-	}
     }
   else
     {
@@ -1065,8 +1088,6 @@ static void
 linux_nat_attach (char *args, int from_tty)
 {
   struct lwp_info *lp;
-  pid_t pid;
-  int status;
 
   /* FIXME: We should probably accept a list of process id's, and
      attach all of them.  */
@@ -1076,22 +1097,6 @@ linux_nat_attach (char *args, int from_t
   inferior_ptid = BUILD_LWP (GET_PID (inferior_ptid), GET_PID (inferior_ptid));
   lp = add_lwp (inferior_ptid);
 
-  /* Make sure the initial process is stopped.  The user-level threads
-     layer might want to poke around in the inferior, and that won't
-     work if things haven't stabilized yet.  */
-  pid = my_waitpid (GET_PID (inferior_ptid), &status, 0);
-  if (pid == -1 && errno == ECHILD)
-    {
-      warning (_("%s is a cloned process"), target_pid_to_str (inferior_ptid));
-
-      /* Try again with __WCLONE to check cloned processes.  */
-      pid = my_waitpid (GET_PID (inferior_ptid), &status, __WCLONE);
-      lp->cloned = 1;
-    }
-
-  gdb_assert (pid == GET_PID (inferior_ptid)
-	      && WIFSTOPPED (status) && WSTOPSIG (status) == SIGSTOP);
-
   lp->stopped = 1;
 
   /* Fake the SIGSTOP that core GDB expects.  */
@@ -1099,8 +1104,8 @@ linux_nat_attach (char *args, int from_t
   lp->resumed = 1;
   if (debug_linux_nat)
     {
-      fprintf_unfiltered (gdb_stdlog,
-			  "LLA: waitpid %ld, faking SIGSTOP\n", (long) pid);
+      fprintf_unfiltered (gdb_stdlog, "LLA: waitpid %d, faking SIGSTOP\n",
+			  GET_PID (inferior_ptid));
     }
 }
 
diff -u -rup gdb-6.6-orig/gdb/target.h gdb-6.6/gdb/target.h
--- gdb-6.6-orig/gdb/target.h	2007-06-06 13:30:52.000000000 +0200
+++ gdb-6.6/gdb/target.h	2007-06-06 13:33:11.000000000 +0200
@@ -529,9 +529,9 @@ void target_close (struct target_ops *ta
    to the `attach' command by the user.  This routine can be called
    when the target is not on the target-stack, if the target_can_run
    routine returns 1; in that case, it must push itself onto the stack.
-   Upon exit, the target should be ready for normal operations, and
-   should be ready to deliver the status of the process immediately
-   (without waiting) to an upcoming target_wait call.  */
+   Upon exit, the target should be ready for normal operations.
+   The status of the inferior is already processed and possibly pending
+   signals redelivered.  */
 
 #define	target_attach(args, from_tty)	\
      (*current_target.to_attach) (args, from_tty)
diff -u -rup gdb-6.6-orig/gdb/testsuite/gdb.threads/attach-into-signal.c gdb-6.6/gdb/testsuite/gdb.threads/attach-into-signal.c
--- gdb-6.6-orig/gdb/testsuite/gdb.threads/attach-into-signal.c	2007-06-06 16:36:34.000000000 +0200
+++ gdb-6.6/gdb/testsuite/gdb.threads/attach-into-signal.c	2007-06-06 13:33:11.000000000 +0200
@@ -0,0 +1,65 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2007 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include <signal.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef USE_THREADS
+#include <pthread.h>
+#endif
+
+void action(int sig, siginfo_t * info, void *uc)
+{
+  raise (SIGALRM);
+}
+
+static void *func (void *arg)
+{
+  struct sigaction act;
+
+  memset (&act, 0, sizeof(struct sigaction));
+  act.sa_sigaction = action;
+  act.sa_flags = SA_RESTART;
+  sigaction (SIGALRM, &act, 0);
+
+  raise (SIGALRM);
+
+  abort ();
+  /* NOTREACHED */
+  return NULL;
+}
+
+int main ()
+{
+
+#ifndef USE_THREADS
+
+  func (NULL);
+
+#else
+
+  pthread_t th;
+  pthread_create (&th, NULL, func, NULL);
+  pthread_join (th, NULL);
+
+#endif
+
+  return 0;
+}
diff -u -rup gdb-6.6-orig/gdb/testsuite/gdb.threads/attach-into-signal.exp gdb-6.6/gdb/testsuite/gdb.threads/attach-into-signal.exp
--- gdb-6.6-orig/gdb/testsuite/gdb.threads/attach-into-signal.exp	2007-06-06 16:36:34.000000000 +0200
+++ gdb-6.6/gdb/testsuite/gdb.threads/attach-into-signal.exp	2007-06-06 13:33:11.000000000 +0200
@@ -0,0 +1,153 @@
+# Copyright 2007
+
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# This test was created by modifying attach-stopped.exp.
+# This file was created by Jan Kratochvil <jan.kratochvil at redhat.com>.
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile "attach-into-signal"
+set srcfile  ${testfile}.c
+set binfile  ${objdir}/${subdir}/${testfile}
+set escapedbinfile  [string_to_regexp ${objdir}/${subdir}/${testfile}]
+
+remote_exec build "rm -f ${binfile}"
+# For debugging this test
+#
+#log_user 1
+
+proc corefunc { threadtype } {
+    global srcfile
+    global binfile
+    global escapedbinfile
+    global srcdir
+    global subdir
+    global gdb_prompt
+
+    if [get_compiler_info ${binfile}] {
+	return -1
+    }
+
+    # Start the program running and then wait for a bit, to be sure
+    # that it can be attached to.
+    # Statistically there is a better chance without giving process a nice.
+
+    set testpid [eval exec $binfile &]
+    exec sleep 2
+
+    # Run 2 passes of the test.
+    # The C file inferior stops pending its signals if a single one is lost,
+    # we test successful redelivery of the caught signal by the 2nd pass.
+
+    # linux-2.6.20.4.x86_64 had maximal attempt # 20 in 4 test runs.
+    set attempts 100
+    set attempt 0
+    set passes 1
+    while { $passes < 3 && $attempt < $attempts } {
+
+	# Start with clean gdb
+	gdb_exit
+	gdb_start
+	gdb_reinitialize_dir $srcdir/$subdir
+	gdb_load ${binfile}
+
+	# No PASS message as we may be looping in multiple attempts.
+	gdb_test "set debug lin-lwp 1" "" ""
+
+	set test "$threadtype: set file (pass $passes), before attach1 to stopped process"
+	if {[gdb_test_multiple "file $binfile" $test {
+	   -re "Load new symbol table from.*y or n. $" {
+		# No PASS message as we may be looping in multiple attempts.
+		gdb_test "y" "Reading symbols from $escapedbinfile\.\.\.*done." ""
+	    }
+	    -re "Reading symbols from $escapedbinfile\.\.\.*done.*$gdb_prompt $" {
+		# No PASS message as we may be looping in multiple attempts.
+	    }
+	}] != 0 } {
+	    break
+	}
+
+	# Main test:
+	set test "$threadtype: attach (pass $passes), pending signal catch"
+	if {[gdb_test_multiple "attach $testpid" $test {
+	    -re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*Redelivering pending Alarm clock..*$gdb_prompt $" {
+		# nonthreaded:
+		pass $test
+		verbose -log "$test succeeded on the attempt # $attempt of $attempts"
+		set passes [expr $passes + 1]
+	    }
+	    -re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*$gdb_prompt $" {
+		# nonthreaded:
+		# We just lack the luck, we should try it again.
+		set attempt [expr $attempt + 1]
+	    }
+	    -re "Attaching to process $testpid.*Redelivering pending Alarm clock..*$gdb_prompt $" {
+		# threaded:
+		pass $test
+		verbose -log "$test succeeded on the attempt # $attempt of $attempts"
+		set passes [expr $passes + 1]
+	    }
+	    -re "Attaching to process $testpid.*$gdb_prompt $" {
+		# threaded:
+		# We just lack the luck, we should try it again.
+		set attempt [expr $attempt - 1]
+	    }
+	}] != 0 } {
+	    break
+	}
+    }
+    if {$passes < 3} {
+	fail $test
+    }
+
+    # Exit and detach the process.
+       
+    gdb_exit
+
+    # Make sure we don't leave a process around to confuse
+    # the next test run (and prevent the compile by keeping
+    # the text file busy), in case the "set should_exit" didn't
+    # work.
+
+    # Continue the program - some Linux kernels need it before -9 if the
+    # process is stopped.
+    remote_exec build "kill -s CONT ${testpid}"
+       
+    remote_exec build "kill -9 ${testpid}"
+}
+
+# build the test case first without threads
+#
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+    gdb_suppress_entire_file "Testcase nonthraded compile failed, so all tests in this file will automatically fail."
+}
+
+corefunc nonthreaded
+
+# build the test case first without threads
+#
+if  { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DUSE_THREADS}] != "" } {
+    gdb_suppress_entire_file "Testcase threaded compile failed, so all tests in this file will automatically fail."
+}
+
+corefunc threaded
+
+return 0
diff -u -rup gdb-6.6-orig/gdb/testsuite/gdb.threads/attach-stopped.c gdb-6.6/gdb/testsuite/gdb.threads/attach-stopped.c
--- gdb-6.6-orig/gdb/testsuite/gdb.threads/attach-stopped.c	2007-06-06 16:36:34.000000000 +0200
+++ gdb-6.6/gdb/testsuite/gdb.threads/attach-stopped.c	2007-06-06 13:33:11.000000000 +0200
@@ -0,0 +1,51 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2005-2007 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* This program is intended to be started outside of gdb, then
+   manually stopped via a signal.  */
+
+#include <stddef.h>
+#include <unistd.h>
+#ifdef USE_THREADS
+#include <pthread.h>
+#endif
+
+static void *func (void *arg)
+{
+  sleep (10000);  /* Ridiculous time, but we will eventually kill it.  */
+  sleep (10000);  /* Second sleep.  */
+  return NULL;
+}
+
+int main ()
+{
+
+#ifndef USE_THREADS
+
+  func (NULL);
+
+#else
+
+  pthread_t th;
+  pthread_create (&th, NULL, func, NULL);
+  pthread_join (th, NULL);
+
+#endif
+
+  return 0;
+}
diff -u -rup gdb-6.6-orig/gdb/testsuite/gdb.threads/attach-stopped.exp gdb-6.6/gdb/testsuite/gdb.threads/attach-stopped.exp
--- gdb-6.6-orig/gdb/testsuite/gdb.threads/attach-stopped.exp	2007-06-06 16:36:34.000000000 +0200
+++ gdb-6.6/gdb/testsuite/gdb.threads/attach-stopped.exp	2007-06-06 13:33:11.000000000 +0200
@@ -0,0 +1,208 @@
+# Copyright 2005-2007
+
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# This test was created by modifying attach.exp.
+# This file was created by Jeff Johnston <jjohnstn at redhat.com>.
+# This file was updated by Jan Kratochvil <jan.kratochvil at redhat.com>.
+
+if $tracelevel then {
+    strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# This test only works on Linux
+if { ![istarget "*-*-linux-gnu*"] } {
+    return 0
+}
+
+set testfile "attach-stopped"
+set srcfile  ${testfile}.c
+set binfile  ${objdir}/${subdir}/${testfile}
+set escapedbinfile  [string_to_regexp ${objdir}/${subdir}/${testfile}]
+
+#execute_anywhere "rm -f ${binfile}"
+remote_exec build "rm -f ${binfile}"
+# For debugging this test
+#
+#log_user 1
+
+proc corefunc { threadtype } {
+    global srcfile
+    global binfile
+    global escapedbinfile
+    global srcdir
+    global subdir
+    global gdb_prompt
+
+    if [get_compiler_info ${binfile}] {
+	return -1
+    }
+
+    # Start the program running and then wait for a bit, to be sure
+    # that it can be attached to.
+
+    set testpid [eval exec $binfile &]
+    exec sleep 2
+       
+    # Stop the program 
+    remote_exec build "kill -s STOP ${testpid}"
+
+    # Start with clean gdb
+    gdb_exit
+    gdb_start
+    gdb_reinitialize_dir $srcdir/$subdir
+    gdb_load ${binfile}
+
+    # Verify that we can attach to the process by first giving its
+    # executable name via the file command, and using attach with the
+    # process ID.
+
+    set test "$threadtype: set file, before attach1 to stopped process"
+    gdb_test_multiple "file $binfile" "$test" {
+       -re "Load new symbol table from.*y or n. $" {
+	    gdb_test "y" "Reading symbols from $escapedbinfile\.\.\.*done." \
+		    "$test (re-read)"
+	}
+	-re "Reading symbols from $escapedbinfile\.\.\.*done.*$gdb_prompt $" {
+	    pass "$test"
+	}
+    }
+
+    set test "$threadtype: attach1 to stopped, after setting file"
+    gdb_test_multiple "attach $testpid" "$test" {
+	-re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*$gdb_prompt $" {
+	    pass "$test"
+	}
+    }
+
+    if {[string equal $threadtype threaded]} {
+	gdb_test "thread apply all bt" ".*sleep.*clone.*" "$threadtype: attach1 to stopped bt"
+    } else {
+	gdb_test "bt" ".*sleep.*main.*" "$threadtype: attach1 to stopped bt"
+    }
+
+    # Exit and detach the process.
+       
+    gdb_exit
+
+    set fileid [open /proc/${testpid}/status r];
+    gets $fileid line1;
+    gets $fileid line2;
+    close $fileid;
+
+    set test "$threadtype: attach1, exit leaves process stopped"
+    if {[string match "*(stopped)*" $line2]} {
+      pass $test
+    } else {
+      fail $test
+    }
+
+    # At this point, the process should still be stopped
+
+    gdb_start
+    gdb_reinitialize_dir $srcdir/$subdir
+    gdb_load ${binfile}
+
+    # Verify that we can attach to the process just by giving the
+    # process ID.
+       
+    set test "$threadtype: attach2 to stopped, after setting file"
+    gdb_test_multiple "attach $testpid" "$test" {
+	-re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*$gdb_prompt $" {
+	    pass "$test"
+	}
+    }
+
+    if {[string equal $threadtype threaded]} {
+	gdb_test "thread apply all bt" ".*sleep.*clone.*" "$threadtype: attach2 to stopped bt"
+    } else {
+	gdb_test "bt" ".*sleep.*main.*" "$threadtype: attach2 to stopped bt"
+    }
+    gdb_breakpoint [gdb_get_line_number "$threadtype: Second sleep"]
+    set test "$threadtype: attach2 continue"
+    send_gdb "continue\n"
+    gdb_expect {
+      -re "Continuing"
+	{ pass "continue ($test)" }
+      timeout
+	{ fail "continue ($test) (timeout)" }
+    }
+
+    # For this to work we must be sure to consume the "Continuing."
+    # message first, or GDB's signal handler may not be in place.
+    after 1000 {send_gdb "\003"}
+    set test "$threadtype: attach2 stop interrupt"
+    gdb_expect 10 {
+      -re "Program received signal SIGINT.*$gdb_prompt $"
+	{
+	  pass $test
+	}
+      -re "Breakpoint \[0-9\].*$srcfile.*$gdb_prompt $"
+	{
+	  pass $test
+	}
+      timeout
+	{
+	  fail $test
+	}
+    }
+
+    gdb_exit
+
+    # Avoid some race:
+    exec sleep 2
+
+    # At this point, the process should be sleeping
+
+    set fileid2 [open /proc/${testpid}/status r];
+    gets $fileid2 line1;
+    gets $fileid2 line2;
+    close $fileid2;
+
+    set test "$threadtype: attach2, exit leaves process sleeping"
+    if {[string match "*(sleeping)*" $line2]} {
+      pass $test
+    } else {
+      fail $test
+    }
+
+    # Make sure we don't leave a process around to confuse
+    # the next test run (and prevent the compile by keeping
+    # the text file busy), in case the "set should_exit" didn't
+    # work.
+       
+    remote_exec build "kill -9 ${testpid}"
+}
+
+# build the test case first without threads
+#
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+    gdb_suppress_entire_file "Testcase nonthraded compile failed, so all tests in this file will automatically fail."
+}
+
+corefunc nonthreaded
+
+# build the test case first without threads
+#
+if  { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DUSE_THREADS}] != "" } {
+    gdb_suppress_entire_file "Testcase threaded compile failed, so all tests in this file will automatically fail."
+}
+
+corefunc threaded
+
+return 0


Index: gdb.spec
===================================================================
RCS file: /cvs/pkgs/rpms/gdb/devel/gdb.spec,v
retrieving revision 1.232
retrieving revision 1.233
diff -u -r1.232 -r1.233
--- gdb.spec	7 Jun 2007 18:31:29 -0000	1.232
+++ gdb.spec	20 Jun 2007 14:25:46 -0000	1.233
@@ -11,7 +11,7 @@
 Version: 6.6
 
 # The release always contains a leading reserved number, start it at 1.
-Release: 15%{?dist}
+Release: 16%{?dist}
 
 License: GPL
 Group: Development/Debuggers
@@ -222,10 +222,6 @@
 # Fix gdb printf command argument using "%p" (BZ 205551).
 Patch191: gdb-6.5-bz205551-printf-p.patch
 
-# Fix attach to stopped process, supersede `gdb-6.3-attach-stop-20051011.patch'.
-# Fix attachment also to a threaded stopped process (BZ 219118).
-Patch193: gdb-6.5-attach-stop.patch
-
 # Support TLS symbols (+`errno' suggestion if no pthread is found) (BZ 185337).
 # FIXME: Still to be updated.
 Patch194: gdb-6.5-bz185337-resolve-tls-without-debuginfo-v2.patch
@@ -350,6 +346,10 @@
 # Avoid too long timeouts on failing cases of "annota1.exp annota3.exp".
 Patch254: gdb-6.6-testsuite-timeouts.patch
 
+# Fix attaching a stopped nonthreaded/threaded process (BZ 219118, 233852).
+# Fix attaching during a pending signal being delivered.
+Patch256: gdb-6.6-bz233852-attach-signalled.patch
+
 BuildRequires: ncurses-devel glibc-devel gcc make gzip texinfo dejagnu gettext
 BuildRequires: flex bison sharutils expat-devel
 
@@ -448,7 +448,6 @@
 %patch188 -p1
 %patch190 -p1
 %patch191 -p1
-%patch193 -p1
 %patch194 -p1
 %patch195 -p1
 %patch196 -p1
@@ -494,6 +493,7 @@
 %patch249 -p1
 %patch251 -p1
 %patch254 -p1
+%patch256 -p1
 
 # Change the version that gets printed at GDB startup, so it is RedHat
 # specific.
@@ -643,6 +643,10 @@
 # don't include the files in include, they are part of binutils
 
 %changelog
+* Wed Jun 20 2007 Jan Kratochvil <jan.kratochvil at redhat.com> - 6.6-16
+- Fix attaching a stopped process on expected + upstream kernels (BZ 233852).
+ - Fix attaching during a pending signal being delivered.
+
 * Thu Jun  7 2007 Jan Kratochvil <jan.kratochvil at redhat.com> - 6.6-15
 - Testcase update to cover PPC Power6/DFP instructions disassembly (BZ 230000).
 - Disable some known timeouting/failing testcases to reduce the build time.


--- gdb-6.5-attach-stop.patch DELETED ---




More information about the fedora-extras-commits mailing list