Extend tst-{atexit,at_quick_exit,cxa_atexit,onexit} to verify minimum number of supported handlers

Message ID CALoOobMeBycaWz2E7_YYQFeg38936j3xde5k3+zk1sgrLy+J0Q@mail.gmail.com
State Committed
Commit 50c66c7acd90f257b295e58bf938ed120cbc27c7
Headers

Commit Message

Paul Pluzhnikov Aug. 29, 2017, 6:11 p.m. UTC
  Greetings,

This patch implements the other TODO in stdlib/tst-atexit-common.c

2017-08-29  Paul Pluzhnikov  <ppluzhnikov@google.com>

        * stdlib/tst-atexit-common.c (do_test): Test support for at least
        32 atexit handlers.
  

Comments

Carlos O'Donell Sept. 1, 2017, 12:40 a.m. UTC | #1
On 08/29/2017 01:11 PM, Paul Pluzhnikov wrote:
> Greetings,
> 
> This patch implements the other TODO in stdlib/tst-atexit-common.c
> 
> 2017-08-29  Paul Pluzhnikov  <ppluzhnikov@google.com>
> 
>         * stdlib/tst-atexit-common.c (do_test): Test support for at least
>         32 atexit handlers.
 
This looks good to me. Thank you for being so thorough.
  
H.J. Lu Sept. 1, 2017, 6:03 p.m. UTC | #2
On Tue, Aug 29, 2017 at 11:11 AM, Paul Pluzhnikov
<ppluzhnikov@google.com> wrote:
> Greetings,
>
> This patch implements the other TODO in stdlib/tst-atexit-common.c
>
> 2017-08-29  Paul Pluzhnikov  <ppluzhnikov@google.com>
>
>         * stdlib/tst-atexit-common.c (do_test): Test support for at least
>         32 atexit handlers.
>
>

It failed on Linux/i686:

FAIL: stdlib/tst-at_quick_exit
FAIL: stdlib/tst-atexit
FAIL: stdlib/tst-cxa_atexit
FAIL: stdlib/tst-on_exit

[hjl@gnu-6 build-i686-linux]$ ./stdlib/tst-at_quick_exit
crumbs:   00000000000000000000000003021121130211
expected: 00000000000000000000000003021121130211
unexpected exit status 1 from child 16101
[hjl@gnu-6 build-i686-linux]$
  

Patch

diff --git a/stdlib/tst-atexit-common.c b/stdlib/tst-atexit-common.c
index 99b00bf3aa..d6dcf08cdd 100644
--- a/stdlib/tst-atexit-common.c
+++ b/stdlib/tst-atexit-common.c
@@ -23,7 +23,13 @@ 
 #include <unistd.h>
 #include <sys/wait.h>
 
-#define MAX_ATEXIT 20  /* Large enough for current set of invocations.  */
+/* http://pubs.opengroup.org/onlinepubs/000095399/functions/atexit.html
+   requires that we support at least 32 atexit handlers.
+
+   The number we actually support is limited by memory. Here we simply
+   check that we support at least the minimum required.  */
+#define MAX_ATEXIT 32
+
 static char crumbs[MAX_ATEXIT];
 static int next_slot = 0;
 
@@ -66,7 +72,7 @@  static void
 fn_final (void)
 {
   /* Arbitrary sequence matching current registrations.  */
-  const char expected[] = "3021121130211";
+  const char expected[] = "00000000000000000000000003021121130211";
 
   if (strcmp (crumbs, expected) == 0)
     _exit_with_flush (0);
@@ -76,25 +82,26 @@  fn_final (void)
   _exit_with_flush (1);
 }
 
-/* This is currently just a basic test to verify that exit handlers execute
-   in LIFO order, even when the handlers register additional new handlers.
-
-   TODO: Additional tests that we should do:
-   1. POSIX says we need to support at least ATEXIT_MAX
-   2. ...  */
-
 static int
 do_test (void)
 {
+  int slots_remaining = MAX_ATEXIT;
+
   /* Register this first so it can verify expected order of the rest.  */
-  ATEXIT (fn_final);
+  ATEXIT (fn_final); --slots_remaining;
 
-  ATEXIT (fn1);
-  ATEXIT (fn3);
-  ATEXIT (fn1);
-  ATEXIT (fn2);
-  ATEXIT (fn1);
-  ATEXIT (fn3);
+  ATEXIT (fn1); --slots_remaining;
+  ATEXIT (fn3); --slots_remaining;
+  ATEXIT (fn1); --slots_remaining;
+  ATEXIT (fn2); --slots_remaining;
+  ATEXIT (fn1); --slots_remaining;
+  ATEXIT (fn3); --slots_remaining;
+
+  /* Fill the rest of available slots with fn0.  */
+  while (slots_remaining > 0)
+    {
+      ATEXIT (fn0); --slots_remaining;
+    }
 
   /* Verify that handlers registered above are inherited across fork.  */
   const pid_t child = fork ();