1*df1ea588SDmitry Chagin /*- 2*df1ea588SDmitry Chagin * Copyright (c) 2023 Dmitry Chagin <dchagin@FreeBSD.org> 3*df1ea588SDmitry Chagin * 4*df1ea588SDmitry Chagin * SPDX-License-Identifier: BSD-2-Clause 5*df1ea588SDmitry Chagin */ 6*df1ea588SDmitry Chagin #include <sys/cdefs.h> 7*df1ea588SDmitry Chagin __FBSDID("$FreeBSD$"); 8*df1ea588SDmitry Chagin 9*df1ea588SDmitry Chagin #include <sys/param.h> 10*df1ea588SDmitry Chagin #include <sys/wait.h> 11*df1ea588SDmitry Chagin 12*df1ea588SDmitry Chagin #include <execinfo.h> 13*df1ea588SDmitry Chagin #include <signal.h> 14*df1ea588SDmitry Chagin #include <stdio.h> 15*df1ea588SDmitry Chagin #include <string.h> 16*df1ea588SDmitry Chagin #include <unistd.h> 17*df1ea588SDmitry Chagin 18*df1ea588SDmitry Chagin #include <atf-c.h> 19*df1ea588SDmitry Chagin 20*df1ea588SDmitry Chagin #define BT_FUNCTIONS 10 21*df1ea588SDmitry Chagin 22*df1ea588SDmitry Chagin void handler(int); 23*df1ea588SDmitry Chagin 24*df1ea588SDmitry Chagin __noinline void 25*df1ea588SDmitry Chagin handler(int signum __unused) 26*df1ea588SDmitry Chagin { 27*df1ea588SDmitry Chagin void *addresses[BT_FUNCTIONS]; 28*df1ea588SDmitry Chagin char **symbols; 29*df1ea588SDmitry Chagin size_t n, i, match; 30*df1ea588SDmitry Chagin 31*df1ea588SDmitry Chagin n = backtrace(addresses, nitems(addresses)); 32*df1ea588SDmitry Chagin ATF_REQUIRE(n > 1); 33*df1ea588SDmitry Chagin symbols = backtrace_symbols(addresses, n); 34*df1ea588SDmitry Chagin ATF_REQUIRE(symbols != NULL); 35*df1ea588SDmitry Chagin 36*df1ea588SDmitry Chagin match = -1; 37*df1ea588SDmitry Chagin for (i = 0; i < n; i++) { 38*df1ea588SDmitry Chagin printf("%zu: %p, %s\n", i, addresses[i], symbols[i]); 39*df1ea588SDmitry Chagin if (strstr(symbols[i], "<main+") != NULL) 40*df1ea588SDmitry Chagin match = i; 41*df1ea588SDmitry Chagin } 42*df1ea588SDmitry Chagin ATF_REQUIRE(match > 0); 43*df1ea588SDmitry Chagin printf("match at %zu, symbols %zu\n", match, n); 44*df1ea588SDmitry Chagin 45*df1ea588SDmitry Chagin } 46*df1ea588SDmitry Chagin 47*df1ea588SDmitry Chagin ATF_TC_WITHOUT_HEAD(test_backtrace_sigtramp); 48*df1ea588SDmitry Chagin ATF_TC_BODY(test_backtrace_sigtramp, tc) 49*df1ea588SDmitry Chagin { 50*df1ea588SDmitry Chagin struct sigaction act; 51*df1ea588SDmitry Chagin pid_t child; 52*df1ea588SDmitry Chagin int status; 53*df1ea588SDmitry Chagin 54*df1ea588SDmitry Chagin memset(&act, 0, sizeof(act)); 55*df1ea588SDmitry Chagin act.sa_handler = handler; 56*df1ea588SDmitry Chagin sigemptyset(&act.sa_mask); 57*df1ea588SDmitry Chagin sigaction(SIGUSR1, &act, NULL); 58*df1ea588SDmitry Chagin 59*df1ea588SDmitry Chagin child = fork(); 60*df1ea588SDmitry Chagin ATF_REQUIRE(child != -1); 61*df1ea588SDmitry Chagin 62*df1ea588SDmitry Chagin if (child == 0) { 63*df1ea588SDmitry Chagin kill(getppid(), SIGUSR1); 64*df1ea588SDmitry Chagin _exit(0); 65*df1ea588SDmitry Chagin } else 66*df1ea588SDmitry Chagin wait(&status); 67*df1ea588SDmitry Chagin } 68*df1ea588SDmitry Chagin 69*df1ea588SDmitry Chagin ATF_TP_ADD_TCS(tp) 70*df1ea588SDmitry Chagin { 71*df1ea588SDmitry Chagin 72*df1ea588SDmitry Chagin ATF_TP_ADD_TC(tp, test_backtrace_sigtramp); 73*df1ea588SDmitry Chagin 74*df1ea588SDmitry Chagin return (atf_no_error()); 75*df1ea588SDmitry Chagin } 76