coredump: Add test for threads core dump config

Add z_test which uses new configs to capture multiple
threads in a core dump and with all of the context
necessary to debug the threads.

Signed-off-by: Mark Holden <mholden@meta.com>
This commit is contained in:
Mark Holden 2024-06-24 13:23:57 -07:00 committed by Anas Nashif
commit c35f6d1cac
6 changed files with 127 additions and 0 deletions

View file

@ -60,6 +60,7 @@ config DEBUG_COREDUMP_MEMORY_DUMP_MIN
config DEBUG_COREDUMP_MEMORY_DUMP_THREADS config DEBUG_COREDUMP_MEMORY_DUMP_THREADS
bool "Threads" bool "Threads"
depends on !SMP
select THREAD_STACK_INFO select THREAD_STACK_INFO
select DEBUG_THREAD_INFO select DEBUG_THREAD_INFO
select DEBUG_COREDUMP_THREADS_METADATA select DEBUG_COREDUMP_THREADS_METADATA
@ -98,6 +99,7 @@ config DEBUG_COREDUMP_SHELL
config DEBUG_COREDUMP_THREADS_METADATA config DEBUG_COREDUMP_THREADS_METADATA
bool "Threads metadata" bool "Threads metadata"
depends on !SMP
select DEBUG_THREAD_INFO select DEBUG_THREAD_INFO
help help
Core dump will contain the threads metadata section containing Core dump will contain the threads metadata section containing

View file

@ -58,6 +58,8 @@ static void dump_header(unsigned int reason)
backend_api->buffer_output((uint8_t *)&hdr, sizeof(hdr)); backend_api->buffer_output((uint8_t *)&hdr, sizeof(hdr));
} }
#if defined(CONFIG_DEBUG_COREDUMP_MEMORY_DUMP_MIN) || \
defined(CONFIG_DEBUG_COREDUMP_MEMORY_DUMP_THREADS)
static void dump_thread(struct k_thread *thread) static void dump_thread(struct k_thread *thread)
{ {
uintptr_t end_addr; uintptr_t end_addr;
@ -80,6 +82,7 @@ static void dump_thread(struct k_thread *thread)
coredump_memory_dump(thread->stack_info.start, end_addr); coredump_memory_dump(thread->stack_info.start, end_addr);
} }
#endif
#if defined(CONFIG_COREDUMP_DEVICE) #if defined(CONFIG_COREDUMP_DEVICE)
static void process_coredump_dev_memory(const struct device *dev) static void process_coredump_dev_memory(const struct device *dev)

View file

@ -0,0 +1,8 @@
# SPDX-License-Identifier: Apache-2.0
cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(debug_coredump_threads)
target_sources(app PRIVATE src/main.c)

View file

@ -0,0 +1,7 @@
# Copyright Meta Platforms, Inc. and its affiliates.
# SPDX-License-Identifier: Apache-2.0
CONFIG_ZTEST=y
CONFIG_DEBUG_COREDUMP=y
CONFIG_DEBUG_COREDUMP_MEMORY_DUMP_THREADS=y

View file

@ -0,0 +1,73 @@
/*
* Copyright Meta Platforms, Inc. and its affiliates.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <zephyr/kernel.h>
#include <zephyr/ztest.h>
#define STACK_SIZE 256
#define THREAD_COUNT 7
static struct k_thread threads[THREAD_COUNT];
static uint32_t params[THREAD_COUNT];
static K_THREAD_STACK_ARRAY_DEFINE(thread_stacks, THREAD_COUNT, STACK_SIZE);
static K_SEM_DEFINE(sem, 0, 1);
static void func0(uint32_t param)
{
int ret = -EAGAIN;
while (ret != 0) {
ret = k_sem_take(&sem, K_NO_WAIT);
k_sleep(K_MSEC(param));
}
k_panic();
}
static void test_thread_entry(void *p1, void *p2, void *p3)
{
uint32_t *param = (uint32_t *)p1;
func0(*param);
}
static void *coredump_threads_suite_setup(void)
{
/* Spawn a few threads */
for (int i = 0; i < THREAD_COUNT; i++) {
params[i] = i;
k_thread_create(
&threads[i],
thread_stacks[i],
K_THREAD_STACK_SIZEOF(thread_stacks[i]),
test_thread_entry,
&params[i],
NULL,
NULL,
(THREAD_COUNT - i), /* arbitrary priority */
0,
K_NO_WAIT);
char thread_name[32];
snprintf(thread_name, sizeof(thread_name), "thread%d", i);
k_thread_name_set(&threads[i], thread_name);
}
return NULL;
}
ZTEST_SUITE(coredump_threads, NULL, coredump_threads_suite_setup, NULL, NULL, NULL);
ZTEST(coredump_threads, test_crash)
{
/* Give semaphore allowing one of the waiting threads to continue and panic */
k_sem_give(&sem);
for (int i = 0; i < THREAD_COUNT; i++) {
k_thread_join(&threads[i], K_FOREVER);
}
}

View file

@ -0,0 +1,34 @@
# Copyright Meta Platforms, Inc. and its affiliates.
# SPDX-License-Identifier: Apache-2.0
common:
tags:
- coredump
ignore_faults: true
ignore_qemu_crash: true
integration_platforms:
- qemu_cortex_m3
tests:
debug.coredump.threads:
filter: CONFIG_DEBUG_COREDUMP_MEMORY_DUMP_THREADS
harness: console
harness_config:
type: multi_line
# Verify core dump contains threads metadata section and several
# memory sections, two for each thread
regex:
- "E: #CD:BEGIN#"
- "E: #CD:5([aA])45([0-9a-fA-F]+)"
- "E: #CD:41([0-9a-fA-F]+)"
- "E: #CD:54([0-9a-fA-F]+)"
- "E: #CD:4([dD])([0-9a-fA-F]+)"
- "E: #CD:4([dD])([0-9a-fA-F]+)"
- "E: #CD:4([dD])([0-9a-fA-F]+)"
- "E: #CD:4([dD])([0-9a-fA-F]+)"
- "E: #CD:4([dD])([0-9a-fA-F]+)"
- "E: #CD:4([dD])([0-9a-fA-F]+)"
- "E: #CD:4([dD])([0-9a-fA-F]+)"
- "E: #CD:4([dD])([0-9a-fA-F]+)"
- "E: #CD:4([dD])([0-9a-fA-F]+)"
- "E: #CD:4([dD])([0-9a-fA-F]+)"
- "E: #CD:END#"