Describe issues with cancellation points in signal handlers.

Message ID 953b30ef-6546-ab16-06cb-e9d8d179dce2@redhat.com
State Not applicable
Headers

Commit Message

Carlos O'Donell Oct. 4, 2019, 9:12 p.m. UTC
  In a recent conversation with Mathieu Desnoyers I was reminded
that we haven't written up anything about how deferred cancellation
and asynchronous signal handlers interact. Mathieu ran into some
of this behaviour and I promised to improve the documentation in
this area to point out the potential pitfall.

Thoughts?

8< --- 8< --- 8<
In pthread_setcancelstate.3, pthreads.7, and signal-safety.7 we
describe that if you have an asynchronous signal nesting over a
deferred cancellation region that any cancellation point in the
signal handler may trigger a cancellation that will behave
as-if it was an asynhcronous cancellation. This asynchronous
cancellation may have unexpected effects on the consistency of
the application. Therefore care should be taken with asynchronous
signals and deferred cancellation.
---
 man3/pthread_setcancelstate.3 | 5 ++++-
 man7/pthreads.7               | 9 +++++++++
 man7/signal-safety.7          | 5 +++++
 3 files changed, 18 insertions(+), 1 deletion(-)
  

Comments

Michael Kerrisk \(man-pages\) Oct. 5, 2019, 11:48 a.m. UTC | #1
Hello Carlos,

On 10/5/19 12:12 AM, Carlos O'Donell wrote:
> In a recent conversation with Mathieu Desnoyers I was reminded
> that we haven't written up anything about how deferred cancellation
> and asynchronous signal handlers interact. Mathieu ran into some
> of this behaviour and I promised to improve the documentation in
> this area to point out the potential pitfall.
> 
> Thoughts?

I've applied this. If some review comments come it, I can
tweak the text.

Thanks!

Michael

> 8< --- 8< --- 8<
> In pthread_setcancelstate.3, pthreads.7, and signal-safety.7 we
> describe that if you have an asynchronous signal nesting over a
> deferred cancellation region that any cancellation point in the
> signal handler may trigger a cancellation that will behave
> as-if it was an asynhcronous cancellation. This asynchronous
> cancellation may have unexpected effects on the consistency of
> the application. Therefore care should be taken with asynchronous
> signals and deferred cancellation.
> ---
>   man3/pthread_setcancelstate.3 | 5 ++++-
>   man7/pthreads.7               | 9 +++++++++
>   man7/signal-safety.7          | 5 +++++
>   3 files changed, 18 insertions(+), 1 deletion(-)
> 
> diff --git a/man3/pthread_setcancelstate.3 b/man3/pthread_setcancelstate.3
> index 0237d572b..1a6fe45bf 100644
> --- a/man3/pthread_setcancelstate.3
> +++ b/man3/pthread_setcancelstate.3
> @@ -78,7 +78,10 @@ A cancellation request is deferred until the thread next calls
>   a function that is a cancellation point (see
>   .BR pthreads (7)).
>   This is the default cancelability type in all new threads,
> -including the initial thread.
> +including the initial thread. Even with deferred cancellation a
> +cancellation point in an asynchronous signal handler may still
> +be acted upon and the effect is as-if it was an asynchronous
> +cancellation.
>   .TP
>   .B PTHREAD_CANCEL_ASYNCHRONOUS
>   The thread can be canceled at any time.
> diff --git a/man7/pthreads.7 b/man7/pthreads.7
> index 06417d503..b39236c39 100644
> --- a/man7/pthreads.7
> +++ b/man7/pthreads.7
> @@ -564,6 +564,15 @@ not specified in the standard as cancellation points.
>   In particular, an implementation is likely to mark
>   any nonstandard function that may block as a cancellation point.
>   (This includes most functions that can touch files.)
> +.in
> +.PP
> +It should be noted that even if an application is not using
> +asynchronous cancellation, that calling a function from the above list
> +from an asynchronous signal handler may cause the equivalent of
> +asynchronous cancellation. The underlying user code may not expect
> +asynchronous cancellation and the state of the user data may become
> +inconsistent. Therefore signals should be used with caution when
> +entering a region of deferred cancellation.
>   .\" So, scanning "cancellation point" comments in the glibc 2.8 header
>   .\" files, it looks as though at least the following nonstandard
>   .\" functions are cancellation points:
> diff --git a/man7/signal-safety.7 b/man7/signal-safety.7
> index 3879a5aef..051702b76 100644
> --- a/man7/signal-safety.7
> +++ b/man7/signal-safety.7
> @@ -314,6 +314,11 @@ is likely to remove
>   .BR fork (2)
>   from the list of async-signal-safe functions.
>   .\"
> +.IP * 3
> +Asynchronous signal handlers that call functions which are cancellation
> +points and nest over regions of deferred cancellation may trigger
> +cancellation whose behavior is as-if asynchronous cancellation had
> +occurred and may cause application state to become inconsistent.
>   .SS Deviations in the GNU C library
>   The following known deviations from the standard occur in
>   the GNU C library:
>
  
Carlos O'Donell Oct. 7, 2019, 2:17 a.m. UTC | #2
On 10/5/19 7:48 AM, Michael Kerrisk (man-pages) wrote:
> Hello Carlos,
> 
> On 10/5/19 12:12 AM, Carlos O'Donell wrote:
>> In a recent conversation with Mathieu Desnoyers I was reminded
>> that we haven't written up anything about how deferred cancellation
>> and asynchronous signal handlers interact. Mathieu ran into some
>> of this behaviour and I promised to improve the documentation in
>> this area to point out the potential pitfall.
>>
>> Thoughts?
> 
> I've applied this. If some review comments come it, I can
> tweak the text.
> 
> Thanks!
Thank you! I tried hard to keep the "asynchronous signal" and
"deferred cancellation" terms all consistent. It's all a bit of
a mouthful, so I'd be happy if we could have come up with simpler
language, but it's hard to write it any simpler without loosing
the exactitude of what I'm trying to say. I'm happy to see future
edits that simplify the language. At the very least we now say
something about this corner case so people aren't caught off guard.
  

Patch

diff --git a/man3/pthread_setcancelstate.3 b/man3/pthread_setcancelstate.3
index 0237d572b..1a6fe45bf 100644
--- a/man3/pthread_setcancelstate.3
+++ b/man3/pthread_setcancelstate.3
@@ -78,7 +78,10 @@  A cancellation request is deferred until the thread next calls
 a function that is a cancellation point (see
 .BR pthreads (7)).
 This is the default cancelability type in all new threads,
-including the initial thread.
+including the initial thread. Even with deferred cancellation a
+cancellation point in an asynchronous signal handler may still
+be acted upon and the effect is as-if it was an asynchronous
+cancellation.
 .TP
 .B PTHREAD_CANCEL_ASYNCHRONOUS
 The thread can be canceled at any time.
diff --git a/man7/pthreads.7 b/man7/pthreads.7
index 06417d503..b39236c39 100644
--- a/man7/pthreads.7
+++ b/man7/pthreads.7
@@ -564,6 +564,15 @@  not specified in the standard as cancellation points.
 In particular, an implementation is likely to mark
 any nonstandard function that may block as a cancellation point.
 (This includes most functions that can touch files.)
+.in
+.PP
+It should be noted that even if an application is not using
+asynchronous cancellation, that calling a function from the above list
+from an asynchronous signal handler may cause the equivalent of
+asynchronous cancellation. The underlying user code may not expect
+asynchronous cancellation and the state of the user data may become
+inconsistent. Therefore signals should be used with caution when
+entering a region of deferred cancellation.
 .\" So, scanning "cancellation point" comments in the glibc 2.8 header
 .\" files, it looks as though at least the following nonstandard
 .\" functions are cancellation points:
diff --git a/man7/signal-safety.7 b/man7/signal-safety.7
index 3879a5aef..051702b76 100644
--- a/man7/signal-safety.7
+++ b/man7/signal-safety.7
@@ -314,6 +314,11 @@  is likely to remove
 .BR fork (2)
 from the list of async-signal-safe functions.
 .\"
+.IP * 3
+Asynchronous signal handlers that call functions which are cancellation
+points and nest over regions of deferred cancellation may trigger
+cancellation whose behavior is as-if asynchronous cancellation had
+occurred and may cause application state to become inconsistent.
 .SS Deviations in the GNU C library
 The following known deviations from the standard occur in
 the GNU C library: