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


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

[PATCH 3/3] debugging with yama: check for yama ptrace_scope


Hi.

This patch augments the attach fail error text if ptrace_scope
is the problem.

Regression tested on amd64-linux.

2015-09-28  Doug Evans  <dje@google.com>

	* inf-ptrace.c (inf_ptrace_attach): Call throw_perror_with_name
	passing SYSCALL_FAILED_ERROR and errno.
	* linux-nat.c (linux_nat_attach): Rewrite attach fail error processing.
	* nat/linux-ptrace.c: #include <ctype.h>, "filestuff.h".
	(ptrace_scope_file): New static global.
	(linux_yama_ptrace_scope_is_on): New function.
	(linux_ptrace_attach_fail_reason): Make static.
	Prepend ", " to messages.  Add yama ptrace_scope check.
	(linux_ptrace_attach_fail_reason_string): Rewrite message construction.
	Add kernel.yama.ptrace_scope suggestion.
	* nat/linux-ptrace.h (linux_ptrace_attach_fail_reason): Delete.

diff --git a/gdb/inf-ptrace.c b/gdb/inf-ptrace.c
index c98de4a..7fbd8a3 100644
--- a/gdb/inf-ptrace.c
+++ b/gdb/inf-ptrace.c
@@ -197,7 +197,7 @@ inf_ptrace_attach (struct target_ops *ops, const char *args, int from_tty)
   errno = 0;
   ptrace (PT_ATTACH, pid, (PTRACE_TYPE_ARG3)0, 0);
   if (errno != 0)
-    perror_with_name (("ptrace"));
+    throw_perror_with_name (SYSCALL_FAILED_ERROR, errno, _("ptrace"));
 #else
   error (_("This system does not support attaching to a process"));
 #endif
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 6423ecc..bdea141 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -1280,23 +1280,18 @@ linux_nat_attach (struct target_ops *ops, const char *args, int from_tty)
   CATCH (ex, RETURN_MASK_ERROR)
     {
       pid_t pid = parse_pid_to_attach (args);
-      struct buffer buffer;
-      char *message, *buffer_s;
+      char *reason;

-      message = xstrdup (ex.message);
-      make_cleanup (xfree, message);
-
-      buffer_init (&buffer);
-      linux_ptrace_attach_fail_reason (pid, &buffer);
-
-      buffer_grow_str0 (&buffer, "");
-      buffer_s = buffer_finish (&buffer);
-      make_cleanup (xfree, buffer_s);
-
-      if (*buffer_s != '\0')
-	throw_error (ex.error, "warning: %s\n%s", buffer_s, message);
+      if (ex.error == SYSCALL_FAILED_ERROR)
+	{
+	  ptid = ptid_build (pid, pid, 0);
+	  reason = linux_ptrace_attach_fail_reason_string (ptid, ex.suberror);
+	  throw_error_with_suberror (ex.error, ex.suberror,
+				     "Cannot attach to process %ld: %s",
+				     (unsigned long) pid, reason);
+	}
       else
-	throw_error (ex.error, "%s", message);
+	throw_error (ex.error, "%s", ex.message);
     }
   END_CATCH

diff --git a/gdb/nat/linux-ptrace.c b/gdb/nat/linux-ptrace.c
index 97331a4..deff050 100644
--- a/gdb/nat/linux-ptrace.c
+++ b/gdb/nat/linux-ptrace.c
@@ -17,37 +17,81 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */

 #include "common-defs.h"
+#include <ctype.h>
 #include "linux-ptrace.h"
 #include "linux-procfs.h"
 #include "linux-waitpid.h"
 #include "buffer.h"
 #include "gdb_wait.h"
 #include "gdb_ptrace.h"
+#include "filestuff.h"

 /* Stores the ptrace options supported by the running kernel.
    A value of -1 means we did not check for features yet.  A value
    of 0 means there are no supported features.  */
 static int supported_ptrace_options = -1;

