xref: /dpdk/app/test/test_debug.c (revision daa02b5cddbb8e11b31d41e2bf7bb1ae64dcae2f)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4 
5 #include <stdio.h>
6 #include <stdint.h>
7 #include <sys/resource.h>
8 #include <sys/time.h>
9 #include <sys/wait.h>
10 #include <unistd.h>
11 
12 #include <rte_debug.h>
13 #include <rte_common.h>
14 #include <rte_eal.h>
15 #include <rte_service_component.h>
16 
17 #include "test.h"
18 
19 /*
20  * Debug test
21  * ==========
22  */
23 
24 /* use fork() to test rte_panic() */
25 static int
26 test_panic(void)
27 {
28 	int pid;
29 	int status;
30 
31 	pid = fork();
32 
33 	if (pid == 0) {
34 		struct rlimit rl;
35 
36 		/* No need to generate a coredump when panicking. */
37 		rl.rlim_cur = rl.rlim_max = 0;
38 		setrlimit(RLIMIT_CORE, &rl);
39 		rte_panic("Test Debug\n");
40 	} else if (pid < 0) {
41 		printf("Fork Failed\n");
42 		return -1;
43 	}
44 	wait(&status);
45 	if(status == 0){
46 		printf("Child process terminated normally!\n");
47 		return -1;
48 	} else
49 		printf("Child process terminated as expected - Test passed!\n");
50 
51 	return 0;
52 }
53 
54 /* use fork() to test rte_exit() */
55 static int
56 test_exit_val(int exit_val)
57 {
58 	int pid;
59 	int status;
60 
61 	/* manually cleanup EAL memory, as the fork() below would otherwise
62 	 * cause the same hugepages to be free()-ed multiple times.
63 	 */
64 	rte_service_finalize();
65 
66 	pid = fork();
67 
68 	if (pid == 0)
69 		rte_exit(exit_val, __func__);
70 	else if (pid < 0){
71 		printf("Fork Failed\n");
72 		return -1;
73 	}
74 	wait(&status);
75 	printf("Child process status: %d\n", status);
76 	if(!WIFEXITED(status) || WEXITSTATUS(status) != (uint8_t)exit_val){
77 		printf("Child process terminated with incorrect status (expected = %d)!\n",
78 				exit_val);
79 		return -1;
80 	}
81 	return 0;
82 }
83 
84 static int
85 test_exit(void)
86 {
87 	int test_vals[] = { 0, 1, 2, 255, -1 };
88 	unsigned i;
89 	for (i = 0; i < RTE_DIM(test_vals); i++) {
90 		if (test_exit_val(test_vals[i]) < 0)
91 			return -1;
92 	}
93 	printf("%s Passed\n", __func__);
94 	return 0;
95 }
96 
97 static void
98 dummy_app_usage(const char *progname)
99 {
100 	RTE_SET_USED(progname);
101 }
102 
103 static int
104 test_usage(void)
105 {
106 	if (rte_set_application_usage_hook(dummy_app_usage) != NULL) {
107 		printf("Non-NULL value returned for initial usage hook\n");
108 		return -1;
109 	}
110 	if (rte_set_application_usage_hook(NULL) != dummy_app_usage) {
111 		printf("Incorrect value returned for application usage hook\n");
112 		return -1;
113 	}
114 	return 0;
115 }
116 
117 static int
118 test_debug(void)
119 {
120 	rte_dump_stack();
121 	if (test_panic() < 0)
122 		return -1;
123 	if (test_exit() < 0)
124 		return -1;
125 	if (test_usage() < 0)
126 		return -1;
127 	return 0;
128 }
129 
130 REGISTER_TEST_COMMAND(debug_autotest, test_debug);
131