shell: modules: kernel: group thread-related cmds
`stacks` `threads` & `unwind` are commands related to kernel thread, group them one level inside a main `thread` command, and rename `threads` to `list`: - `kernel threads` -> `kernel thread list` - `kernel stacks` -> `kernel thread stacks` - `kernel unwind` -> `kernel thread unwind` Additionally, rename and mark the `thread_valid()` function as `__maybe_unused` as it might be unused for architectures without stackwalk implementation, and use the locked version of the thread iterator (`k_thread_foreach()`) Signed-off-by: Yong Cong Sin <ycsin@meta.com> Signed-off-by: Yong Cong Sin <yongcong.sin@gmail.com>
This commit is contained in:
parent
665da7354b
commit
e3c2e8484f
1 changed files with 82 additions and 72 deletions
|
@ -190,8 +190,7 @@ static void shell_tdata_dump(const struct k_thread *cthread, void *user_data)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cmd_kernel_threads(const struct shell *sh,
|
static int cmd_kernel_thread_list(const struct shell *sh, size_t argc, char **argv)
|
||||||
size_t argc, char **argv)
|
|
||||||
{
|
{
|
||||||
ARG_UNUSED(argc);
|
ARG_UNUSED(argc);
|
||||||
ARG_UNUSED(argv);
|
ARG_UNUSED(argv);
|
||||||
|
@ -208,66 +207,6 @@ static int cmd_kernel_threads(const struct shell *sh,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_ARCH_STACKWALK)
|
|
||||||
|
|
||||||
static bool print_trace_address(void *arg, unsigned long ra)
|
|
||||||
{
|
|
||||||
const struct shell *sh = arg;
|
|
||||||
#ifdef CONFIG_SYMTAB
|
|
||||||
uint32_t offset = 0;
|
|
||||||
const char *name = symtab_find_symbol_name(ra, &offset);
|
|
||||||
|
|
||||||
shell_print(sh, "ra: %p [%s+0x%x]", (void *)ra, name, offset);
|
|
||||||
#else
|
|
||||||
shell_print(sh, "ra: %p", (void *)ra);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct unwind_entry {
|
|
||||||
const struct k_thread *const thread;
|
|
||||||
bool valid;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void is_valid_thread(const struct k_thread *cthread, void *user_data)
|
|
||||||
{
|
|
||||||
struct unwind_entry *entry = user_data;
|
|
||||||
|
|
||||||
if (cthread == entry->thread) {
|
|
||||||
entry->valid = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cmd_kernel_unwind(const struct shell *sh, size_t argc, char **argv)
|
|
||||||
{
|
|
||||||
struct k_thread *thread;
|
|
||||||
|
|
||||||
if (argc == 1) {
|
|
||||||
thread = _current;
|
|
||||||
} else {
|
|
||||||
thread = UINT_TO_POINTER(strtoll(argv[1], NULL, 16));
|
|
||||||
struct unwind_entry entry = {
|
|
||||||
.thread = thread,
|
|
||||||
.valid = false,
|
|
||||||
};
|
|
||||||
|
|
||||||
k_thread_foreach_unlocked(is_valid_thread, &entry);
|
|
||||||
|
|
||||||
if (!entry.valid) {
|
|
||||||
shell_error(sh, "Invalid thread id %p", (void *)thread);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
shell_print(sh, "Unwinding %p %s", (void *)thread, thread->name);
|
|
||||||
|
|
||||||
arch_stack_walk(print_trace_address, (void *)sh, thread, NULL);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* CONFIG_ARCH_STACKWALK */
|
|
||||||
|
|
||||||
static void shell_stack_dump(const struct k_thread *thread, void *user_data)
|
static void shell_stack_dump(const struct k_thread *thread, void *user_data)
|
||||||
{
|
{
|
||||||
const struct shell *sh = (const struct shell *)user_data;
|
const struct shell *sh = (const struct shell *)user_data;
|
||||||
|
@ -299,8 +238,7 @@ static void shell_stack_dump(const struct k_thread *thread, void *user_data)
|
||||||
K_KERNEL_STACK_ARRAY_DECLARE(z_interrupt_stacks, CONFIG_MP_MAX_NUM_CPUS,
|
K_KERNEL_STACK_ARRAY_DECLARE(z_interrupt_stacks, CONFIG_MP_MAX_NUM_CPUS,
|
||||||
CONFIG_ISR_STACK_SIZE);
|
CONFIG_ISR_STACK_SIZE);
|
||||||
|
|
||||||
static int cmd_kernel_stacks(const struct shell *sh,
|
static int cmd_kernel_thread_stacks(const struct shell *sh, size_t argc, char **argv)
|
||||||
size_t argc, char **argv)
|
|
||||||
{
|
{
|
||||||
ARG_UNUSED(argc);
|
ARG_UNUSED(argc);
|
||||||
ARG_UNUSED(argv);
|
ARG_UNUSED(argv);
|
||||||
|
@ -337,8 +275,87 @@ static int cmd_kernel_stacks(const struct shell *sh,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_INIT_STACKS & CONFIG_THREAD_STACK_INFO & CONFIG_THREAD_MONITOR */
|
||||||
|
|
||||||
|
struct thread_entry {
|
||||||
|
const struct k_thread *const thread;
|
||||||
|
bool valid;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void thread_valid_cb(const struct k_thread *cthread, void *user_data)
|
||||||
|
{
|
||||||
|
struct thread_entry *entry = user_data;
|
||||||
|
|
||||||
|
if (cthread == entry->thread) {
|
||||||
|
entry->valid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__maybe_unused
|
||||||
|
static bool thread_is_valid(const struct k_thread *thread)
|
||||||
|
{
|
||||||
|
struct thread_entry entry = {
|
||||||
|
.thread = thread,
|
||||||
|
.valid = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
k_thread_foreach(thread_valid_cb, &entry);
|
||||||
|
|
||||||
|
return entry.valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_ARCH_STACKWALK)
|
||||||
|
|
||||||
|
static bool print_trace_address(void *arg, unsigned long ra)
|
||||||
|
{
|
||||||
|
const struct shell *sh = arg;
|
||||||
|
#ifdef CONFIG_SYMTAB
|
||||||
|
uint32_t offset = 0;
|
||||||
|
const char *name = symtab_find_symbol_name(ra, &offset);
|
||||||
|
|
||||||
|
shell_print(sh, "ra: %p [%s+0x%x]", (void *)ra, name, offset);
|
||||||
|
#else
|
||||||
|
shell_print(sh, "ra: %p", (void *)ra);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_kernel_thread_unwind(const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
struct k_thread *thread;
|
||||||
|
|
||||||
|
if (argc == 1) {
|
||||||
|
thread = _current;
|
||||||
|
} else {
|
||||||
|
thread = UINT_TO_POINTER(strtoll(argv[1], NULL, 16));
|
||||||
|
|
||||||
|
if (!thread_is_valid(thread)) {
|
||||||
|
shell_error(sh, "Invalid thread id %p", (void *)thread);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shell_print(sh, "Unwinding %p %s", (void *)thread, thread->name);
|
||||||
|
|
||||||
|
arch_stack_walk(print_trace_address, (void *)sh, thread, NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_ARCH_STACKWALK */
|
||||||
|
|
||||||
|
SHELL_STATIC_SUBCMD_SET_CREATE(sub_kernel_thread,
|
||||||
|
#if defined(CONFIG_INIT_STACKS) && defined(CONFIG_THREAD_STACK_INFO) && \
|
||||||
|
defined(CONFIG_THREAD_MONITOR)
|
||||||
|
SHELL_CMD(stacks, NULL, "List threads stack usage.", cmd_kernel_thread_stacks),
|
||||||
|
SHELL_CMD(list, NULL, "List kernel threads.", cmd_kernel_thread_list),
|
||||||
|
#endif
|
||||||
|
#if defined(CONFIG_ARCH_STACKWALK)
|
||||||
|
SHELL_CMD_ARG(unwind, NULL, "Unwind a thread.", cmd_kernel_thread_unwind, 1, 1),
|
||||||
|
#endif /* CONFIG_ARCH_STACKWALK */
|
||||||
|
SHELL_SUBCMD_SET_END /* Array terminated. */
|
||||||
|
);
|
||||||
|
|
||||||
#if defined(CONFIG_SYS_HEAP_RUNTIME_STATS) && (K_HEAP_MEM_POOL_SIZE > 0)
|
#if defined(CONFIG_SYS_HEAP_RUNTIME_STATS) && (K_HEAP_MEM_POOL_SIZE > 0)
|
||||||
extern struct sys_heap _system_heap;
|
extern struct sys_heap _system_heap;
|
||||||
|
|
||||||
|
@ -458,14 +475,7 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sub_kernel,
|
||||||
#if defined(CONFIG_REBOOT)
|
#if defined(CONFIG_REBOOT)
|
||||||
SHELL_CMD(reboot, &sub_kernel_reboot, "Reboot.", NULL),
|
SHELL_CMD(reboot, &sub_kernel_reboot, "Reboot.", NULL),
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_INIT_STACKS) && defined(CONFIG_THREAD_STACK_INFO) && \
|
SHELL_CMD(thread, &sub_kernel_thread, "Kernel threads.", NULL),
|
||||||
defined(CONFIG_THREAD_MONITOR)
|
|
||||||
SHELL_CMD(stacks, NULL, "List threads stack usage.", cmd_kernel_stacks),
|
|
||||||
SHELL_CMD(threads, NULL, "List kernel threads.", cmd_kernel_threads),
|
|
||||||
#if defined(CONFIG_ARCH_STACKWALK)
|
|
||||||
SHELL_CMD_ARG(unwind, NULL, "Unwind a thread.", cmd_kernel_unwind, 1, 1),
|
|
||||||
#endif /* CONFIG_ARCH_STACKWALK */
|
|
||||||
#endif
|
|
||||||
#if defined(CONFIG_SYS_HEAP_RUNTIME_STATS) && (K_HEAP_MEM_POOL_SIZE > 0)
|
#if defined(CONFIG_SYS_HEAP_RUNTIME_STATS) && (K_HEAP_MEM_POOL_SIZE > 0)
|
||||||
SHELL_CMD(heap, NULL, "System heap usage statistics.", cmd_kernel_heap),
|
SHELL_CMD(heap, NULL, "System heap usage statistics.", cmd_kernel_heap),
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue