Subject: [RFC PATCH] New SA_NOPRNOTIF sigaction flag


Sometimes when a task is being ptraced (e.g. by a debugger), one would
like to handle a certain signal (e.g. SIGSEGV) within the task without
having to notify the ptracing task.

An example of this is if one would like to detect the rate at which pages
are being modified, and therefore mprotect() the pages. The SIGSEGV
handler just keeps track of how many writes are happening on each of the
mprotect()ed pages, but you don't want to bother the debugger with these
SIGSEGVs.

I'm proposing the addition of a new SA_NOPRNOTIF flag to struct sigaction
{ sa_flags }, which makes the kernel skip notifying the ptracing parent if
the flag is set for a sighandler for a particular signal.

This trivial patch achieves just that.

Comments?

Thanks

- Bhavesh

ps: wonder why POSIX, SUSV3, SVR4, etc. didn't have this option. Seems
like a handy flag to have...


Bhavesh P. Davda | Distinguished Member of Technical Staff | Avaya |
1300 West 120th Avenue | B3-B03 | Westminster, CO 80234 | U.S.A. |
Voice/Fax: 303.538.4438 | [email protected]


Attachments:
noprnotif.patch (10.56 kB)

2005-09-27 13:06:42

by Daniel Jacobowitz

[permalink] [raw]
Subject: Re: [RFC PATCH] New SA_NOPRNOTIF sigaction flag

On Mon, Sep 26, 2005 at 11:39:40AM -0600, Bhavesh P. Davda wrote:
>
> Sometimes when a task is being ptraced (e.g. by a debugger), one would
> like to handle a certain signal (e.g. SIGSEGV) within the task without
> having to notify the ptracing task.
>
> An example of this is if one would like to detect the rate at which pages
> are being modified, and therefore mprotect() the pages. The SIGSEGV
> handler just keeps track of how many writes are happening on each of the
> mprotect()ed pages, but you don't want to bother the debugger with these
> SIGSEGVs.
>
> I'm proposing the addition of a new SA_NOPRNOTIF flag to struct sigaction
> { sa_flags }, which makes the kernel skip notifying the ptracing parent if
> the flag is set for a sighandler for a particular signal.
>
> This trivial patch achieves just that.
>
> Comments?

No way! It needs to work the other way: allow the debugger to
short-circuit a signal for performance reasons if it wants to. Ptrace
is supposed to report all signals and debuggers expect it to do so.
It'd be pretty confusing if, say, you were trying to debug the SIGSEGV
handler in an application which did this.

--
Daniel Jacobowitz
CodeSourcery, LLC

Subject: RE: [RFC PATCH] New SA_NOPRNOTIF sigaction flag

> -----Original Message-----
> From: Daniel Jacobowitz [mailto:[email protected]]
> Sent: Tuesday, September 27, 2005 7:07 AM
> To: Davda, Bhavesh P (Bhavesh)
> Cc: [email protected]
> Subject: Re: [RFC PATCH] New SA_NOPRNOTIF sigaction flag
>
> On Mon, Sep 26, 2005 at 11:39:40AM -0600, Bhavesh P. Davda wrote:
> >
> > Sometimes when a task is being ptraced (e.g. by a
> debugger), one would
> > like to handle a certain signal (e.g. SIGSEGV) within the
> task without
> > having to notify the ptracing task.
> >
> > An example of this is if one would like to detect the rate
> at which pages
> > are being modified, and therefore mprotect() the pages. The SIGSEGV
> > handler just keeps track of how many writes are happening
> on each of the
> > mprotect()ed pages, but you don't want to bother the
> debugger with these
> > SIGSEGVs.
> >
> > I'm proposing the addition of a new SA_NOPRNOTIF flag to
> struct sigaction
> > { sa_flags }, which makes the kernel skip notifying the
> ptracing parent if
> > the flag is set for a sighandler for a particular signal.
> >
> > This trivial patch achieves just that.
> >
> > Comments?
>
> No way! It needs to work the other way: allow the debugger to
> short-circuit a signal for performance reasons if it wants to. Ptrace
> is supposed to report all signals and debuggers expect it to do so.
> It'd be pretty confusing if, say, you were trying to debug the SIGSEGV
> handler in an application which did this.
>
> --
> Daniel Jacobowitz
> CodeSourcery, LLC
>


Then propose an alternative way where a real-time (SCHED_FIFO/SCHED_RR)
CPU bound application getting lots of SEGVs for normal operation doesn't
cause a priority inversion with the debugger getting SIGCHLDs for every
SEGV and deciding to ignore it?

This way avoids the unnecessary context switch to the debugger, and is
intended for use only by someone who knows darn sure that s/he will
handle the signal safely, and don't mind if the debugger is not notified
(in fact would love it if that's the case) on specific signals.

IMHO this is a perfectly safe capability...

- Bhavesh

Bhavesh P. Davda | Distinguished Member of Technical Staff | Avaya |
1300 West 120th Avenue | B3-B03 | Westminster, CO 80234 | U.S.A. |
Voice/Fax: 303.538.4438 | [email protected]

2005-09-27 15:55:27

by Daniel Jacobowitz

[permalink] [raw]
Subject: Re: [RFC PATCH] New SA_NOPRNOTIF sigaction flag

On Tue, Sep 27, 2005 at 08:45:07AM -0600, Davda, Bhavesh P (Bhavesh) wrote:
> > No way! It needs to work the other way: allow the debugger to
> > short-circuit a signal for performance reasons if it wants to. Ptrace
> > is supposed to report all signals and debuggers expect it to do so.
> > It'd be pretty confusing if, say, you were trying to debug the SIGSEGV
> > handler in an application which did this.

> Then propose an alternative way where a real-time (SCHED_FIFO/SCHED_RR)
> CPU bound application getting lots of SEGVs for normal operation doesn't
> cause a priority inversion with the debugger getting SIGCHLDs for every
> SEGV and deciding to ignore it?

Read my reply above again, please. I did. It needs to be under
control of the tracer.

Also, this is far from the only problem you're going to have if you run
your debugger with lower priority than your debuggee.

> This way avoids the unnecessary context switch to the debugger, and is
> intended for use only by someone who knows darn sure that s/he will
> handle the signal safely, and don't mind if the debugger is not notified
> (in fact would love it if that's the case) on specific signals.
>
> IMHO this is a perfectly safe capability...

No. Ptrace is considered a security barrier; the tracee should not be
able to control what the tracer sees.

--
Daniel Jacobowitz
CodeSourcery, LLC

Subject: RE: [RFC PATCH] New SA_NOPRNOTIF sigaction flag

> Also, this is far from the only problem you're going to have
> if you run
> your debugger with lower priority than your debuggee.

About the priority inversion and running the debugger at higher priority
then the debuggee, that's a moot point. You're still doing too many
pointless context switches to the debugger only to do nothing and switch
back to the debuggee.


> >
> > IMHO this is a perfectly safe capability...
>
> No. Ptrace is considered a security barrier; the tracee should not be
> able to control what the tracer sees.
>

Since when did ptrace become a security barrier? If security is the only
concern, then we can always add a capability check to only allow root to
set SA_NOPRNOTIF on sigaction() for a particular signal.

Besides, putting this responsibility (ignore SIGCHLDs for signal X from
Task Y) in the debugger requires the debugger to have information about
the debuggee, like Task Y is special for handling signal X, and I'm
going to ptrace() ignore SIGCHLD's from Task Y.

See where I'm going with this?

That's why I specifically put the responsibility on the debuggee to say:
I know what I'm doing and I don't want the debugger to be notified about
this specific signal.


- Bhavesh


Bhavesh P. Davda | Distinguished Member of Technical Staff | Avaya |
1300 West 120th Avenue | B3-B03 | Westminster, CO 80234 | U.S.A. |
Voice/Fax: 303.538.4438 | [email protected]

2005-09-27 20:39:21

by Daniel Jacobowitz

[permalink] [raw]
Subject: Re: [RFC PATCH] New SA_NOPRNOTIF sigaction flag

On Tue, Sep 27, 2005 at 10:24:23AM -0600, Davda, Bhavesh P (Bhavesh) wrote:
> About the priority inversion and running the debugger at higher priority
> then the debuggee, that's a moot point. You're still doing too many
> pointless context switches to the debugger only to do nothing and switch
> back to the debuggee.

Depending on your debugger, they may not be pointless.

> Besides, putting this responsibility (ignore SIGCHLDs for signal X from
> Task Y) in the debugger requires the debugger to have information about
> the debuggee, like Task Y is special for handling signal X, and I'm
> going to ptrace() ignore SIGCHLD's from Task Y.
>
> See where I'm going with this?

Hint: your debugger already needs to know this. GDB already does. It
has a list of signals not to bother stopping or displaying to the user.
SIGCHLD is on it by default. If not, you'd see the debugger prompt
after each one of these context switches.

--
Daniel Jacobowitz
CodeSourcery, LLC

Subject: RE: [RFC PATCH] New SA_NOPRNOTIF sigaction flag

> -----Original Message-----
> From: Daniel Jacobowitz [mailto:[email protected]]
> Sent: Tuesday, September 27, 2005 2:39 PM
> To: Davda, Bhavesh P (Bhavesh)
> Cc: [email protected]
> Subject: Re: [RFC PATCH] New SA_NOPRNOTIF sigaction flag
>
> On Tue, Sep 27, 2005 at 10:24:23AM -0600, Davda, Bhavesh P
> (Bhavesh) wrote:
> > About the priority inversion and running the debugger at
> higher priority
> > then the debuggee, that's a moot point. You're still doing too many
> > pointless context switches to the debugger only to do
> nothing and switch
> > back to the debuggee.
>
> Depending on your debugger, they may not be pointless.


Sorry for reiterating this, but in certain cases, yes, the context
switch to the debugger just to have it ignore the SIGCHLD for that
signal is pointless.


> > Besides, putting this responsibility (ignore SIGCHLDs for
> signal X from
> > Task Y) in the debugger requires the debugger to have
> information about
> > the debuggee, like Task Y is special for handling signal X, and I'm
> > going to ptrace() ignore SIGCHLD's from Task Y.
> >
> > See where I'm going with this?
>
> Hint: your debugger already needs to know this. GDB already does. It
> has a list of signals not to bother stopping or displaying to
> the user.
> SIGCHLD is on it by default. If not, you'd see the debugger prompt
> after each one of these context switches.
>

That is under user control of the person using the debugger. What I was
talking about is control in the debuggee process/developer to say that I
would like to spare the unnecessary overhead of notifying the debugger
that a specific signal is being delivered to me.

By the time GDB decides to ignore the SIGCHLD, you've already incurred
the overhead of notifying GDB and context switching into it. Then GDB,
in userspace, has to waitpid(), look at WIFSTOPPED(status),
WSTOPSIG(status) and then decide to do nothing and ptrace(PTRACE_CONT)
if the signal was one of the ignored signals. Lots of unnecessary
overhead in this case.

It is obvious to me that you and I are going to continue disagreeing
about this and arguing endlessly about this capability, so I would like
to in all modesty solicit other folks opinion about this capability
too...

Thanks

- Bhavesh

Bhavesh P. Davda | Distinguished Member of Technical Staff | Avaya |
1300 West 120th Avenue | B3-B03 | Westminster, CO 80234 | U.S.A. |
Voice/Fax: 303.538.4438 | [email protected]

2005-09-27 23:27:07

by Valdis Klētnieks

[permalink] [raw]
Subject: Re: [RFC PATCH] New SA_NOPRNOTIF sigaction flag

On Tue, 27 Sep 2005 08:45:07 MDT, "Davda, Bhavesh P (Bhavesh)" said:

> Then propose an alternative way where a real-time (SCHED_FIFO/SCHED_RR)
> CPU bound application getting lots of SEGVs for normal operation doesn't

If it's RT, *and* CPU-bound, *and* tossing enough SEGV's to matter, it's a
train wreck waiting to happen. If something attaches to that locomotive
with a ptrace(), making sure that a SEGV doesn't cause a priority inversion
merely delays the wreck until the *next* thing the debugger is interested in.
What's *next*, prohibit the overhead of whatever "stop at" or "trace value"
command the debugger has? By the time you clean all of that stuff up, you're
basically left with "why bother allowing a ptrace()?".


Attachments:
(No filename) (226.00 B)

2005-09-28 14:10:11

by Daniel Jacobowitz

[permalink] [raw]
Subject: Re: [RFC PATCH] New SA_NOPRNOTIF sigaction flag

On Tue, Sep 27, 2005 at 03:55:26PM -0600, Davda, Bhavesh P (Bhavesh) wrote:
> > On Tue, Sep 27, 2005 at 10:24:23AM -0600, Davda, Bhavesh P
> > (Bhavesh) wrote:
> > > About the priority inversion and running the debugger at
> > higher priority
> > > then the debuggee, that's a moot point. You're still doing too many
> > > pointless context switches to the debugger only to do
> > nothing and switch
> > > back to the debuggee.
> >
> > Depending on your debugger, they may not be pointless.
>
>
> Sorry for reiterating this, but in certain cases, yes, the context
> switch to the debugger just to have it ignore the SIGCHLD for that
> signal is pointless.

Note, this is a property of the debugging session, not a property of
the debuggee. The debuggee can not say "no possible debugger will ever
be interested in this signal"; it doesn't make sense.

> > > Besides, putting this responsibility (ignore SIGCHLDs for
> > signal X from
> > > Task Y) in the debugger requires the debugger to have
> > information about
> > > the debuggee, like Task Y is special for handling signal X, and I'm
> > > going to ptrace() ignore SIGCHLD's from Task Y.
> > >
> > > See where I'm going with this?
> >
> > Hint: your debugger already needs to know this. GDB already does. It
> > has a list of signals not to bother stopping or displaying to
> > the user.
> > SIGCHLD is on it by default. If not, you'd see the debugger prompt
> > after each one of these context switches.
> >
>
> That is under user control of the person using the debugger. What I was
> talking about is control in the debuggee process/developer to say that I
> would like to spare the unnecessary overhead of notifying the debugger
> that a specific signal is being delivered to me.
>
> By the time GDB decides to ignore the SIGCHLD, you've already incurred
> the overhead of notifying GDB and context switching into it. Then GDB,
> in userspace, has to waitpid(), look at WIFSTOPPED(status),
> WSTOPSIG(status) and then decide to do nothing and ptrace(PTRACE_CONT)
> if the signal was one of the ignored signals. Lots of unnecessary
> overhead in this case.

Yes, I entirely understand what you're saying. I feel like you're not
reading my responses. GDB _already has a list of signals it does not
care about_. If ptrace permitted, it could tell the kernel not to
context switch to deliver those signals. In advance! That's a
debugger-driven solution to your problem.

I'm not arguing out of theory here. I've implemented this mechanism
before in other contexts, for instance to prevent the remote protocol
overhead for ignored signals when using gdb with gdbserver.

--
Daniel Jacobowitz
CodeSourcery, LLC

Subject: RE: [RFC PATCH] New SA_NOPRNOTIF sigaction flag

> Yes, I entirely understand what you're saying. I feel like you're not
> reading my responses. GDB _already has a list of signals it does not
> care about_. If ptrace permitted, it could tell the kernel not to
> context switch to deliver those signals. In advance! That's a
> debugger-driven solution to your problem.
>
> I'm not arguing out of theory here. I've implemented this mechanism
> before in other contexts, for instance to prevent the remote protocol
> overhead for ignored signals when using gdb with gdbserver.
>


Okay, I'll come up with an alternative patch that enhances the ptrace
interface so the debugger can guide the kernel to NOT context switch and
bother it about signal x from task y.

Would you be amenable to such a patch?

Thanks

- Bhavesh

2005-09-28 18:33:24

by Daniel Jacobowitz

[permalink] [raw]
Subject: Re: [RFC PATCH] New SA_NOPRNOTIF sigaction flag

On Wed, Sep 28, 2005 at 12:06:21PM -0600, Davda, Bhavesh P (Bhavesh) wrote:
> > Yes, I entirely understand what you're saying. I feel like you're not
> > reading my responses. GDB _already has a list of signals it does not
> > care about_. If ptrace permitted, it could tell the kernel not to
> > context switch to deliver those signals. In advance! That's a
> > debugger-driven solution to your problem.
> >
> > I'm not arguing out of theory here. I've implemented this mechanism
> > before in other contexts, for instance to prevent the remote protocol
> > overhead for ignored signals when using gdb with gdbserver.
> >
>
>
> Okay, I'll come up with an alternative patch that enhances the ptrace
> interface so the debugger can guide the kernel to NOT context switch and
> bother it about signal x from task y.
>
> Would you be amenable to such a patch?

Yes, definitely. I just hadn't found a chance to think about what the
interface should look like.

[For the record, I'm pretty sure that the Solaris procfs debug
interface offers a similar feature.]

--
Daniel Jacobowitz
CodeSourcery, LLC

Subject: RE: [RFC PATCH] New SA_NOPRNOTIF sigaction flag

> > Okay, I'll come up with an alternative patch that enhances
> the ptrace
> > interface so the debugger can guide the kernel to NOT
> context switch and
> > bother it about signal x from task y.
> >
> > Would you be amenable to such a patch?
>
> Yes, definitely. I just hadn't found a chance to think about what the
> interface should look like.
>
> [For the record, I'm pretty sure that the Solaris procfs debug
> interface offers a similar feature.]
>
> --
> Daniel Jacobowitz
> CodeSourcery, LLC
>


How about 2 new PTRACE requests: PTRACE_SET_SIGIGN_MASK,
PTRACE_GET_SIGIGN_MASK

Both taking a "sigset_t *mask" as a parameter? The mask would be filled
by the debugger as usual using sigemptyset(), sigfillset(), sigaddset(),
etc.

Of course, the implementation would do error checking for legal values
of signals to mask, etc.

And this might require augmenting task_struct {} to store this mask,
kind of like last_siginfo which is already used by the
PTRACE_SETSIGINFO/PTRACE_GETSIGINFO ptrace requests.

- Bhavesh


Bhavesh P. Davda | Distinguished Member of Technical Staff | Avaya |
1300 West 120th Avenue | B3-B03 | Westminster, CO 80234 | U.S.A. |
Voice/Fax: 303.538.4438 | [email protected]

2005-10-03 00:27:18

by Daniel Jacobowitz

[permalink] [raw]
Subject: Re: [RFC PATCH] New SA_NOPRNOTIF sigaction flag

On Wed, Sep 28, 2005 at 01:11:22PM -0600, Davda, Bhavesh P (Bhavesh) wrote:
> How about 2 new PTRACE requests: PTRACE_SET_SIGIGN_MASK,
> PTRACE_GET_SIGIGN_MASK
>
> Both taking a "sigset_t *mask" as a parameter? The mask would be filled
> by the debugger as usual using sigemptyset(), sigfillset(), sigaddset(),
> etc.
>
> Of course, the implementation would do error checking for legal values
> of signals to mask, etc.
>
> And this might require augmenting task_struct {} to store this mask,
> kind of like last_siginfo which is already used by the
> PTRACE_SETSIGINFO/PTRACE_GETSIGINFO ptrace requests.

Hmm, the only problem with this is that it requires consensus on the
format of kernel sigsets. Think about the 32-vs-64-bit compatibility
issues.

It should be cleared on PTRACE_DETACH, of course. Do we even need the
GET functionality? If not, is PTRACE_SET_IGNORE_SIGNAL taking a single
signal number sufficient?

--
Daniel Jacobowitz
CodeSourcery, LLC

Subject: RE: [RFC PATCH] New SA_NOPRNOTIF sigaction flag

> Hmm, the only problem with this is that it requires consensus on the
> format of kernel sigsets. Think about the 32-vs-64-bit compatibility
> issues.
>
> It should be cleared on PTRACE_DETACH, of course. Do we even need the
> GET functionality? If not, is PTRACE_SET_IGNORE_SIGNAL
> taking a single
> signal number sufficient?

Thanks for reminding me about handling PTRACE_DETACH!

Yeah, we could go with PTRACE_SET_IGNORE_SIGNAL (signum), but we'll
still need a sigset_t like structure in struct task_struct {}. I figured
the PTRACE_SET_SIGIGN_MASK interface would be more flexible and
efficient if someone wanted to have the debugger ignore a whole bunch of
signals at once for a debuggee child.

But I agree, the GET interface is perhaps not required.

Okay, I'll whip out a preliminary patch, and you can all rip it apart if
you find issues with it. Stay tuned...

Thanks for your comments, Daniel!

- Bhavesh



Bhavesh P. Davda | Distinguished Member of Technical Staff | Avaya |
1300 West 120th Avenue | B3-B03 | Westminster, CO 80234 | U.S.A. |
Voice/Fax: 303.538.4438 | [email protected]

2005-10-03 16:12:44

by Daniel Jacobowitz

[permalink] [raw]
Subject: Re: [RFC PATCH] New SA_NOPRNOTIF sigaction flag

On Mon, Oct 03, 2005 at 09:21:00AM -0600, Davda, Bhavesh P (Bhavesh) wrote:
> Yeah, we could go with PTRACE_SET_IGNORE_SIGNAL (signum), but we'll
> still need a sigset_t like structure in struct task_struct {}.

Right - but a non-exported structure can't present any ABI problems :-)

--
Daniel Jacobowitz
CodeSourcery, LLC