xref: /freebsd/lib/libexecinfo/tests/sigtramp_test.c (revision df1ea5887326103f0cc1445ab42fce528b474030)
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