public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Pedro Alves <palves@redhat.com>
To: Sergio Durigan Junior <sergiodj@redhat.com>,
	       GDB Patches <gdb-patches@sourceware.org>
Cc: dje@google.com
Subject: Re: [PATCH] PR gdb/16188: Verify PTRACE_TRACEME succeeded
Date: Fri, 17 Feb 2017 10:48:00 -0000	[thread overview]
Message-ID: <f38a33ad-6fe5-7ed9-6b7a-a3c53999dd5e@redhat.com> (raw)
In-Reply-To: <20170216201931.5843-1-sergiodj@redhat.com>

On 02/16/2017 08:19 PM, Sergio Durigan Junior wrote:

> I confess I have no idea how to make a testcase for this bug, but I've
> run the patch through BuildBot and no regressions were found
> whatsoever.  I could not actively test some targets (gdb/darwin-nat.c,
> gdb/procfs.c, gdb/gnu-nat.c), so I'd appreciate if others could look
> at the patch.

Off hand, all that comes up is to write a LD_PRELOAD wrapper around
ptrace that always fails, similar to testsuite/lib/read1.c.
But that'd only work for that specific call and only for ptrace targets.
And it'd probably conflict with the ptrace calls that we do early on
gdb startup to probe for level of ptrace support.  Likely not work the
trouble.

>  
> -static void
> -darwin_ptrace_me (void)
> +static bool
> +darwin_ptrace_me (int *trace_errno)
>  {
>    int res;
>    char c;
>  
> +  errno = 0;
>    /* Close write end point.  */
> -  close (ptrace_fds[1]);
> +  if (close (ptrace_fds[1]) < 0)
> +    goto fail;
>  
>    /* Wait until gdb is ready.  */
>    res = read (ptrace_fds[0], &c, 1);
>    if (res != 0)
> -    error (_("unable to read from pipe, read returned: %d"), res);
> -  close (ptrace_fds[0]);
> +    {
> +      int saved_errno = errno;
> +
> +      warning (_("unable to read from pipe, read returned: %d"), res);
> +      errno = saved_errno;
> +      goto fail;


Hmm, seeing this makes me wonder about the interface
of returning the errno.  It loses detail on context of what
exactly fails.

Throwing an error/exception and catching it from fork_inferior instead would
be the "obvious" choice, but we're in an async-signal-safe context (we're
in a fork child, before calling exec), and we already do things that we
shouldn't, and I wouldn't want to make it worse.

But, all we do when we "catch" the error is print something and _exit.
So I'm wondering whether a couple functions similar to "error"
and "perror_with_name" but that print the error and _exit themselves
wouldn't be a better interface.  I think it'd result in less boilerplate.
Something like these exported from fork-child.c:

extern void trace_start_error (const char *fmt, ...)
  ATTRIBUTE_NORETURN;
extern void trace_start_error_with_name (const char *string)
  ATTRIBUTE_NORETURN;

/* There was an error when trying to initiate the trace in
   the fork child.  Report the error to the user and bail out.  */

void
trace_start_error (const char *fmt, ...)
{
  va_list ap;

  va_start (ap, fmt);
  fprintf_unfiltered (gdb_stderr, "Could not trace the inferior "
		                  "process.\nError: ");
  vfprintf_unfiltered (gdb_stderr, fmt, ap);
  va_end (args);

  gdb_flush (gdb_stderr);
  _exit (0177);
}

/* Like "trace_start_error", but the error message is constructed
   by combining STRING with the system error message for errno.
   This function does not return.  */

void
trace_start_error_with_name (const char *string)
{
  fatal_trace_error ("%s", safe_strerror (trace_errno));
}


and then in darwin_ptrace_me you'd do:

   if (res != 0)
-    error (_("unable to read from pipe, read returned: %d"), res);
+     trace_start_error (_("unable to read from pipe, read returned: %d"), res);

> +    }
> +  if (close (ptrace_fds[0]) < 0)
> +    goto fail;
>  
>    /* Get rid of privileges.  */
> -  setegid (getgid ());
> +  if (setegid (getgid ()) < 0)
> +    goto fail;
>  
>    /* Set TRACEME.  */
> -  PTRACE (PT_TRACE_ME, 0, 0, 0);
> +  if (PTRACE (PT_TRACE_ME, 0, 0, 0) < 0)
> +    goto fail;
>  
>    /* Redirect signals to exception port.  */
> -  PTRACE (PT_SIGEXC, 0, 0, 0);
> +  if (PTRACE (PT_SIGEXC, 0, 0, 0) < 0)
> +    goto fail;
> +

And these gotos would be replaced with calls
to trace_start_error_with_name, etc.

Thanks,
Pedro Alves

  reply	other threads:[~2017-02-17 10:48 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-16 20:19 Sergio Durigan Junior
2017-02-17 10:48 ` Pedro Alves [this message]
2017-02-18  4:55   ` Sergio Durigan Junior
2017-02-18  5:09 ` Sergio Durigan Junior
2017-02-20 12:19   ` Pedro Alves
2017-02-20 12:51     ` Sergio Durigan Junior
2017-02-20 13:05       ` [PATCH] Fix thinko on last commit Sergio Durigan Junior
2017-02-20 13:08         ` Sergio Durigan Junior

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=f38a33ad-6fe5-7ed9-6b7a-a3c53999dd5e@redhat.com \
    --to=palves@redhat.com \
    --cc=dje@google.com \
    --cc=gdb-patches@sourceware.org \
    --cc=sergiodj@redhat.com \
    /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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).