(root)/
glibc-2.38/
sysdeps/
unix/
sysv/
linux/
tst-sigcontext-get_pc.c
       1  /* Test that the GET_PC macro is consistent with the unwinder.
       2     Copyright (C) 2019-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 License as
       7     published by the Free Software Foundation; either version 2.1 of the
       8     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; see the file COPYING.LIB.  If
      17     not, see <https://www.gnu.org/licenses/>.  */
      18  
      19  /* This test searches for the value of the GET_PC macro in the
      20     addresses obtained from the backtrace function.  */
      21  
      22  #include <array_length.h>
      23  #include <execinfo.h>
      24  #include <inttypes.h>
      25  #include <signal.h>
      26  #include <stdbool.h>
      27  #include <stdio.h>
      28  #include <support/check.h>
      29  #include <support/xsignal.h>
      30  #include <sigcontextinfo.h>
      31  
      32  static bool handler_called;
      33  
      34  static void
      35  handler (int signal, siginfo_t *info, void *ctx)
      36  {
      37    TEST_COMPARE (signal, SIGUSR1);
      38  
      39    uintptr_t pc = sigcontext_get_pc (ctx);
      40    printf ("info: address in signal handler: 0x%" PRIxPTR "\n", pc);
      41  
      42    void *callstack[10];
      43    int callstack_count = backtrace (callstack, array_length (callstack));
      44    TEST_VERIFY_EXIT (callstack_count > 0);
      45    TEST_VERIFY_EXIT (callstack_count <= array_length (callstack));
      46    bool found = false;
      47    for (int i = 0; i < callstack_count; ++i)
      48      {
      49        const char *marker;
      50        if ((uintptr_t) callstack[i] == pc)
      51          {
      52            found = true;
      53            marker = " *";
      54          }
      55        else
      56          marker = "";
      57        printf ("info: call stack entry %d: 0x%" PRIxPTR "%s\n",
      58                i, (uintptr_t) callstack[i], marker);
      59      }
      60    TEST_VERIFY (found);
      61    handler_called = true;
      62  }
      63  
      64  static int
      65  do_test (void)
      66  {
      67    struct sigaction sa =
      68      {
      69       .sa_sigaction = &handler,
      70       .sa_flags = SA_SIGINFO
      71      };
      72    xsigaction (SIGUSR1, &sa, NULL);
      73    raise (SIGUSR1);
      74    TEST_VERIFY (handler_called);
      75    return 0;
      76  }
      77  
      78  #include <support/test-driver.c>