1 /*
2  * Copyright Meta Platforms, Inc. and its affiliates.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdio.h>
8 #include <zephyr/kernel.h>
9 #include <zephyr/ztest.h>
10 
11 #define STACK_SIZE 256
12 #define THREAD_COUNT 7
13 
14 static struct k_thread threads[THREAD_COUNT];
15 static uint32_t params[THREAD_COUNT];
16 static K_THREAD_STACK_ARRAY_DEFINE(thread_stacks, THREAD_COUNT, STACK_SIZE);
17 static K_SEM_DEFINE(sem, 0, 1);
18 
func0(uint32_t param)19 static void func0(uint32_t param)
20 {
21 	int ret = -EAGAIN;
22 
23 	while (ret != 0) {
24 		ret = k_sem_take(&sem, K_NO_WAIT);
25 		k_sleep(K_MSEC(param));
26 	}
27 
28 	k_panic();
29 }
30 
test_thread_entry(void * p1,void * p2,void * p3)31 static void test_thread_entry(void *p1, void *p2, void *p3)
32 {
33 	uint32_t *param = (uint32_t *)p1;
34 
35 	func0(*param);
36 }
37 
coredump_threads_suite_setup(void)38 static void *coredump_threads_suite_setup(void)
39 {
40 	/* Spawn a few threads */
41 	for (int i = 0; i < THREAD_COUNT; i++) {
42 		params[i] = i;
43 		k_thread_create(
44 			&threads[i],
45 			thread_stacks[i],
46 			K_THREAD_STACK_SIZEOF(thread_stacks[i]),
47 			test_thread_entry,
48 			&params[i],
49 			NULL,
50 			NULL,
51 			(THREAD_COUNT - i), /* arbitrary priority */
52 			0,
53 			K_NO_WAIT);
54 
55 		char thread_name[32];
56 
57 		snprintf(thread_name, sizeof(thread_name), "thread%d", i);
58 		k_thread_name_set(&threads[i], thread_name);
59 	}
60 
61 	return NULL;
62 }
63 
64 ZTEST_SUITE(coredump_threads, NULL, coredump_threads_suite_setup, NULL, NULL, NULL);
65 
ZTEST(coredump_threads,test_crash)66 ZTEST(coredump_threads, test_crash)
67 {
68 	/* Give semaphore allowing one of the waiting threads to continue and panic */
69 	k_sem_give(&sem);
70 	for (int i = 0; i < THREAD_COUNT; i++) {
71 		k_thread_join(&threads[i], K_FOREVER);
72 	}
73 }
74