[gdb/f17] Print reasons for failed attach/spawn incl. SELinux deny_ptrace (BZ 786878).

Jan Kratochvil jankratochvil at fedoraproject.org
Tue Mar 6 06:57:14 UTC 2012


commit c64e73263bc5a353268f1f2e8e164ee9f0849694
Author: Jan Kratochvil <jan.kratochvil at redhat.com>
Date:   Tue Mar 6 07:57:07 2012 +0100

    Print reasons for failed attach/spawn incl. SELinux deny_ptrace (BZ 786878).

 gdb-attach-fail-reasons-1of5.patch |   88 ++++++
 gdb-attach-fail-reasons-2of5.patch |  178 +++++++++++
 gdb-attach-fail-reasons-3of5.patch |  583 ++++++++++++++++++++++++++++++++++++
 gdb-attach-fail-reasons-4of5.patch |  402 +++++++++++++++++++++++++
 gdb-attach-fail-reasons-5of5.patch |  209 +++++++++++++
 gdb.spec                           |   18 +-
 6 files changed, 1477 insertions(+), 1 deletions(-)
---
diff --git a/gdb-attach-fail-reasons-1of5.patch b/gdb-attach-fail-reasons-1of5.patch
new file mode 100644
index 0000000..4c547d8
--- /dev/null
+++ b/gdb-attach-fail-reasons-1of5.patch
@@ -0,0 +1,88 @@
+http://sourceware.org/ml/gdb-cvs/2012-02/msg00180.html
+
+### src/gdb/gdbserver/ChangeLog	2012/02/25 19:54:50	1.556
+### src/gdb/gdbserver/ChangeLog	2012/02/27 16:19:19	1.557
+## -1,3 +1,9 @@
++2012-02-27  Pedro Alves  <palves at redhat.com>
++
++	PR server/9684
++	* linux-low.c (pid_is_stopped): New.
++	(linux_attach_lwp_1): Handle attaching to 'T (stopped)' processes.
++
+ 2012-02-25  Luis Machado  <lgustavo at codesourcery.com>
+ 
+ 	* mem-break.c (clear_gdb_breakpoint_conditions): Fix de-allocation
+--- src/gdb/gdbserver/linux-low.c	2012/02/24 15:15:56	1.193
++++ src/gdb/gdbserver/linux-low.c	2012/02/27 16:19:19	1.194
+@@ -598,6 +598,37 @@
+   return pid;
+ }
+ 
++/* Detect `T (stopped)' in `/proc/PID/status'.
++   Other states including `T (tracing stop)' are reported as false.  */
++
++static int
++pid_is_stopped (pid_t pid)
++{
++  FILE *status_file;
++  char buf[100];
++  int retval = 0;
++
++  snprintf (buf, sizeof (buf), "/proc/%d/status", (int) pid);
++  status_file = fopen (buf, "r");
++  if (status_file != NULL)
++    {
++      int have_state = 0;
++
++      while (fgets (buf, sizeof (buf), status_file))
++	{
++	  if (strncmp (buf, "State:", 6) == 0)
++	    {
++	      have_state = 1;
++	      break;
++	    }
++	}
++      if (have_state && strstr (buf, "T (stopped)") != NULL)
++	retval = 1;
++      fclose (status_file);
++    }
++  return retval;
++}
++
+ /* Attach to an inferior process.  */
+ 
+ static void
+@@ -643,6 +674,33 @@
+      ptrace call on this LWP.  */
+   new_lwp->must_set_ptrace_flags = 1;
+ 
++  if (pid_is_stopped (lwpid))
++    {
++      if (debug_threads)
++	fprintf (stderr,
++		 "Attached to a stopped process\n");
++
++      /* The process is definitely stopped.  It is in a job control
++	 stop, unless the kernel predates the TASK_STOPPED /
++	 TASK_TRACED distinction, in which case it might be in a
++	 ptrace stop.  Make sure it is in a ptrace stop; from there we
++	 can kill it, signal it, et cetera.
++
++	 First make sure there is a pending SIGSTOP.  Since we are
++	 already attached, the process can not transition from stopped
++	 to running without a PTRACE_CONT; so we know this signal will
++	 go into the queue.  The SIGSTOP generated by PTRACE_ATTACH is
++	 probably already in the queue (unless this kernel is old
++	 enough to use TASK_STOPPED for ptrace stops); but since
++	 SIGSTOP is not an RT signal, it can only be queued once.  */
++      kill_lwp (lwpid, SIGSTOP);
++
++      /* Finally, resume the stopped process.  This will deliver the
++	 SIGSTOP (or a higher priority signal, just like normal
++	 PTRACE_ATTACH), which we'll catch later on.  */
++      ptrace (PTRACE_CONT, lwpid, 0, 0);
++    }
++
+   /* The next time we wait for this LWP we'll see a SIGSTOP as PTRACE_ATTACH
+      brings it to a halt.
+ 
diff --git a/gdb-attach-fail-reasons-2of5.patch b/gdb-attach-fail-reasons-2of5.patch
new file mode 100644
index 0000000..92565b9
--- /dev/null
+++ b/gdb-attach-fail-reasons-2of5.patch
@@ -0,0 +1,178 @@
+http://sourceware.org/ml/gdb-cvs/2012-02/msg00181.html
+
+### src/gdb/ChangeLog	2012/02/24 23:48:37	1.13869
+### src/gdb/ChangeLog	2012/02/27 16:22:06	1.13870
+## -1,3 +1,13 @@
++2012-02-27  Pedro Alves  <palves at redhat.com>
++
++	* linux-nat.c (pid_is_stopped): Delete, moved to common/.
++	(linux_nat_post_attach_wait): Adjust to use
++	linux_proc_pid_is_stopped.
++	* common/linux-procfs.h (linux_proc_pid_is_stopped): Declare.
++	* common/linux-procfs.c (linux_proc_pid_is_stopped): New function,
++	based on pid_is_stopped from both linux-nat.c and
++	gdbserver/linux-low.c, and renamed.
++
+ 2012-02-24  Maciej W. Rozycki  <macro at codesourcery.com>
+ 
+ 	* remote.c (remote_watchpoint_addr_within_range): New function.
+--- src/gdb/linux-nat.c	2012/02/16 21:07:20	1.239
++++ src/gdb/linux-nat.c	2012/02/27 16:22:13	1.240
+@@ -1356,37 +1356,6 @@
+   delete_lwp (lp->ptid);
+ }
+ 
+-/* Detect `T (stopped)' in `/proc/PID/status'.
+-   Other states including `T (tracing stop)' are reported as false.  */
+-
+-static int
+-pid_is_stopped (pid_t pid)
+-{
+-  FILE *status_file;
+-  char buf[100];
+-  int retval = 0;
+-
+-  snprintf (buf, sizeof (buf), "/proc/%d/status", (int) pid);
+-  status_file = fopen (buf, "r");
+-  if (status_file != NULL)
+-    {
+-      int have_state = 0;
+-
+-      while (fgets (buf, sizeof (buf), status_file))
+-	{
+-	  if (strncmp (buf, "State:", 6) == 0)
+-	    {
+-	      have_state = 1;
+-	      break;
+-	    }
+-	}
+-      if (have_state && strstr (buf, "T (stopped)") != NULL)
+-	retval = 1;
+-      fclose (status_file);
+-    }
+-  return retval;
+-}
+-
+ /* Wait for the LWP specified by LP, which we have just attached to.
+    Returns a wait status for that LWP, to cache.  */
+ 
+@@ -1397,7 +1366,7 @@
+   pid_t new_pid, pid = GET_LWP (ptid);
+   int status;
+ 
+-  if (pid_is_stopped (pid))
++  if (linux_proc_pid_is_stopped (pid))
+     {
+       if (debug_linux_nat)
+ 	fprintf_unfiltered (gdb_stdlog,
+--- src/gdb/common/linux-procfs.c	2012/01/04 08:17:18	1.2
++++ src/gdb/common/linux-procfs.c	2012/02/27 16:22:14	1.3
+@@ -53,3 +53,34 @@
+ 
+   return tgid;
+ }
++
++/* Detect `T (stopped)' in `/proc/PID/status'.
++   Other states including `T (tracing stop)' are reported as false.  */
++
++int
++linux_proc_pid_is_stopped (pid_t pid)
++{
++  FILE *status_file;
++  char buf[100];
++  int retval = 0;
++
++  snprintf (buf, sizeof (buf), "/proc/%d/status", (int) pid);
++  status_file = fopen (buf, "r");
++  if (status_file != NULL)
++    {
++      int have_state = 0;
++
++      while (fgets (buf, sizeof (buf), status_file))
++	{
++	  if (strncmp (buf, "State:", 6) == 0)
++	    {
++	      have_state = 1;
++	      break;
++	    }
++	}
++      if (have_state && strstr (buf, "T (stopped)") != NULL)
++	retval = 1;
++      fclose (status_file);
++    }
++  return retval;
++}
+--- src/gdb/common/linux-procfs.h	2012/01/04 08:17:18	1.2
++++ src/gdb/common/linux-procfs.h	2012/02/27 16:22:15	1.3
+@@ -26,4 +26,9 @@
+ 
+ extern int linux_proc_get_tgid (int lwpid);
+ 
++/* Detect `T (stopped)' in `/proc/PID/status'.
++   Other states including `T (tracing stop)' are reported as false.  */
++
++extern int linux_proc_pid_is_stopped (pid_t pid);
++
+ #endif /* COMMON_LINUX_PROCFS_H */
+### src/gdb/gdbserver/ChangeLog	2012/02/27 16:19:19	1.557
+### src/gdb/gdbserver/ChangeLog	2012/02/27 16:22:15	1.558
+## -1,5 +1,10 @@
+ 2012-02-27  Pedro Alves  <palves at redhat.com>
+ 
++	* linux-low.c (pid_is_stopped): Delete, moved to common/.
++	(linux_attach_lwp_1): Adjust to use linux_proc_pid_is_stopped.
++
++2012-02-27  Pedro Alves  <palves at redhat.com>
++
+ 	PR server/9684
+ 	* linux-low.c (pid_is_stopped): New.
+ 	(linux_attach_lwp_1): Handle attaching to 'T (stopped)' processes.
+--- src/gdb/gdbserver/linux-low.c	2012/02/27 16:19:19	1.194
++++ src/gdb/gdbserver/linux-low.c	2012/02/27 16:22:16	1.195
+@@ -598,37 +598,6 @@
+   return pid;
+ }
+ 
+-/* Detect `T (stopped)' in `/proc/PID/status'.
+-   Other states including `T (tracing stop)' are reported as false.  */
+-
+-static int
+-pid_is_stopped (pid_t pid)
+-{
+-  FILE *status_file;
+-  char buf[100];
+-  int retval = 0;
+-
+-  snprintf (buf, sizeof (buf), "/proc/%d/status", (int) pid);
+-  status_file = fopen (buf, "r");
+-  if (status_file != NULL)
+-    {
+-      int have_state = 0;
+-
+-      while (fgets (buf, sizeof (buf), status_file))
+-	{
+-	  if (strncmp (buf, "State:", 6) == 0)
+-	    {
+-	      have_state = 1;
+-	      break;
+-	    }
+-	}
+-      if (have_state && strstr (buf, "T (stopped)") != NULL)
+-	retval = 1;
+-      fclose (status_file);
+-    }
+-  return retval;
+-}
+-
+ /* Attach to an inferior process.  */
+ 
+ static void
+@@ -674,7 +643,7 @@
+      ptrace call on this LWP.  */
+   new_lwp->must_set_ptrace_flags = 1;
+ 
+-  if (pid_is_stopped (lwpid))
++  if (linux_proc_pid_is_stopped (lwpid))
+     {
+       if (debug_threads)
+ 	fprintf (stderr,
diff --git a/gdb-attach-fail-reasons-3of5.patch b/gdb-attach-fail-reasons-3of5.patch
new file mode 100644
index 0000000..a16618e
--- /dev/null
+++ b/gdb-attach-fail-reasons-3of5.patch
@@ -0,0 +1,583 @@
+http://sourceware.org/ml/gdb-patches/2012-03/msg00169.html
+Subject: [patch 1/3] attach-fail-reasons: Reshuffle code
+
+Hi,
+
+this patch does not make sense on its own but it contains all the
+uninteresting code moves / reconfigurations.
+
+
+Thanks,
+Jan
+
+
+gdb/
+2012-03-06  Jan Kratochvil  <jan.kratochvil at redhat.com>
+
+	* Makefile.in (linux-ptrace.o): New.
+	* common/linux-procfs.c (linux_proc_pid_is_zombie): New,
+	from linux-nat.c.
+	* common/linux-procfs.h (linux_proc_pid_is_zombie): New declaration.
+	* common/linux-ptrace.c: New file.
+	* config/alpha/alpha-linux.mh (NATDEPFILES): Add linux-ptrace.o.
+	* config/arm/linux.mh: Likewise.
+	* config/i386/linux.mh: Likewise.
+	* config/i386/linux64.mh: Likewise.
+	* config/ia64/linux.mh: Likewise.
+	* config/m32r/linux.mh: Likewise.
+	* config/m68k/linux.mh: Likewise.
+	* config/mips/linux.mh: Likewise.
+	* config/pa/linux.mh: Likewise.
+	* config/powerpc/linux.mh: Likewise.
+	* config/powerpc/ppc64-linux.mh: Likewise.
+	* config/powerpc/spu-linux.mh: Likewise.
+	* config/s390/s390.mh: Likewise.
+	* config/sparc/linux.mh: Likewise.
+	* config/sparc/linux64.mh: Likewise.
+	* config/xtensa/linux.mh: Likewise.
+	* linux-nat.c (linux_lwp_is_zombie): Remove, move it to
+	common/linux-procfs.c.
+	(wait_lwp): Rename linux_lwp_is_zombie to linux_proc_pid_is_zombie.
+
+gdb/gdbserver/
+2012-03-06  Jan Kratochvil  <jan.kratochvil at redhat.com>
+
+	* Makefile.in (linux-ptrace.o): New.
+	* configure.srv (arm*-*-linux*, bfin-*-*linux*, crisv32-*-linux*)
+	(cris-*-linux*, i[34567]86-*-linux*, ia64-*-linux*, m32r*-*-linux*)
+	(m68*-*-linux*, m68*-*-uclinux*, mips*-*-linux*, powerpc*-*-linux*)
+	(s390*-*-linux*, sh*-*-linux*, sparc*-*-linux*, tic6x-*-uclinux)
+	(x86_64-*-linux*, xtensa*-*-linux*): Add linux-ptrace.o to SRV_TGTOBJ
+	of these targets.
+	* linux-low.c (linux_attach_lwp_1): Remove redundent else clause.
+
+Index: gdb-7.4.50.20120120/gdb/Makefile.in
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/Makefile.in	2012-03-06 07:39:41.000000000 +0100
++++ gdb-7.4.50.20120120/gdb/Makefile.in	2012-03-06 07:39:50.771713128 +0100
+@@ -1968,6 +1968,10 @@ linux-procfs.o: $(srcdir)/common/linux-p
+ 	$(COMPILE) $(srcdir)/common/linux-procfs.c
+ 	$(POSTCOMPILE)
+ 
++linux-ptrace.o: $(srcdir)/common/linux-ptrace.c
++	$(COMPILE) $(srcdir)/common/linux-ptrace.c
++	$(POSTCOMPILE)
++
+ #
+ # gdb/tui/ dependencies
+ #
+Index: gdb-7.4.50.20120120/gdb/common/linux-procfs.c
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/common/linux-procfs.c	2012-03-06 07:39:41.000000000 +0100
++++ gdb-7.4.50.20120120/gdb/common/linux-procfs.c	2012-03-06 07:39:50.771713128 +0100
+@@ -84,3 +84,34 @@ linux_proc_pid_is_stopped (pid_t pid)
+     }
+   return retval;
+ }
++
++/* See linux-procfs.h declaration.  */
++
++int
++linux_proc_pid_is_zombie (pid_t pid)
++{
++  char buffer[100];
++  FILE *procfile;
++  int retval;
++  int have_state;
++
++  xsnprintf (buffer, sizeof (buffer), "/proc/%d/status", (int) pid);
++  procfile = fopen (buffer, "r");
++  if (procfile == NULL)
++    {
++      warning (_("unable to open /proc file '%s'"), buffer);
++      return 0;
++    }
++
++  have_state = 0;
++  while (fgets (buffer, sizeof (buffer), procfile) != NULL)
++    if (strncmp (buffer, "State:", 6) == 0)
++      {
++	have_state = 1;
++	break;
++      }
++  retval = (have_state
++	    && strcmp (buffer, "State:\tZ (zombie)\n") == 0);
++  fclose (procfile);
++  return retval;
++}
+Index: gdb-7.4.50.20120120/gdb/common/linux-procfs.h
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/common/linux-procfs.h	2012-03-06 07:39:41.000000000 +0100
++++ gdb-7.4.50.20120120/gdb/common/linux-procfs.h	2012-03-06 07:39:50.771713128 +0100
+@@ -31,4 +31,8 @@ extern int linux_proc_get_tgid (int lwpi
+ 
+ extern int linux_proc_pid_is_stopped (pid_t pid);
+ 
++/* Return non-zero if PID is a zombie.  */
++
++extern int linux_proc_pid_is_zombie (pid_t pid);
++
+ #endif /* COMMON_LINUX_PROCFS_H */
+Index: gdb-7.4.50.20120120/gdb/common/linux-ptrace.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ gdb-7.4.50.20120120/gdb/common/linux-ptrace.c	2012-03-06 07:39:50.771713128 +0100
+@@ -0,0 +1,26 @@
++/* Linux-specific ptrace manipulation routines.
++   Copyright (C) 2012 Free Software Foundation, Inc.
++
++   This file is part of GDB.
++
++   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/>.  */
++
++#ifdef GDBSERVER
++#include "server.h"
++#else
++#include "defs.h"
++#include "gdb_string.h"
++#endif
++
++#include "linux-ptrace.h"
+Index: gdb-7.4.50.20120120/gdb/config/alpha/alpha-linux.mh
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/config/alpha/alpha-linux.mh	2012-01-10 17:30:44.000000000 +0100
++++ gdb-7.4.50.20120120/gdb/config/alpha/alpha-linux.mh	2012-03-06 07:39:50.771713128 +0100
+@@ -2,7 +2,7 @@
+ NAT_FILE= config/nm-linux.h
+ NATDEPFILES= inf-ptrace.o alpha-linux-nat.o \
+ 	fork-child.o proc-service.o linux-thread-db.o \
+-	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o
++	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o
+ NAT_CDEPS = $(srcdir)/proc-service.list
+ 
+ # The dynamically loaded libthread_db needs access to symbols in the
+Index: gdb-7.4.50.20120120/gdb/config/arm/linux.mh
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/config/arm/linux.mh	2011-08-24 14:07:25.000000000 +0200
++++ gdb-7.4.50.20120120/gdb/config/arm/linux.mh	2012-03-06 07:39:50.772713125 +0100
+@@ -3,7 +3,7 @@
+ NAT_FILE= config/nm-linux.h
+ NATDEPFILES= inf-ptrace.o fork-child.o arm-linux-nat.o \
+ 	proc-service.o linux-thread-db.o \
+-	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o
++	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o
+ NAT_CDEPS = $(srcdir)/proc-service.list
+ 
+ LOADLIBES= -ldl $(RDYNAMIC)
+Index: gdb-7.4.50.20120120/gdb/config/i386/linux.mh
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/config/i386/linux.mh	2012-03-06 07:39:41.000000000 +0100
++++ gdb-7.4.50.20120120/gdb/config/i386/linux.mh	2012-03-06 07:39:50.772713125 +0100
+@@ -4,7 +4,7 @@ NAT_FILE= nm-linux.h
+ NATDEPFILES= inf-ptrace.o fork-child.o \
+ 	i386-nat.o i386-linux-nat.o \
+ 	proc-service.o linux-thread-db.o \
+-	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o
++	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o
+ NAT_CDEPS = $(srcdir)/proc-service.list
+ 
+ # The dynamically loaded libthread_db needs access to symbols in the
+Index: gdb-7.4.50.20120120/gdb/config/i386/linux64.mh
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/config/i386/linux64.mh	2012-03-06 07:39:41.000000000 +0100
++++ gdb-7.4.50.20120120/gdb/config/i386/linux64.mh	2012-03-06 07:39:50.772713125 +0100
+@@ -3,7 +3,7 @@ NATDEPFILES= inf-ptrace.o fork-child.o \
+ 	i386-nat.o amd64-nat.o amd64-linux-nat.o \
+ 	linux-nat.o linux-osdata.o \
+ 	proc-service.o linux-thread-db.o linux-fork.o \
+-	linux-procfs.o
++	linux-procfs.o linux-ptrace.o
+ NAT_FILE= nm-linux64.h
+ NAT_CDEPS = $(srcdir)/proc-service.list
+ 
+Index: gdb-7.4.50.20120120/gdb/config/ia64/linux.mh
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/config/ia64/linux.mh	2012-01-10 17:30:44.000000000 +0100
++++ gdb-7.4.50.20120120/gdb/config/ia64/linux.mh	2012-03-06 07:39:50.772713125 +0100
+@@ -5,7 +5,7 @@ NATDEPFILES= inf-ptrace.o fork-child.o \
+ 	core-regset.o ia64-linux-nat.o \
+ 	proc-service.o linux-thread-db.o \
+ 	linux-nat.o linux-osdata.o linux-fork.o \
+-	linux-procfs.o
++	linux-procfs.o linux-ptrace.o
+ NAT_CDEPS = $(srcdir)/proc-service.list
+ 
+ LOADLIBES = -ldl $(RDYNAMIC)
+Index: gdb-7.4.50.20120120/gdb/config/m32r/linux.mh
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/config/m32r/linux.mh	2012-01-10 17:30:44.000000000 +0100
++++ gdb-7.4.50.20120120/gdb/config/m32r/linux.mh	2012-03-06 07:39:50.773713122 +0100
+@@ -3,7 +3,7 @@
+ NAT_FILE= config/nm-linux.h
+ NATDEPFILES= inf-ptrace.o fork-child.o				\
+ 	m32r-linux-nat.o proc-service.o linux-thread-db.o	\
+-	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o
++	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o
+ NAT_CDEPS = $(srcdir)/proc-service.list
+ 
+ LOADLIBES= -ldl $(RDYNAMIC)
+Index: gdb-7.4.50.20120120/gdb/config/m68k/linux.mh
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/config/m68k/linux.mh	2012-01-10 17:30:45.000000000 +0100
++++ gdb-7.4.50.20120120/gdb/config/m68k/linux.mh	2012-03-06 07:39:50.773713122 +0100
+@@ -4,7 +4,7 @@ NAT_FILE= config/nm-linux.h
+ NATDEPFILES= inf-ptrace.o fork-child.o \
+ 	m68klinux-nat.o \
+ 	proc-service.o linux-thread-db.o \
+-	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o
++	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o
+ NAT_CDEPS = $(srcdir)/proc-service.list
+ 
+ # The dynamically loaded libthread_db needs access to symbols in the
+Index: gdb-7.4.50.20120120/gdb/config/mips/linux.mh
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/config/mips/linux.mh	2011-08-24 14:07:26.000000000 +0200
++++ gdb-7.4.50.20120120/gdb/config/mips/linux.mh	2012-03-06 07:39:50.773713122 +0100
+@@ -3,7 +3,7 @@ NAT_FILE= config/nm-linux.h
+ NATDEPFILES= inf-ptrace.o fork-child.o mips-linux-nat.o \
+ 	linux-thread-db.o proc-service.o \
+ 	linux-nat.o linux-osdata.o linux-fork.o \
+-	linux-procfs.o
++	linux-procfs.o linux-ptrace.o
+ NAT_CDEPS = $(srcdir)/proc-service.list
+ 
+ LOADLIBES = -ldl $(RDYNAMIC)
+Index: gdb-7.4.50.20120120/gdb/config/pa/linux.mh
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/config/pa/linux.mh	2012-01-10 17:30:45.000000000 +0100
++++ gdb-7.4.50.20120120/gdb/config/pa/linux.mh	2012-03-06 07:39:50.773713122 +0100
+@@ -3,7 +3,7 @@ NAT_FILE= config/nm-linux.h
+ NATDEPFILES= inf-ptrace.o fork-child.o \
+ 	hppa-linux-nat.o proc-service.o linux-thread-db.o \
+ 	linux-nat.o linux-osdata.o linux-fork.o \
+-	linux-procfs.o
++	linux-procfs.o linux-ptrace.o
+ NAT_CDEPS = $(srcdir)/proc-service.list
+ 
+ LOADLIBES = -ldl $(RDYNAMIC)
+Index: gdb-7.4.50.20120120/gdb/config/powerpc/linux.mh
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/config/powerpc/linux.mh	2011-08-24 14:07:27.000000000 +0200
++++ gdb-7.4.50.20120120/gdb/config/powerpc/linux.mh	2012-03-06 07:39:50.773713122 +0100
+@@ -5,7 +5,7 @@ XM_CLIBS=
+ NAT_FILE= config/nm-linux.h
+ NATDEPFILES= inf-ptrace.o fork-child.o \
+ 	ppc-linux-nat.o proc-service.o linux-thread-db.o \
+-	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o
++	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o
+ NAT_CDEPS = $(srcdir)/proc-service.list
+ 
+ LOADLIBES = -ldl $(RDYNAMIC)
+Index: gdb-7.4.50.20120120/gdb/config/powerpc/ppc64-linux.mh
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/config/powerpc/ppc64-linux.mh	2011-08-24 14:07:27.000000000 +0200
++++ gdb-7.4.50.20120120/gdb/config/powerpc/ppc64-linux.mh	2012-03-06 07:39:50.774713118 +0100
+@@ -5,7 +5,7 @@ XM_CLIBS=
+ NAT_FILE= config/nm-linux.h
+ NATDEPFILES= inf-ptrace.o fork-child.o \
+ 	ppc-linux-nat.o proc-service.o linux-thread-db.o \
+-	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o
++	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o
+ NAT_CDEPS = $(srcdir)/proc-service.list
+ 
+ # The PowerPC has severe limitations on TOC size, and uses them even
+Index: gdb-7.4.50.20120120/gdb/config/powerpc/spu-linux.mh
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/config/powerpc/spu-linux.mh	2011-08-24 14:07:27.000000000 +0200
++++ gdb-7.4.50.20120120/gdb/config/powerpc/spu-linux.mh	2012-03-06 07:39:50.774713118 +0100
+@@ -4,5 +4,5 @@
+ # PPU side of the Cell BE and debugging the SPU side.
+ 
+ NATDEPFILES = spu-linux-nat.o fork-child.o inf-ptrace.o \
+-	      linux-procfs.o
++	      linux-procfs.o linux-ptrace.o
+ 
+Index: gdb-7.4.50.20120120/gdb/config/s390/s390.mh
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/config/s390/s390.mh	2012-01-05 18:07:05.000000000 +0100
++++ gdb-7.4.50.20120120/gdb/config/s390/s390.mh	2012-03-06 07:39:50.774713118 +0100
+@@ -2,6 +2,6 @@
+ NAT_FILE= config/nm-linux.h
+ NATDEPFILES= inf-ptrace.o fork-child.o s390-nat.o \
+ 	linux-thread-db.o proc-service.o \
+-	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o
++	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o
+ NAT_CDEPS = $(srcdir)/proc-service.list
+ LOADLIBES = -ldl $(RDYNAMIC)
+Index: gdb-7.4.50.20120120/gdb/config/sparc/linux.mh
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/config/sparc/linux.mh	2012-01-10 17:30:49.000000000 +0100
++++ gdb-7.4.50.20120120/gdb/config/sparc/linux.mh	2012-03-06 07:39:50.774713118 +0100
+@@ -4,7 +4,7 @@ NATDEPFILES= sparc-nat.o sparc-linux-nat
+ 	core-regset.o fork-child.o inf-ptrace.o \
+ 	proc-service.o linux-thread-db.o \
+ 	linux-nat.o linux-osdata.o linux-fork.o \
+-	linux-procfs.o
++	linux-procfs.o linux-ptrace.o
+ NAT_CDEPS = $(srcdir)/proc-service.list
+ 
+ # The dynamically loaded libthread_db needs access to symbols in the
+Index: gdb-7.4.50.20120120/gdb/config/sparc/linux64.mh
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/config/sparc/linux64.mh	2012-01-10 17:30:49.000000000 +0100
++++ gdb-7.4.50.20120120/gdb/config/sparc/linux64.mh	2012-03-06 07:39:50.775713114 +0100
+@@ -5,7 +5,7 @@ NATDEPFILES= sparc-nat.o sparc64-nat.o s
+ 	fork-child.o inf-ptrace.o \
+ 	proc-service.o linux-thread-db.o \
+ 	linux-nat.o linux-osdata.o linux-fork.o \
+-	linux-procfs.o
++	linux-procfs.o linux-ptrace.o
+ NAT_CDEPS = $(srcdir)/proc-service.list
+ 
+ # The dynamically loaded libthread_db needs access to symbols in the
+Index: gdb-7.4.50.20120120/gdb/config/xtensa/linux.mh
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/config/xtensa/linux.mh	2011-08-24 14:07:27.000000000 +0200
++++ gdb-7.4.50.20120120/gdb/config/xtensa/linux.mh	2012-03-06 07:39:50.775713114 +0100
+@@ -4,7 +4,7 @@ NAT_FILE= config/nm-linux.h
+ 
+ NATDEPFILES= inf-ptrace.o fork-child.o xtensa-linux-nat.o \
+ 	linux-thread-db.o proc-service.o \
+-	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o
++	linux-nat.o linux-osdata.o linux-fork.o linux-procfs.o linux-ptrace.o
+ NAT_CDEPS = $(srcdir)/proc-service.list
+ 
+ LOADLIBES = -ldl $(RDYNAMIC)
+Index: gdb-7.4.50.20120120/gdb/gdbserver/Makefile.in
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/gdbserver/Makefile.in	2012-01-04 09:17:23.000000000 +0100
++++ gdb-7.4.50.20120120/gdb/gdbserver/Makefile.in	2012-03-06 07:39:50.775713114 +0100
+@@ -408,6 +408,9 @@ signals.o: ../common/signals.c $(server_
+ linux-procfs.o: ../common/linux-procfs.c $(server_h)
+ 	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
+ 
++linux-ptrace.o: ../common/linux-ptrace.c $(server_h)
++	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
++
+ common-utils.o: ../common/common-utils.c $(server_h)
+ 	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
+ 
+Index: gdb-7.4.50.20120120/gdb/gdbserver/configure.srv
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/gdbserver/configure.srv	2011-12-06 15:14:49.000000000 +0100
++++ gdb-7.4.50.20120120/gdb/gdbserver/configure.srv	2012-03-06 07:39:50.775713114 +0100
+@@ -47,6 +47,7 @@ case "${target}" in
+ 			srv_regobj="${srv_regobj} arm-with-vfpv3.o"
+ 			srv_regobj="${srv_regobj} arm-with-neon.o"
+ 			srv_tgtobj="linux-low.o linux-osdata.o linux-arm-low.o linux-procfs.o"
++			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ 			srv_xmlfiles="arm-with-iwmmxt.xml"
+ 			srv_xmlfiles="${srv_xmlfiles} arm-with-vfpv2.xml"
+ 			srv_xmlfiles="${srv_xmlfiles} arm-with-vfpv3.xml"
+@@ -69,16 +70,19 @@ case "${target}" in
+ 			;;
+   bfin-*-*linux*)	srv_regobj=reg-bfin.o
+ 			srv_tgtobj="linux-low.o linux-osdata.o linux-bfin-low.o linux-procfs.o"
++			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ 			srv_linux_usrregs=yes
+ 			srv_linux_thread_db=yes
+ 			;;
+   crisv32-*-linux*)	srv_regobj=reg-crisv32.o
+ 			srv_tgtobj="linux-low.o linux-osdata.o linux-crisv32-low.o linux-procfs.o"
++			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ 			srv_linux_regsets=yes
+ 			srv_linux_thread_db=yes
+ 			;;
+   cris-*-linux*)	srv_regobj=reg-cris.o
+ 			srv_tgtobj="linux-low.o linux-osdata.o linux-cris-low.o linux-procfs.o"
++			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ 			srv_linux_usrregs=yes
+ 			srv_linux_thread_db=yes
+ 			;;
+@@ -93,6 +97,7 @@ case "${target}" in
+ 			    srv_xmlfiles="${srv_xmlfiles} $srv_amd64_linux_xmlfiles"
+ 			fi
+ 			srv_tgtobj="linux-low.o linux-osdata.o linux-x86-low.o i386-low.o i387-fp.o linux-procfs.o"
++			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ 			srv_linux_usrregs=yes
+ 			srv_linux_regsets=yes
+ 			srv_linux_thread_db=yes
+@@ -124,10 +129,12 @@ case "${target}" in
+ 			;;
+   ia64-*-linux*)	srv_regobj=reg-ia64.o
+ 			srv_tgtobj="linux-low.o linux-osdata.o linux-ia64-low.o linux-procfs.o"
++			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ 			srv_linux_usrregs=yes
+ 			;;
+   m32r*-*-linux*)	srv_regobj=reg-m32r.o
+ 			srv_tgtobj="linux-low.o linux-osdata.o linux-m32r-low.o linux-procfs.o"
++			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ 			srv_linux_usrregs=yes
+  			srv_linux_thread_db=yes
+ 			;;
+@@ -137,6 +144,7 @@ case "${target}" in
+                           srv_regobj=reg-m68k.o
+                         fi
+ 			srv_tgtobj="linux-low.o linux-osdata.o linux-m68k-low.o linux-procfs.o"
++			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ 			srv_linux_usrregs=yes
+ 			srv_linux_regsets=yes
+ 			srv_linux_thread_db=yes
+@@ -147,12 +155,14 @@ case "${target}" in
+                           srv_regobj=reg-m68k.o
+                         fi
+ 			srv_tgtobj="linux-low.o linux-osdata.o linux-m68k-low.o linux-procfs.o"
++			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ 			srv_linux_usrregs=yes
+ 			srv_linux_regsets=yes
+ 			srv_linux_thread_db=yes
+ 			;;
+   mips*-*-linux*)	srv_regobj="mips-linux.o mips64-linux.o"
+ 			srv_tgtobj="linux-low.o linux-osdata.o linux-mips-low.o linux-procfs.o"
++			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ 			srv_xmlfiles="mips-linux.xml"
+ 			srv_xmlfiles="${srv_xmlfiles} mips-cpu.xml"
+ 			srv_xmlfiles="${srv_xmlfiles} mips-cp0.xml"
+@@ -181,6 +191,7 @@ case "${target}" in
+ 			srv_regobj="${srv_regobj} powerpc-isa205-altivec64l.o"
+ 			srv_regobj="${srv_regobj} powerpc-isa205-vsx64l.o"
+ 			srv_tgtobj="linux-low.o linux-osdata.o linux-ppc-low.o linux-procfs.o"
++			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ 			srv_xmlfiles="rs6000/powerpc-32l.xml"
+ 			srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-altivec32l.xml"
+ 			srv_xmlfiles="${srv_xmlfiles} rs6000/powerpc-cell32l.xml"
+@@ -223,6 +234,7 @@ case "${target}" in
+ 			srv_regobj="${srv_regobj} s390x-linux64v1.o"
+ 			srv_regobj="${srv_regobj} s390x-linux64v2.o"
+ 			srv_tgtobj="linux-low.o linux-osdata.o linux-s390-low.o linux-procfs.o"
++			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ 			srv_xmlfiles="s390-linux32.xml"
+ 			srv_xmlfiles="${srv_xmlfiles} s390-linux32v1.xml"
+ 			srv_xmlfiles="${srv_xmlfiles} s390-linux32v2.xml"
+@@ -243,12 +255,14 @@ case "${target}" in
+ 			;;
+   sh*-*-linux*)		srv_regobj=reg-sh.o
+ 			srv_tgtobj="linux-low.o linux-osdata.o linux-sh-low.o linux-procfs.o"
++			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ 			srv_linux_usrregs=yes
+ 			srv_linux_regsets=yes
+ 			srv_linux_thread_db=yes
+ 			;;
+   sparc*-*-linux*)	srv_regobj=reg-sparc64.o
+ 			srv_tgtobj="linux-low.o linux-osdata.o linux-sparc-low.o linux-procfs.o"
++			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ 			srv_linux_regsets=yes
+ 			srv_linux_thread_db=yes
+ 			;;
+@@ -265,12 +279,14 @@ case "${target}" in
+ 			srv_xmlfiles="${srv_xmlfiles} tic6x-gp.xml"
+ 			srv_xmlfiles="${srv_xmlfiles} tic6x-c6xp.xml"
+   			srv_tgtobj="linux-low.o linux-osdata.o linux-tic6x-low.o linux-procfs.o"
++			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ 			srv_linux_regsets=yes
+ 			srv_linux_usrregs=yes
+ 			srv_linux_thread_db=yes
+ 			;;
+   x86_64-*-linux*)	srv_regobj="$srv_amd64_linux_regobj $srv_i386_linux_regobj"
+ 			srv_tgtobj="linux-low.o linux-osdata.o linux-x86-low.o i386-low.o i387-fp.o linux-procfs.o"
++			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ 			srv_xmlfiles="$srv_i386_linux_xmlfiles $srv_amd64_linux_xmlfiles"
+ 			srv_linux_usrregs=yes # This is for i386 progs.
+ 			srv_linux_regsets=yes
+@@ -285,6 +301,7 @@ case "${target}" in
+ 
+   xtensa*-*-linux*)	srv_regobj=reg-xtensa.o
+ 			srv_tgtobj="linux-low.o linux-osdata.o linux-xtensa-low.o linux-procfs.o"
++			srv_tgtobj="${srv_tgtobj} linux-ptrace.o"
+ 			srv_linux_regsets=yes
+ 			;;
+   *)			echo "Error: target not supported by gdbserver."
+Index: gdb-7.4.50.20120120/gdb/gdbserver/linux-low.c
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/gdbserver/linux-low.c	2012-03-06 07:39:41.000000000 +0100
++++ gdb-7.4.50.20120120/gdb/gdbserver/linux-low.c	2012-03-06 07:39:50.776713111 +0100
+@@ -630,10 +630,10 @@ linux_attach_lwp_1 (unsigned long lwpid,
+ 	  fflush (stderr);
+ 	  return;
+ 	}
+-      else
+-	/* If we fail to attach to a process, report an error.  */
+-	error ("Cannot attach to lwp %ld: %s (%d)\n", lwpid,
+-	       strerror (errno), errno);
++
++      /* If we fail to attach to a process, report an error.  */
++      error ("Cannot attach to lwp %ld: %s (%d)\n", lwpid,
++	     strerror (errno), errno);
+     }
+ 
+   if (initial)
+Index: gdb-7.4.50.20120120/gdb/linux-nat.c
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/linux-nat.c	2012-03-06 07:39:41.000000000 +0100
++++ gdb-7.4.50.20120120/gdb/linux-nat.c	2012-03-06 07:39:50.777713108 +0100
+@@ -2464,37 +2464,6 @@ linux_handle_extended_wait (struct lwp_i
+ 		  _("unknown ptrace event %d"), event);
+ }
+ 
+-/* Return non-zero if LWP is a zombie.  */
+-
+-static int
+-linux_lwp_is_zombie (long lwp)
+-{
+-  char buffer[MAXPATHLEN];
+-  FILE *procfile;
+-  int retval;
+-  int have_state;
+-
+-  xsnprintf (buffer, sizeof (buffer), "/proc/%ld/status", lwp);
+-  procfile = fopen (buffer, "r");
+-  if (procfile == NULL)
+-    {
+-      warning (_("unable to open /proc file '%s'"), buffer);
+-      return 0;
+-    }
+-
+-  have_state = 0;
+-  while (fgets (buffer, sizeof (buffer), procfile) != NULL)
+-    if (strncmp (buffer, "State:", 6) == 0)
+-      {
+-	have_state = 1;
+-	break;
+-      }
+-  retval = (have_state
+-	    && strcmp (buffer, "State:\tZ (zombie)\n") == 0);
+-  fclose (procfile);
+-  return retval;
+-}
+-
+ /* Wait for LP to stop.  Returns the wait status, or 0 if the LWP has
+    exited.  */
+ 
+@@ -2548,10 +2517,10 @@ wait_lwp (struct lwp_info *lp)
+ 
+ 	 This is racy, what if the tgl becomes a zombie right after we check?
+ 	 Therefore always use WNOHANG with sigsuspend - it is equivalent to
+-	 waiting waitpid but the linux_lwp_is_zombie is safe this way.  */
++	 waiting waitpid but linux_proc_pid_is_zombie is safe this way.  */
+ 
+       if (GET_PID (lp->ptid) == GET_LWP (lp->ptid)
+-	  && linux_lwp_is_zombie (GET_LWP (lp->ptid)))
++	  && linux_proc_pid_is_zombie (GET_LWP (lp->ptid)))
+ 	{
+ 	  thread_dead = 1;
+ 	  if (debug_linux_nat)
+@@ -3431,7 +3400,7 @@ check_zombie_leaders (void)
+ 	  /* Check if there are other threads in the group, as we may
+ 	     have raced with the inferior simply exiting.  */
+ 	  && num_lwps (inf->pid) > 1
+-	  && linux_lwp_is_zombie (inf->pid))
++	  && linux_proc_pid_is_zombie (inf->pid))
+ 	{
+ 	  if (debug_linux_nat)
+ 	    fprintf_unfiltered (gdb_stdlog,
diff --git a/gdb-attach-fail-reasons-4of5.patch b/gdb-attach-fail-reasons-4of5.patch
new file mode 100644
index 0000000..564ee72
--- /dev/null
+++ b/gdb-attach-fail-reasons-4of5.patch
@@ -0,0 +1,402 @@
+http://sourceware.org/ml/gdb-patches/2012-03/msg00170.html
+Subject: [patch 2/3] attach-fail-reasons: Say more than ptrace: Operation not permitted.
+
+Hi,
+
+There is a common question on #gdb and also already described:
+
+http://sourceware.org/gdb/wiki/FAQ
+16. Getting an internal error or other error while attaching to processes on
+    GNU/Linux
+->
+    Try setenforce 0 (SELinux) or echo 0 >/proc/sys/kernel/yama/ptrace_scope
+    (ptrace scope) to disable system security protections. 
+
+and here is a patch to give some explanations.
+
+More reasons can be given later, this is a container for them and it contains
+some useful ones already.
+
+No regressions on {x86_64,x86_64-m32,i686}-fedora17-linux-gnu and with
+non-extended gdbserver.
+
+The testcase does not test gdbserver, somehow it is a bit difficult without
+having shell on target.
+
+Attaching to process 27480
+ptrace: Operation not permitted.
+(gdb) _
+->
+Attaching to process 27480
+warning: process 27480 is already traced by process 29011
+ptrace: Operation not permitted.
+(gdb) _
+
+
+Thanks,
+Jan
+
+
+gdb/
+2012-03-06  Jan Kratochvil  <jan.kratochvil at redhat.com>
+
+	* common/linux-procfs.c (linux_proc_get_int): New, from
+	linux_proc_get_tgid.
+	(linux_proc_get_tgid): Only call linux_proc_get_int.
+	(linux_proc_get_tracerpid): New.
+	(linux_proc_pid_has_state): New, from linux_proc_pid_is_zombie.
+	(linux_proc_pid_is_stopped, linux_proc_pid_is_zombie): Only call
+	linux_proc_pid_has_state.
+	* common/linux-procfs.h (linux_proc_get_tracerpid): New declaration.
+	* common/linux-ptrace.c: Include linux-procfs.h.
+	(linux_ptrace_attach_warnings): New.
+	* common/linux-ptrace.h (linux_ptrace_attach_warnings): New declaration.
+	* linux-nat.c: Include exceptions.h and linux-ptrace.h.
+	(linux_nat_attach): New variable ex.  Wrap to_attach by TRY_CATCH and
+	call linux_ptrace_attach_warnings.
+
+gdb/gdbserver/
+2012-03-06  Jan Kratochvil  <jan.kratochvil at redhat.com>
+
+	* linux-low.c (linux_attach_lwp_1): Call linux_ptrace_attach_warnings.
+
+gdb/testsuite/
+2012-03-06  Jan Kratochvil  <jan.kratochvil at redhat.com>
+
+	* gdb.base/attach-twice.c: New files.
+	* gdb.base/attach-twice.exp: New files.
+
+Index: gdb-7.4.50.20120120/gdb/common/linux-procfs.c
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/common/linux-procfs.c	2012-03-06 07:34:00.000000000 +0100
++++ gdb-7.4.50.20120120/gdb/common/linux-procfs.c	2012-03-06 07:34:17.586816449 +0100
+@@ -28,67 +28,54 @@
+ /* Return the TGID of LWPID from /proc/pid/status.  Returns -1 if not
+    found.  */
+ 
+-int
+-linux_proc_get_tgid (int lwpid)
++static int
++linux_proc_get_int (int lwpid, const char *field)
+ {
++  size_t field_len = strlen (field);
+   FILE *status_file;
+   char buf[100];
+-  int tgid = -1;
++  int retval = -1;
+ 
+   snprintf (buf, sizeof (buf), "/proc/%d/status", (int) lwpid);
+   status_file = fopen (buf, "r");
+-  if (status_file != NULL)
++  if (status_file == NULL)
+     {
+-      while (fgets (buf, sizeof (buf), status_file))
+-	{
+-	  if (strncmp (buf, "Tgid:", 5) == 0)
+-	    {
+-	      tgid = strtoul (buf + strlen ("Tgid:"), NULL, 10);
+-	      break;
+-	    }
+-	}
+-
+-      fclose (status_file);
++      warning (_("unable to open /proc file '%s'"), buf);
++      return -1;
+     }
+ 
+-  return tgid;
++  while (fgets (buf, sizeof (buf), status_file))
++    if (strncmp (buf, field, field_len) == 0 && buf[field_len] == ':')
++      {
++	retval = strtol (&buf[field_len + 1], NULL, 10);
++	break;
++      }
++
++  fclose (status_file);
++  return retval;
+ }
+ 
+-/* Detect `T (stopped)' in `/proc/PID/status'.
+-   Other states including `T (tracing stop)' are reported as false.  */
++/* Return the TGID of LWPID from /proc/pid/status.  Returns -1 if not
++   found.  */
+ 
+ int
+-linux_proc_pid_is_stopped (pid_t pid)
++linux_proc_get_tgid (int lwpid)
+ {
+-  FILE *status_file;
+-  char buf[100];
+-  int retval = 0;
++  return linux_proc_get_int (lwpid, "Tgid");
++}
+ 
+-  snprintf (buf, sizeof (buf), "/proc/%d/status", (int) pid);
+-  status_file = fopen (buf, "r");
+-  if (status_file != NULL)
+-    {
+-      int have_state = 0;
++/* See linux-procfs.h.  */
+ 
+-      while (fgets (buf, sizeof (buf), status_file))
+-	{
+-	  if (strncmp (buf, "State:", 6) == 0)
+-	    {
+-	      have_state = 1;
+-	      break;
+-	    }
+-	}
+-      if (have_state && strstr (buf, "T (stopped)") != NULL)
+-	retval = 1;
+-      fclose (status_file);
+-    }
+-  return retval;
++pid_t
++linux_proc_get_tracerpid (int lwpid)
++{
++  return linux_proc_get_int (lwpid, "TracerPid");
+ }
+ 
+-/* See linux-procfs.h declaration.  */
++/* Return non-zero if 'State' of /proc/PID/status contains STATE.  */
+ 
+-int
+-linux_proc_pid_is_zombie (pid_t pid)
++static int
++linux_proc_pid_has_state (pid_t pid, const char *state)
+ {
+   char buffer[100];
+   FILE *procfile;
+@@ -110,8 +97,24 @@ linux_proc_pid_is_zombie (pid_t pid)
+ 	have_state = 1;
+ 	break;
+       }
+-  retval = (have_state
+-	    && strcmp (buffer, "State:\tZ (zombie)\n") == 0);
++  retval = (have_state && strstr (buffer, state) != NULL);
+   fclose (procfile);
+   return retval;
+ }
++
++/* Detect `T (stopped)' in `/proc/PID/status'.
++   Other states including `T (tracing stop)' are reported as false.  */
++
++int
++linux_proc_pid_is_stopped (pid_t pid)
++{
++  return linux_proc_pid_has_state (pid, "T (stopped)");
++}
++
++/* See linux-procfs.h declaration.  */
++
++int
++linux_proc_pid_is_zombie (pid_t pid)
++{
++  return linux_proc_pid_has_state (pid, "Z (zombie)");
++}
+Index: gdb-7.4.50.20120120/gdb/common/linux-procfs.h
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/common/linux-procfs.h	2012-03-06 07:34:00.000000000 +0100
++++ gdb-7.4.50.20120120/gdb/common/linux-procfs.h	2012-03-06 07:34:17.586816449 +0100
+@@ -26,6 +26,11 @@
+ 
+ extern int linux_proc_get_tgid (int lwpid);
+ 
++/* Return the TracerPid of LWPID from /proc/pid/status.  Returns -1 if not
++   found.  */
++
++extern pid_t linux_proc_get_tracerpid (int lwpid);
++
+ /* Detect `T (stopped)' in `/proc/PID/status'.
+    Other states including `T (tracing stop)' are reported as false.  */
+ 
+Index: gdb-7.4.50.20120120/gdb/common/linux-ptrace.c
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/common/linux-ptrace.c	2012-03-06 07:34:00.000000000 +0100
++++ gdb-7.4.50.20120120/gdb/common/linux-ptrace.c	2012-03-06 07:34:17.586816449 +0100
+@@ -24,3 +24,21 @@
+ #endif
+ 
+ #include "linux-ptrace.h"
++#include "linux-procfs.h"
++
++/* Print all possible reasons we could fail to attach PID.  */
++
++void
++linux_ptrace_attach_warnings (pid_t pid)
++{
++  pid_t tracerpid;
++
++  tracerpid = linux_proc_get_tracerpid (pid);
++  if (tracerpid > 0)
++    warning (_("process %d is already traced by process %d"), (int) pid,
++	     (int) tracerpid);
++
++  if (linux_proc_pid_is_zombie (pid))
++    warning (_("process %d is a zombie - the process has already terminated"),
++	     (int) pid);
++}
+Index: gdb-7.4.50.20120120/gdb/common/linux-ptrace.h
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/common/linux-ptrace.h	2012-01-04 09:17:18.000000000 +0100
++++ gdb-7.4.50.20120120/gdb/common/linux-ptrace.h	2012-03-06 07:34:17.586816449 +0100
+@@ -65,4 +65,6 @@
+ #define __WALL          0x40000000 /* Wait for any child.  */
+ #endif
+ 
++extern void linux_ptrace_attach_warnings (pid_t pid);
++
+ #endif /* COMMON_LINUX_PTRACE_H */
+Index: gdb-7.4.50.20120120/gdb/gdbserver/linux-low.c
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/gdbserver/linux-low.c	2012-03-06 07:34:00.000000000 +0100
++++ gdb-7.4.50.20120120/gdb/gdbserver/linux-low.c	2012-03-06 07:34:17.587816446 +0100
+@@ -632,6 +632,7 @@ linux_attach_lwp_1 (unsigned long lwpid,
+ 	}
+ 
+       /* If we fail to attach to a process, report an error.  */
++      linux_ptrace_attach_warnings (lwpid);
+       error ("Cannot attach to lwp %ld: %s (%d)\n", lwpid,
+ 	     strerror (errno), errno);
+     }
+Index: gdb-7.4.50.20120120/gdb/linux-nat.c
+===================================================================
+--- gdb-7.4.50.20120120.orig/gdb/linux-nat.c	2012-03-06 07:34:00.000000000 +0100
++++ gdb-7.4.50.20120120/gdb/linux-nat.c	2012-03-06 07:34:29.860775803 +0100
+@@ -59,6 +59,8 @@
+ #include "solib.h"
+ #include "linux-osdata.h"
+ #include "cli/cli-utils.h"
++#include "exceptions.h"
++#include "linux-ptrace.h"
+ 
+ #ifndef SPUFS_MAGIC
+ #define SPUFS_MAGIC 0x23c9b64e
+@@ -1613,11 +1615,22 @@ linux_nat_attach (struct target_ops *ops
+   struct lwp_info *lp;
+   int status;
+   ptid_t ptid;
++  volatile struct gdb_exception ex;
+ 
+   /* Make sure we report all signals during attach.  */
+   linux_nat_pass_signals (0, NULL);
+ 
+-  linux_ops->to_attach (ops, args, from_tty);
++  TRY_CATCH (ex, RETURN_MASK_ERROR)
++    {
++      linux_ops->to_attach (ops, args, from_tty);
++    }
++  if (ex.reason < 0)
++    {
++      pid_t pid = parse_pid_to_attach (args);
++
++      linux_ptrace_attach_warnings (pid);
++      throw_exception (ex);
++    }
+ 
+   /* The ptrace base target adds the main thread with (pid,0,0)
+      format.  Decorate it with lwp info.  */
+Index: gdb-7.4.50.20120120/gdb/testsuite/gdb.base/attach-twice.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ gdb-7.4.50.20120120/gdb/testsuite/gdb.base/attach-twice.c	2012-03-06 07:34:17.589816440 +0100
+@@ -0,0 +1,42 @@
++/* This testcase is part of GDB, the GNU debugger.
++
++   Copyright 2011-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 <stdlib.h>
++#include <unistd.h>
++#include <sys/ptrace.h>
++#include <errno.h>
++
++int
++main (void)
++{
++  long l;
++
++  switch (fork ())
++  {
++    case -1:
++      perror ("fork");
++      exit (1);
++    case 0:
++      errno = 0;
++      ptrace (PTRACE_ATTACH, getppid (), NULL, NULL);
++      if (errno != 0)
++	perror ("PTRACE_ATTACH");
++      break;
++  }
++  sleep (600);
++  return 0;
++}
+Index: gdb-7.4.50.20120120/gdb/testsuite/gdb.base/attach-twice.exp
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ gdb-7.4.50.20120120/gdb/testsuite/gdb.base/attach-twice.exp	2012-03-06 07:34:17.589816440 +0100
+@@ -0,0 +1,52 @@
++# Copyright (C) 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/>.
++
++# Manipulation with PID on target is not supported.
++if [is_remote target] then {
++    return 0
++}
++
++set testfile attach-twice
++set executable ${testfile}
++set binfile ${objdir}/${subdir}/${executable}
++
++if { [prepare_for_testing ${testfile}.exp $executable] } {
++    return -1
++}
++
++set testpid [eval exec $binfile &]
++exec sleep 2
++
++set parentpid 0
++
++set test "attach"
++gdb_test_multiple "attach $testpid" $test {
++    -re "Attaching to program: \[^\r\n\]*, process $testpid\r\n.*warning: process $testpid is already traced by process (\[0-9\]+)\r\n.*ptrace: Operation not permitted\\.\r\n$gdb_prompt $" {
++	set parentpid $expect_out(1,string)
++	pass $test
++    }
++    -re "Attaching to program: \[^\r\n\]*, process $testpid\r\n.*ptrace: Operation not permitted\\.\r\n$gdb_prompt $" {
++	fail $test
++    }
++    -re "\r\n$gdb_prompt $" {
++	xfail $test
++    }
++}
++
++eval exec ps xfw
++if {$parentpid != 0} {
++  eval exec kill -9 $parentpid
++}
++eval exec kill -9 $testpid
diff --git a/gdb-attach-fail-reasons-5of5.patch b/gdb-attach-fail-reasons-5of5.patch
new file mode 100644
index 0000000..aa4a44f
--- /dev/null
+++ b/gdb-attach-fail-reasons-5of5.patch
@@ -0,0 +1,209 @@
+http://sourceware.org/ml/gdb-patches/2012-03/msg00171.html
+Subject: [patch 3/3] attach-fail-reasons: SELinux deny_ptrace
+
+Hi,
+
+and here is the last bit for new SELinux 'deny_ptrace':
+	https://bugzilla.redhat.com/show_bug.cgi?id=786878
+
+As even PTRACE_TRACEME fails in such case it needs to install hook for even
+that event.
+
+
+Thanks,
+Jan
+
+
+gdb/
+2012-03-06  Jan Kratochvil  <jan.kratochvil at redhat.com>
+
+	* common/linux-ptrace.c [HAVE_SELINUX_SELINUX_H]: include
+	selinux/selinux.h.
+	(linux_ptrace_attach_warnings): Call linux_ptrace_create_warnings.
+	(linux_ptrace_create_warnings): New.
+	* common/linux-ptrace.h (linux_ptrace_create_warnings): New declaration.
+	* config.in: Regenerate.
+	* configure: Regenerate.
+	* configure.ac: Check selinux/selinux.h and the selinux library.
+	* inf-ptrace.c (inf_ptrace_me): Check the ptrace result.
+	* linux-nat.c (linux_nat_create_inferior): New variable ex.  Wrap
+	to_create_inferior into TRY_CATCH, call linux_ptrace_create_warnings.
+
+gdb/gdbserver/
+	* config.in: Regenerate.
+	* configure: Regenerate.
+	* configure.ac: Check selinux/selinux.h and the selinux library.
+	* linux-low.c (linux_traceme): New function.
+	(linux_create_inferior, linux_tracefork_child): Call it instead of
+	direct ptrace.
+
+--- a/gdb/common/linux-ptrace.c
++++ b/gdb/common/linux-ptrace.c
+@@ -26,6 +26,10 @@
+ #include "linux-ptrace.h"
+ #include "linux-procfs.h"
+ 
++#ifdef HAVE_SELINUX_SELINUX_H
++# include <selinux/selinux.h>
++#endif /* HAVE_SELINUX_SELINUX_H */
++
+ /* Print all possible reasons we could fail to attach PID.  */
+ 
+ void
+@@ -41,4 +45,21 @@ linux_ptrace_attach_warnings (pid_t pid)
+   if (linux_proc_pid_is_zombie (pid))
+     warning (_("process %d is a zombie - the process has already terminated"),
+ 	     (int) pid);
++
++  linux_ptrace_create_warnings ();
++}
++
++/* Print all possible reasons we could fail to create a traced process.  */
++
++void
++linux_ptrace_create_warnings (void)
++{
++#ifdef HAVE_LIBSELINUX
++  /* -1 is returned for errors, 0 if it has no effect, 1 if PTRACE_ATTACH is
++     forbidden.  */
++  if (security_get_boolean_active ("deny_ptrace") == 1)
++    warning (_("the SELinux boolean 'deny_ptrace' is enabled, "
++	       "you can disable this process attach protection by: "
++	       "(gdb) shell sudo setsebool deny_ptrace=0"));
++#endif /* HAVE_LIBSELINUX */
+ }
+--- a/gdb/common/linux-ptrace.h
++++ b/gdb/common/linux-ptrace.h
+@@ -66,5 +66,6 @@
+ #endif
+ 
+ extern void linux_ptrace_attach_warnings (pid_t pid);
++extern void linux_ptrace_create_warnings (void);
+ 
+ #endif /* COMMON_LINUX_PTRACE_H */
+--- a/gdb/configure.ac
++++ b/gdb/configure.ac
+@@ -1748,6 +1748,10 @@ then
+ 	      [Define if you support the personality syscall.])
+ fi
+ 
++dnl Check security_get_boolean_active availability.
++AC_CHECK_HEADERS(selinux/selinux.h)
++AC_CHECK_LIB(selinux, security_get_boolean_active)
++
+ dnl Handle optional features that can be enabled.
+ 
+ # Support for --with-sysroot is a copy of GDB_AC_WITH_DIR,
+--- a/gdb/gdbserver/configure.ac
++++ b/gdb/gdbserver/configure.ac
+@@ -411,6 +411,10 @@ if $want_ipa ; then
+    fi
+ fi
+ 
++dnl Check security_get_boolean_active availability.
++AC_CHECK_HEADERS(selinux/selinux.h)
++AC_CHECK_LIB(selinux, security_get_boolean_active)
++
+ AC_SUBST(GDBSERVER_DEPFILES)
+ AC_SUBST(GDBSERVER_LIBS)
+ AC_SUBST(USE_THREAD_DB)
+--- a/gdb/gdbserver/linux-low.c
++++ b/gdb/gdbserver/linux-low.c
+@@ -550,6 +550,25 @@ add_lwp (ptid_t ptid)
+   return lwp;
+ }
+ 
++/* Execute PTRACE_TRACEME with error checking.  */
++
++static void
++linux_traceme (const char *program)
++{
++  int save_errno;
++
++  errno = 0;
++  if (ptrace (PTRACE_TRACEME, 0, NULL, NULL) == 0)
++    return;
++
++  save_errno = errno;
++  linux_ptrace_create_warnings ();
++  fprintf (stderr, _("Cannot trace created process %s: %s.\n"), program,
++	   strerror (save_errno));
++  fflush (stderr);
++  _exit (0177);
++}
++
+ /* Start an inferior process and returns its pid.
+    ALLARGS is a vector of program-name and args. */
+ 
+@@ -590,7 +609,7 @@ linux_create_inferior (char *program, char **allargs)
+ 
+   if (pid == 0)
+     {
+-      ptrace (PTRACE_TRACEME, 0, 0, 0);
++      linux_traceme (program);
+ 
+ #ifndef __ANDROID__ /* Bionic doesn't use SIGRTMIN the way glibc does.  */
+       signal (__SIGRTMIN + 1, SIG_DFL);
+@@ -4386,7 +4405,7 @@ linux_tracefork_grandchild (void *arg)
+ static int
+ linux_tracefork_child (void *arg)
+ {
+-  ptrace (PTRACE_TRACEME, 0, 0, 0);
++  linux_traceme ("PTRACE_O_TRACEFORK test");
+   kill (getpid (), SIGSTOP);
+ 
+ #if !(defined(__UCLIBC__) && defined(HAS_NOMMU))
+--- a/gdb/inf-ptrace.c
++++ b/gdb/inf-ptrace.c
+@@ -105,7 +105,15 @@ static void
+ inf_ptrace_me (void)
+ {
+   /* "Trace me, Dr. Memory!"  */
++  errno = 0;
+   ptrace (PT_TRACE_ME, 0, (PTRACE_TYPE_ARG3)0, 0);
++  if (errno != 0)
++    {
++      fprintf_unfiltered (gdb_stderr, _("Cannot create process: %s\n"),
++			  safe_strerror (errno));
++      gdb_flush (gdb_stderr);
++      _exit (0177);
++    }
+ }
+ 
+ /* Start a new inferior Unix child process.  EXEC_FILE is the file to
+--- a/gdb/linux-nat.c
++++ b/gdb/linux-nat.c
+@@ -1570,6 +1570,7 @@ linux_nat_create_inferior (struct target_ops *ops,
+ #ifdef HAVE_PERSONALITY
+   int personality_orig = 0, personality_set = 0;
+ #endif /* HAVE_PERSONALITY */
++  volatile struct gdb_exception ex;
+ 
+   /* The fork_child mechanism is synchronous and calls target_wait, so
+      we have to mask the async mode.  */
+@@ -1594,7 +1595,10 @@ linux_nat_create_inferior (struct target_ops *ops,
+   /* Make sure we report all signals during startup.  */
+   linux_nat_pass_signals (0, NULL);
+ 
+-  linux_ops->to_create_inferior (ops, exec_file, allargs, env, from_tty);
++  TRY_CATCH (ex, RETURN_MASK_ERROR)
++    {
++      linux_ops->to_create_inferior (ops, exec_file, allargs, env, from_tty);
++    }
+ 
+ #ifdef HAVE_PERSONALITY
+   if (personality_set)
+@@ -1606,6 +1610,12 @@ linux_nat_create_inferior (struct target_ops *ops,
+ 		 safe_strerror (errno));
+     }
+ #endif /* HAVE_PERSONALITY */
++
++  if (ex.reason < 0)
++    {
++      linux_ptrace_create_warnings ();
++      throw_exception (ex);
++    }
+ }
+ 
+ static void
+
diff --git a/gdb.spec b/gdb.spec
index 6422732..78e7ea3 100644
--- a/gdb.spec
+++ b/gdb.spec
@@ -33,7 +33,7 @@ Version: 7.4.50.%{snap}
 
 # The release always contains a leading reserved number, start it at 1.
 # `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing.
-Release: 27%{?dist}
+Release: 28%{?dist}
 
 License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and BSD and Public Domain
 Group: Development/Debuggers
@@ -552,6 +552,14 @@ Patch646: gdb-exit-warning.patch
 #=push+work
 Patch648: gdb-archer-vla-rhel5gcc.patch
 
+# Print reasons for failed attach/spawn incl. SELinux deny_ptrace (BZ 786878).
+#=push
+Patch649: gdb-attach-fail-reasons-1of5.patch
+Patch650: gdb-attach-fail-reasons-2of5.patch
+Patch651: gdb-attach-fail-reasons-3of5.patch
+Patch652: gdb-attach-fail-reasons-4of5.patch
+Patch653: gdb-attach-fail-reasons-5of5.patch
+
 %if 0%{!?rhel:1} || 0%{?rhel} > 6
 # RL_STATE_FEDORA_GDB would not be found for:
 # Patch642: gdb-readline62-ask-more-rh.patch
@@ -830,6 +838,11 @@ rm -f gdb/jv-exp.c gdb/m2-exp.c gdb/objc-exp.c gdb/p-exp.c
 %patch645 -p1
 %patch646 -p1
 %patch648 -p1
+%patch649 -p1
+%patch650 -p1
+%patch651 -p1
+%patch652 -p1
+%patch653 -p1
 
 %patch393 -p1
 %if 0%{!?el5:1} || 0%{?scl:1}
@@ -1296,6 +1309,9 @@ fi
 %endif # 0%{!?el5:1} || "%{_target_cpu}" == "noarch"
 
 %changelog
+* Tue Mar  6 2012 Jan Kratochvil <jan.kratochvil at redhat.com> - 7.4.50.20120120-28.fc17
+- Print reasons for failed attach/spawn incl. SELinux deny_ptrace (BZ 786878).
+
 * Sun Mar  4 2012 Jan Kratochvil <jan.kratochvil at redhat.com> - 7.4.50.20120120-27.fc17
 - [rhel5] Fix up the previous commit (BZ 799318).
 


More information about the scm-commits mailing list