1 /*
2 * Copyright (c) 2022 Nordic Semiconductor
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/ztest.h>
8 #include <zephyr/logging/log.h>
9
10 /* The idea of this test is to estimate stack usage of logging messages. Each
11 * test checks stack usage before and after logging a message. Increase of stack
12 * usage is interpreted as stack used by the logging. Test has been used to
13 * characterize some common architectures and it will fail if significantly more
14 * stack is used.
15 *
16 * This will help to detect when changes in logging, toolchain or modules used
17 * by logging increase stack usage. Failure of the test should lead to investigation
18 * to determine if stack usage change is justified. If it is justified, thresholds
19 * may be updated.
20 */
21
22 LOG_MODULE_REGISTER(test);
23
24 static size_t simple_usage;
25 static size_t hexdump_usage;
26 static size_t more_args_usage;
27
28 /* Stack increase margin. */
29 #ifdef CONFIG_PICOLIBC
30 #define STACK_USAGE_MARGIN 128
31 #else
32 #define STACK_USAGE_MARGIN 16
33 #endif
34
after(void * data)35 static void after(void *data)
36 {
37 PRINT("#elif %sdefined(CONFIG_LOG_MODE_IMMEDIATE) && %sdefined(CONFIG_NO_OPTIMIZATIONS)\n",
38 IS_ENABLED(CONFIG_LOG_MODE_IMMEDIATE) ? "" : "!",
39 IS_ENABLED(CONFIG_NO_OPTIMIZATIONS) ? "" : "!");
40 PRINT("#define SIMPLE_USAGE %zu\n", simple_usage);
41 PRINT("#define HEXDUMP_USAGE %zu\n", hexdump_usage);
42 PRINT("#define MORE_ARGS_USAGE %zu\n", more_args_usage);
43 }
44
45 ZTEST_SUITE(test_log_stack, NULL, NULL, NULL, NULL, after);
46
47 #define TEST_LOG_STACK(usage, log_msg) do { \
48 size_t unused, unused2; \
49 int err; \
50 \
51 k_msleep(100); \
52 err = k_thread_stack_space_get(k_current_get(), &unused); \
53 zassert_equal(err, 0); \
54 __DEBRACKET log_msg; \
55 \
56 k_msleep(100); \
57 \
58 err = k_thread_stack_space_get(k_current_get(), &unused2); \
59 zassert_equal(err, 0); \
60 \
61 usage = unused - unused2; \
62 PRINT("Stack increase due to log usage: %zu\n", usage); \
63 } while (0)
64
65 #if defined(CONFIG_CPU_CORTEX_M0)
66
67 #if !defined(CONFIG_LOG_MODE_IMMEDIATE) && !defined(CONFIG_NO_OPTIMIZATIONS)
68 #define SIMPLE_USAGE 120
69 #define HEXDUMP_USAGE 120
70 #define MORE_ARGS_USAGE 136
71 #elif defined(CONFIG_LOG_MODE_IMMEDIATE) && !defined(CONFIG_NO_OPTIMIZATIONS)
72 #define SIMPLE_USAGE 436
73 #define HEXDUMP_USAGE 436
74 #define MORE_ARGS_USAGE 452
75 #elif !defined(CONFIG_LOG_MODE_IMMEDIATE) && defined(CONFIG_NO_OPTIMIZATIONS)
76 #define SIMPLE_USAGE 168
77 #define HEXDUMP_USAGE 168
78 #define MORE_ARGS_USAGE 171
79 #elif defined(CONFIG_LOG_MODE_IMMEDIATE) && defined(CONFIG_NO_OPTIMIZATIONS)
80 #define SIMPLE_USAGE 911
81 #define HEXDUMP_USAGE 911
82 #define MORE_ARGS_USAGE 927
83 #endif
84
85 #elif defined(CONFIG_CPU_CORTEX_M3)
86
87 #if !defined(CONFIG_LOG_MODE_IMMEDIATE) && !defined(CONFIG_NO_OPTIMIZATIONS)
88 #define SIMPLE_USAGE 160
89 #define HEXDUMP_USAGE 160
90 #define MORE_ARGS_USAGE 176
91 #elif defined(CONFIG_LOG_MODE_IMMEDIATE) && !defined(CONFIG_NO_OPTIMIZATIONS)
92 #define SIMPLE_USAGE 388
93 #define HEXDUMP_USAGE 388
94 #define MORE_ARGS_USAGE 404
95 #elif !defined(CONFIG_LOG_MODE_IMMEDIATE) && defined(CONFIG_NO_OPTIMIZATIONS)
96 #define SIMPLE_USAGE 144
97 #define HEXDUMP_USAGE 88
98 #define MORE_ARGS_USAGE 144
99 #elif defined(CONFIG_LOG_MODE_IMMEDIATE) && defined(CONFIG_NO_OPTIMIZATIONS)
100 #define SIMPLE_USAGE 640
101 #define HEXDUMP_USAGE 640
102 #define MORE_ARGS_USAGE 656
103 #endif
104
105 #elif defined(CONFIG_X86) && !defined(CONFIG_X86_64)
106
107 #if !defined(CONFIG_LOG_MODE_IMMEDIATE) && !defined(CONFIG_NO_OPTIMIZATIONS)
108 #define SIMPLE_USAGE 72
109 #define HEXDUMP_USAGE 68
110 #define MORE_ARGS_USAGE 88
111 #elif defined(CONFIG_LOG_MODE_IMMEDIATE) && !defined(CONFIG_NO_OPTIMIZATIONS)
112 #define SIMPLE_USAGE 448
113 #define HEXDUMP_USAGE 444
114 #define MORE_ARGS_USAGE 484
115 #elif !defined(CONFIG_LOG_MODE_IMMEDIATE) && defined(CONFIG_NO_OPTIMIZATIONS)
116 #define SIMPLE_USAGE 288
117 #define HEXDUMP_USAGE 272
118 #define MORE_ARGS_USAGE 304
119 #elif defined(CONFIG_LOG_MODE_IMMEDIATE) && defined(CONFIG_NO_OPTIMIZATIONS)
120 #define SIMPLE_USAGE 988
121 #define HEXDUMP_USAGE 972
122 #define MORE_ARGS_USAGE 1020
123 #endif
124
125 #elif defined(CONFIG_X86_64)
126
127 #if !defined(CONFIG_LOG_MODE_IMMEDIATE) && !defined(CONFIG_NO_OPTIMIZATIONS)
128 #define SIMPLE_USAGE 168
129 #define HEXDUMP_USAGE 136
130 #define MORE_ARGS_USAGE 200
131 #elif defined(CONFIG_LOG_MODE_IMMEDIATE) && !defined(CONFIG_NO_OPTIMIZATIONS)
132 #define SIMPLE_USAGE 1120
133 #define HEXDUMP_USAGE 1104
134 #define MORE_ARGS_USAGE 1184
135 #elif !defined(CONFIG_LOG_MODE_IMMEDIATE) && defined(CONFIG_NO_OPTIMIZATIONS)
136 #define SIMPLE_USAGE 576
137 #define HEXDUMP_USAGE 576
138 #define MORE_ARGS_USAGE 608
139 #elif defined(CONFIG_LOG_MODE_IMMEDIATE) && defined(CONFIG_NO_OPTIMIZATIONS)
140 #define SIMPLE_USAGE 1680
141 #define HEXDUMP_USAGE 1680
142 #define MORE_ARGS_USAGE 1744
143 #endif
144
145 #elif defined(CONFIG_RISCV) && !defined(CONFIG_64BIT) && !defined(CONFIG_SMP)
146
147 #if !defined(CONFIG_LOG_MODE_IMMEDIATE) && !defined(CONFIG_NO_OPTIMIZATIONS)
148 #define SIMPLE_USAGE 136
149 #define HEXDUMP_USAGE 136
150 #define MORE_ARGS_USAGE 152
151 #elif defined(CONFIG_LOG_MODE_IMMEDIATE) && !defined(CONFIG_NO_OPTIMIZATIONS)
152 #define SIMPLE_USAGE 504
153 #define HEXDUMP_USAGE 504
154 #define MORE_ARGS_USAGE 520
155 #elif !defined(CONFIG_LOG_MODE_IMMEDIATE) && defined(CONFIG_NO_OPTIMIZATIONS)
156 #define SIMPLE_USAGE 240
157 #define HEXDUMP_USAGE 240
158 #define MORE_ARGS_USAGE 240
159 #elif defined(CONFIG_LOG_MODE_IMMEDIATE) && defined(CONFIG_NO_OPTIMIZATIONS)
160 #define SIMPLE_USAGE 992
161 #define HEXDUMP_USAGE 992
162 #define MORE_ARGS_USAGE 1008
163 #endif
164
165 #elif defined(CONFIG_RISCV) && !defined(CONFIG_64BIT) && defined(CONFIG_SMP)
166
167 #if !defined(CONFIG_LOG_MODE_IMMEDIATE) && !defined(CONFIG_NO_OPTIMIZATIONS)
168 #define SIMPLE_USAGE 96
169 #define HEXDUMP_USAGE 96
170 #define MORE_ARGS_USAGE 112
171 #elif defined(CONFIG_LOG_MODE_IMMEDIATE) && !defined(CONFIG_NO_OPTIMIZATIONS)
172 #define SIMPLE_USAGE 456
173 #define HEXDUMP_USAGE 456
174 #define MORE_ARGS_USAGE 472
175 #elif !defined(CONFIG_LOG_MODE_IMMEDIATE) && defined(CONFIG_NO_OPTIMIZATIONS)
176 #define SIMPLE_USAGE 304
177 #define HEXDUMP_USAGE 240
178 #define MORE_ARGS_USAGE 240
179 #elif defined(CONFIG_LOG_MODE_IMMEDIATE) && defined(CONFIG_NO_OPTIMIZATIONS)
180 #define SIMPLE_USAGE 1008
181 #define HEXDUMP_USAGE 1008
182 #define MORE_ARGS_USAGE 1024
183 #endif
184
185 #elif defined(CONFIG_RISCV) && defined(CONFIG_64BIT) && defined(CONFIG_SMP)
186
187 #if !defined(CONFIG_LOG_MODE_IMMEDIATE) && !defined(CONFIG_NO_OPTIMIZATIONS)
188 #define SIMPLE_USAGE 200
189 #define HEXDUMP_USAGE 168
190 #define MORE_ARGS_USAGE 232
191 #elif defined(CONFIG_LOG_MODE_IMMEDIATE) && !defined(CONFIG_NO_OPTIMIZATIONS)
192 #define SIMPLE_USAGE 736
193 #define HEXDUMP_USAGE 768
194 #define MORE_ARGS_USAGE 768
195 #elif !defined(CONFIG_LOG_MODE_IMMEDIATE) && defined(CONFIG_NO_OPTIMIZATIONS)
196 #define SIMPLE_USAGE 320
197 #define HEXDUMP_USAGE 320
198 #define MORE_ARGS_USAGE 320
199 #elif defined(CONFIG_LOG_MODE_IMMEDIATE) && defined(CONFIG_NO_OPTIMIZATIONS)
200 #define SIMPLE_USAGE 1248
201 #define HEXDUMP_USAGE 1248
202 #define MORE_ARGS_USAGE 1280
203 #endif
204
205 #elif defined(CONFIG_RISCV) && defined(CONFIG_64BIT)
206
207 #if !defined(CONFIG_LOG_MODE_IMMEDIATE) && !defined(CONFIG_NO_OPTIMIZATIONS)
208 #define SIMPLE_USAGE 240
209 #define HEXDUMP_USAGE 240
210 #define MORE_ARGS_USAGE 272
211 #elif defined(CONFIG_LOG_MODE_IMMEDIATE) && !defined(CONFIG_NO_OPTIMIZATIONS)
212 #define SIMPLE_USAGE 704
213 #define HEXDUMP_USAGE 704
214 #define MORE_ARGS_USAGE 736
215 #elif !defined(CONFIG_LOG_MODE_IMMEDIATE) && defined(CONFIG_NO_OPTIMIZATIONS)
216 #define SIMPLE_USAGE 320
217 #define HEXDUMP_USAGE 320
218 #define MORE_ARGS_USAGE 320
219 #elif defined(CONFIG_LOG_MODE_IMMEDIATE) && defined(CONFIG_NO_OPTIMIZATIONS)
220 #define SIMPLE_USAGE 1128
221 #define HEXDUMP_USAGE 1128
222 #define MORE_ARGS_USAGE 1160
223 #endif
224
225 #elif defined(CONFIG_SPARC)
226
227 #if !defined(CONFIG_LOG_MODE_IMMEDIATE) && !defined(CONFIG_NO_OPTIMIZATIONS)
228 #define SIMPLE_USAGE 0
229 #define HEXDUMP_USAGE 28
230 #define MORE_ARGS_USAGE 0
231 #elif defined(CONFIG_LOG_MODE_IMMEDIATE) && !defined(CONFIG_NO_OPTIMIZATIONS)
232 #define SIMPLE_USAGE 849
233 #define HEXDUMP_USAGE 849
234 #define MORE_ARGS_USAGE 865
235 #elif !defined(CONFIG_LOG_MODE_IMMEDIATE) && defined(CONFIG_NO_OPTIMIZATIONS)
236 #define SIMPLE_USAGE 416
237 #define HEXDUMP_USAGE 232
238 #define MORE_ARGS_USAGE 416
239 #elif defined(CONFIG_LOG_MODE_IMMEDIATE) && defined(CONFIG_NO_OPTIMIZATIONS)
240 #define SIMPLE_USAGE 1544
241 #define HEXDUMP_USAGE 1544
242 #define MORE_ARGS_USAGE 1560
243 #endif
244
245 #elif defined(CONFIG_XTENSA)
246
247 #if !defined(CONFIG_LOG_MODE_IMMEDIATE) && !defined(CONFIG_NO_OPTIMIZATIONS)
248 #define SIMPLE_USAGE 72
249 #define HEXDUMP_USAGE 168
250 #define MORE_ARGS_USAGE 88
251 #elif defined(CONFIG_LOG_MODE_IMMEDIATE) && !defined(CONFIG_NO_OPTIMIZATIONS)
252 #define SIMPLE_USAGE 584
253 #define HEXDUMP_USAGE 584
254 #define MORE_ARGS_USAGE 600
255 #elif !defined(CONFIG_LOG_MODE_IMMEDIATE) && defined(CONFIG_NO_OPTIMIZATIONS)
256 #define SIMPLE_USAGE 336
257 #define HEXDUMP_USAGE 336
258 #define MORE_ARGS_USAGE 336
259 #elif defined(CONFIG_LOG_MODE_IMMEDIATE) && defined(CONFIG_NO_OPTIMIZATIONS)
260 #define SIMPLE_USAGE 1040
261 #define HEXDUMP_USAGE 1040
262 #define MORE_ARGS_USAGE 1056
263 #endif
264
265 #else
266 /* For other platforms which were not characterized use something big. */
267 #define SIMPLE_USAGE 2000
268 #define HEXDUMP_USAGE 2000
269 #define MORE_ARGS_USAGE 2000
270 #endif
271
272 #define SIMPLE_USAGE_LIMIT (SIMPLE_USAGE + STACK_USAGE_MARGIN)
273 #define HEXDUMP_USAGE_LIMIT (HEXDUMP_USAGE + STACK_USAGE_MARGIN)
274 #define MORE_ARGS_USAGE_LIMIT (MORE_ARGS_USAGE + STACK_USAGE_MARGIN)
275
ZTEST(test_log_stack,test_log_simple)276 ZTEST(test_log_stack, test_log_simple)
277 {
278 uint32_t test_u = 1;
279 int test_i = 1;
280
281 TEST_LOG_STACK(simple_usage, (LOG_INF("test %u %d", test_u, test_i)));
282
283 zassert_true(simple_usage <= SIMPLE_USAGE_LIMIT, "Usage:%zu, expected:%zu",
284 simple_usage, SIMPLE_USAGE_LIMIT);
285 }
286
ZTEST(test_log_stack,test_log_hexdump)287 ZTEST(test_log_stack, test_log_hexdump)
288 {
289 uint8_t data[] = {1, 2, 3, 4};
290
291 TEST_LOG_STACK(hexdump_usage, (LOG_HEXDUMP_INF(data, sizeof(data), "description")));
292
293 zassert_true(hexdump_usage <= HEXDUMP_USAGE_LIMIT, "Usage:%zu, expected:%zu",
294 hexdump_usage, HEXDUMP_USAGE_LIMIT);
295 }
296
ZTEST(test_log_stack,test_log_more_args)297 ZTEST(test_log_stack, test_log_more_args)
298 {
299 TEST_LOG_STACK(more_args_usage, (LOG_INF("test %d %d %d %d %d %d",
300 k_uptime_get_32(), k_uptime_get_32(),
301 k_uptime_get_32(), k_uptime_get_32(),
302 k_uptime_get_32(), k_uptime_get_32())));
303
304 zassert_true(more_args_usage <= MORE_ARGS_USAGE_LIMIT, "Usage:%zu, expected:%zu",
305 more_args_usage, MORE_ARGS_USAGE_LIMIT);
306 }
307