• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) Crackerjack Project., 2007
4  * Copyright (C) 2022 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
5  */
6 
7 /*\
8  * [Description]
9  *
10  * This test is checking if waitid() syscall recognizes a process that ended
11  * with division by zero error.
12  */
13 
14 #include <stdlib.h>
15 #include <sys/wait.h>
16 #include <sys/prctl.h>
17 #include "tst_test.h"
18 
19 static siginfo_t *infop;
20 static int core_dumps = 1;
21 
run(void)22 static void run(void)
23 {
24 	pid_t pidchild;
25 
26 	/*
27 	 * Triggering SIGFPE by invalid instruction is not always possible,
28 	 * some architectures does not trap division-by-zero at all and even
29 	 * when it's possible we would have to fight the compiler optimizations
30 	 * that have tendency to remove undefined operations.
31 	 */
32 	pidchild = SAFE_FORK();
33 	if (!pidchild)
34 		raise(SIGFPE);
35 
36 	TST_EXP_PASS(waitid(P_ALL, 0, infop, WEXITED));
37 	TST_EXP_EQ_LI(infop->si_pid, pidchild);
38 	TST_EXP_EQ_LI(infop->si_status, SIGFPE);
39 	TST_EXP_EQ_LI(infop->si_signo, SIGCHLD);
40 
41 	if (core_dumps)
42 		TST_EXP_EQ_LI(infop->si_code, CLD_DUMPED);
43 	else
44 		TST_EXP_EQ_LI(infop->si_code, CLD_KILLED);
45 }
46 
setup(void)47 static void setup(void)
48 {
49 	struct rlimit rlim;
50 	char c;
51 
52 	SAFE_GETRLIMIT(RLIMIT_CORE, &rlim);
53 	SAFE_FILE_SCANF("/proc/sys/kernel/core_pattern", "%c", &c);
54 
55 	if (rlim.rlim_cur)
56 		return;
57 
58 	if (!rlim.rlim_max) {
59 		if (c != '|')
60 			core_dumps = 0;
61 		return;
62 	}
63 
64 	tst_res(TINFO, "Raising RLIMIT_CORE rlim_cur=%li -> %li",
65 	        rlim.rlim_cur, rlim.rlim_max);
66 
67 	rlim.rlim_cur = rlim.rlim_max;
68 	SAFE_SETRLIMIT(RLIMIT_CORE, &rlim);
69 }
70 
71 static struct tst_test test = {
72 	.test_all = run,
73 	.forks_child = 1,
74 	.setup = setup,
75 	.bufs =	(struct tst_buffers[]) {
76 		{&infop, .size = sizeof(*infop)},
77 		{},
78 	},
79 };
80