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