@@ -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
@@ -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
@@ -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;
}
@@ -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