Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Doug Evans <dje@google.com>
To: gdb-patches@sourceware.org
Subject: [PATCH 3/3] debugging with yama: check for yama ptrace_scope
Date: Mon, 28 Sep 2015 19:35:00 -0000	[thread overview]
Message-ID: <047d7b1121b7dbb3190520d3ca0f@google.com> (raw)

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


             reply	other threads:[~2015-09-28 19:35 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-28 19:35 Doug Evans [this message]
2015-09-29 11:20 ` Pedro Alves

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=047d7b1121b7dbb3190520d3ca0f@google.com \
    --to=dje@google.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox