(root)/
glibc-2.38/
signal/
tst-minsigstksz-5.c
       1  /* Test of signal delivery on an alternate stack with MINSIGSTKSZ size.
       2     Copyright (C) 2020-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <signal.h>
      20  #include <stdlib.h>
      21  #include <string.h>
      22  #include <unistd.h>
      23  #include <support/check.h>
      24  #include <support/support.h>
      25  
      26  static volatile sig_atomic_t handler_run;
      27  
      28  static void
      29  handler (int signo)
      30  {
      31    /* Clear a bit of on-stack memory.  */
      32    volatile char buffer[256];
      33    for (size_t i = 0; i < sizeof (buffer); ++i)
      34      buffer[i] = 0;
      35    handler_run = 1;
      36  }
      37  
      38  int
      39  do_test (void)
      40  {
      41    size_t stack_buffer_size = 64 * 1024 * 1024;
      42    void *stack_buffer = xmalloc (stack_buffer_size);
      43    void *stack_end = stack_buffer + stack_buffer_size;
      44    memset (stack_buffer, 0xCC, stack_buffer_size);
      45  
      46    void *stack_bottom = stack_buffer + (stack_buffer_size + MINSIGSTKSZ) / 2;
      47    void *stack_top = stack_bottom + MINSIGSTKSZ;
      48    stack_t stack =
      49      {
      50        .ss_sp = stack_bottom,
      51        .ss_size = MINSIGSTKSZ,
      52      };
      53    if (sigaltstack (&stack, NULL) < 0)
      54      FAIL_RET ("sigaltstack: %m\n");
      55  
      56    struct sigaction act =
      57      {
      58        .sa_handler = handler,
      59        .sa_flags = SA_ONSTACK,
      60      };
      61    if (sigaction (SIGUSR1, &act, NULL) < 0)
      62      FAIL_RET ("sigaction: %m\n");
      63  
      64    if (kill (getpid (), SIGUSR1) < 0)
      65      FAIL_RET ("kill: %m\n");
      66  
      67    if (handler_run != 1)
      68      FAIL_RET ("handler did not run\n");
      69  
      70    for (void *p = stack_buffer; p < stack_bottom; ++p)
      71      if (*(unsigned char *) p != 0xCC)
      72        FAIL_RET ("changed byte %ld bytes below configured stack\n",
      73  		(long) (stack_bottom - p));
      74    for (void *p = stack_top; p < stack_end; ++p)
      75      if (*(unsigned char *) p != 0xCC)
      76        FAIL_RET ("changed byte %ld bytes above configured stack\n",
      77  		(long) (p - stack_top));
      78  
      79    free (stack_buffer);
      80  
      81    return 0;
      82  }
      83  
      84  #include <support/test-driver.c>