+ DW_LNS_set_address_from_logical, DW_LNS_set_subprogram,
+ DW_LNS_inlined_call, DW_LNS_pop_context.
+ (dwarf_line_number_content_type): New enum.
+--- README.google 2015-09-05 20:17:18.000000000 -0700
++++ README.google 2015-09-05 23:58:27.000000000 -0700
++
++2015-09-05 Doug Evans <dje@google.com>
++
++ Ref# 20215162
++ * common/common-exceptions.c (exceptions_state_mc_init): Initialize
++ suberror.
++ (throw_it): New arg suberror. All callers updated.
++ (throw_error_with_suberror): New function.
++ * common/common-exceptions.h (enum errors): New enum value
++ SYSCALL_FAILED_ERROR.
++ (struct gdb_exception): New member suberror.
++ (throw_error_with_suberror): Declare.
++ * inf-ptrace.c (inf_ptrace_attach): Call throw_perror_with_name
++ passing SYSCALL_FAILED_ERROR.
++ * linux-nat.c (linux_nat_attach): Rewrite attach fail error processing.
++ * nat/linux-ptrace.c (linux_ptrace_attach_fail_reason): Make static.
++ Prepend ", " to messages.
++ (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.
++ * utils.c (perror_string): New arg errno_value. All callers updated.
++ (throw_perror_with_name): Call throw_error_with_suberror.
#include "common-defs.h"
#include "common-exceptions.h"
-const struct gdb_exception exception_none = { 0, GDB_NO_ERROR, NULL };
+const struct gdb_exception exception_none = { 0, GDB_NO_ERROR, 0, NULL };
#ifndef __cplusplus
/* The number of currently allocated entries in exception_messages. */
static int exception_messages_size;
-static void ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (3, 0)
-throw_it (enum return_reason reason, enum errors error, const char *fmt,
- va_list ap)
+static void ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (4, 0)
+throw_it (enum return_reason reason, enum errors error, int suberror,
+ const char *fmt, va_list ap)
{
struct gdb_exception e;
char *new_message;
/* Create the exception. */
e.reason = reason;
e.error = error;
+ e.suberror = suberror;
e.message = new_message;
/* Throw the exception. */
void
throw_verror (enum errors error, const char *fmt, va_list ap)
{
- throw_it (RETURN_ERROR, error, fmt, ap);
+ throw_it (RETURN_ERROR, error, 0, fmt, ap);
}
void
throw_vquit (const char *fmt, va_list ap)
{
- throw_it (RETURN_QUIT, GDB_NO_ERROR, fmt, ap);
+ throw_it (RETURN_QUIT, GDB_NO_ERROR, 0, fmt, ap);
}
void
va_end (args);
}
+void
+throw_error_with_suberror (enum errors error, int suberror,
+ const char *fmt, ...)
+{
+ va_list args;
+
+ va_start (args, fmt);
+ throw_it (RETURN_ERROR, error, suberror, fmt, args);
+ va_end (args);
+}
+
void
throw_quit (const char *fmt, ...)
{
"_ERROR" is appended to the name. */
MAX_COMPLETIONS_REACHED_ERROR,
+ /* A system call failed.
+ The "errno" value is in gdb_exception.suberror. */
+ SYSCALL_FAILED_ERROR,
+
/* Add more errors here. */
NR_ERRORS
};
{
enum return_reason reason;
enum errors error;
+ int suberror;
const char *message;
};
ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (1, 0);
extern void throw_error (enum errors error, const char *fmt, ...)
ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 3);
+extern void throw_error_with_suberror (enum errors error, int suberror,
+ const char *fmt, ...)
+ ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (3, 4);
extern void throw_quit (const char *fmt, ...)
ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (1, 2);
errno = 0;
ptrace (PT_ATTACH, pid, (PTRACE_TYPE_ARG3)0, 0);
if (errno != 0)
- perror_with_name (("ptrace"));
+ {
+ /* GOOGLE LOCAL: We want the linux caller to see errno. */
+ throw_perror_with_name (SYSCALL_FAILED_ERROR, _("ptrace"));
+ }
#else
error (_("This system does not support attaching to a process"));
#endif
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
these as strings to the already initialized BUFFER. '\0'
termination of BUFFER must be done by the caller. */
-void
+static void
linux_ptrace_attach_fail_reason (pid_t pid, struct buffer *buffer)
{
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);
}
{
static char *reason_string;
struct buffer buffer;
- char *warnings;
long lwpid = ptid_get_lwp (ptid);
xfree (reason_string);
buffer_init (&buffer);
+ buffer_xml_printf (&buffer, "%s (%d)", strerror (err), err);
linux_ptrace_attach_fail_reason (lwpid, &buffer);
+ /* GOOGLE LOCAL, ref: 20215162 */
+ if (err == EPERM)
+ {
+ buffer_xml_printf (&buffer, _("\n\
+If your uid matches the uid of the target process, check the setting of\n\
+/proc/sys/kernel/yama/ptrace_scope. See /etc/sysctl.d/10-ptrace.conf.\n\
+If ptrace scope is enabled, you can lift the restriction with:\n\
+sudo sysctl -w kernel.yama.ptrace_scope=0"));
+ }
+ /* END GOOGLE LOCAL */
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;
}
# 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
}
/* Return a newly allocated string, containing the PREFIX followed
- by the system error message for errno (separated by a colon).
+ by the system error message for ERRNO_VALUE (separated by a colon).
The result must be deallocated after use. */
static char *
-perror_string (const char *prefix)
+perror_string (const char *prefix, int errno_value)
{
char *err;
char *combined;
- err = safe_strerror (errno);
+ err = safe_strerror (errno_value);
combined = (char *) xmalloc (strlen (err) + strlen (prefix) + 3);
strcpy (combined, prefix);
strcat (combined, ": ");
return combined;
}
-/* Print the system error message for errno, and also mention STRING
- as the file name for which the error was encountered. Use ERRCODE
- for the thrown exception. Then return to command level. */
+/* Throw an error with the system error message for errno, and also mention
+ STRING as the file name or system call for which the error was encountered.
+ Use ERRCODE for the thrown exception. */
void
throw_perror_with_name (enum errors errcode, const char *string)
{
char *combined;
+ /* Fetch ERRNO early, you never know which function might modify it. */
+ int saved_errno = errno;
- combined = perror_string (string);
+ combined = perror_string (string, saved_errno);
make_cleanup (xfree, combined);
/* I understand setting these is a matter of taste. Still, some people
bfd_set_error (bfd_error_no_error);
errno = 0;
- throw_error (errcode, _("%s."), combined);
+ throw_error_with_suberror (errcode,
+ errcode == SYSCALL_FAILED_ERROR ? saved_errno : 0,
+ _("%s."), combined);
}
/* See throw_perror_with_name, ERRCODE defaults here to GENERIC_ERROR. */
{
char *combined;
- combined = perror_string (string);
+ combined = perror_string (string, errno);
warning (_("%s"), combined);
xfree (combined);
}