[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