+/* The file containing the current setting of yama ptrace_scope.  */
+static const char ptrace_scope_file[] = "/proc/sys/kernel/yama/ptrace_scope";
+
+/* Return non-zero if yama ptrace_scope is on.  */
+
+static int
+linux_yama_ptrace_scope_is_on (void)
+{
+  FILE *f;
+  char buffer[100];
+  struct cleanup *cleanup;
+  int is_on = 0;
+
+  f = gdb_fopen_cloexec (ptrace_scope_file, "r");
+  if (f == NULL)
+    return 0;
+  cleanup = make_cleanup_fclose (f);
+
+  if (fgets (buffer, sizeof (buffer), f) != NULL)
+    {
+      char *p;
+      long l;
+
+      l = strtoul (buffer, &p, 10);
+      if (*buffer != '\0' && (*p == '\0' || isspace (*p)))
+	is_on = l != 0;
+    }
+
+  do_cleanups (cleanup);
+  return is_on;
+}
+
 /* Find all possible reasons we could fail to attach PID and append
    these as strings to the already initialized BUFFER.  '\0'
-   termination of BUFFER must be done by the caller.  */
+   termination of BUFFER must be done by the caller.
+   ERR is the errno value of the failure.  */

-void
-linux_ptrace_attach_fail_reason (pid_t pid, struct buffer *buffer)
+static void
+linux_ptrace_attach_fail_reason (pid_t pid, struct buffer *buffer, int err)
 {
   pid_t tracerpid;

   tracerpid = linux_proc_get_tracerpid_nowarn (pid);
   if (tracerpid > 0)
-    buffer_xml_printf (buffer, _("process %d is already traced "
+    buffer_xml_printf (buffer, _(", process %d is already traced "
 				 "by process %d"),
 		       (int) pid, (int) tracerpid);

   if (linux_proc_pid_is_zombie_nowarn (pid))
-    buffer_xml_printf (buffer, _("process %d is a zombie "
+    buffer_xml_printf (buffer, _(", process %d is a zombie "
 				 "- the process has already terminated"),
 		       (int) pid);
+  if (err == EPERM && linux_yama_ptrace_scope_is_on ())
+    {
+      buffer_xml_printf (buffer, _("\n\
+It looks like yama ptrace_scope is enabled.\n\
+See %s.\n\
+You can lift the restriction with:\n\
+sudo sysctl -w kernel.yama.ptrace_scope=0"),
+			 ptrace_scope_file);
+    }
 }

 /* See linux-ptrace.h.  */
@@ -57,22 +101,15 @@ linux_ptrace_attach_fail_reason_string (ptid_t ptid, int err)
 {
   static char *reason_string;
   struct buffer buffer;
-  char *warnings;
   long lwpid = ptid_get_lwp (ptid);

   xfree (reason_string);

   buffer_init (&buffer);
-  linux_ptrace_attach_fail_reason (lwpid, &buffer);
+  buffer_xml_printf (&buffer, "%s (%d)", safe_strerror (err), err);
+  linux_ptrace_attach_fail_reason (lwpid, &buffer, err);
   buffer_grow_str0 (&buffer, "");
-  warnings = buffer_finish (&buffer);
-  if (warnings[0] != '\0')
-    reason_string = xstrprintf ("%s (%d), %s",
-				safe_strerror (err), err, warnings);
-  else
-    reason_string = xstrprintf ("%s (%d)",
-				safe_strerror (err), err);
-  xfree (warnings);
+  reason_string = buffer_finish (&buffer);
   return reason_string;
 }

diff --git a/gdb/nat/linux-ptrace.h b/gdb/nat/linux-ptrace.h
index 1be38fe..3b5dbd6 100644
--- a/gdb/nat/linux-ptrace.h
+++ b/gdb/nat/linux-ptrace.h
@@ -154,8 +154,6 @@ struct buffer;
 # define TRAP_HWBKPT 4
 #endif

-extern void linux_ptrace_attach_fail_reason (pid_t pid, struct buffer *buffer);
-
 /* Find all possible reasons we could have failed to attach to PTID
    and return them as a string.  ERR is the error PTRACE_ATTACH failed
    with (an errno).  The result is stored in a static buffer.  This


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