Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 62 additions & 7 deletions src/kservice.c
Original file line number Diff line number Diff line change
Expand Up @@ -747,10 +747,64 @@ rt_uint8_t rt_thread_get_usage(rt_thread_t thread)
#if defined(RT_USING_LIBC) && defined(RT_USING_FINSH)
#include <stdlib.h> /* for string service */

static void cmd_backtrace(int argc, char** argv)
struct cmd_backtrace_find_ctx
{
rt_uintptr_t pid;
rt_thread_t thread;
};

static rt_err_t cmd_backtrace_match_thread(struct rt_object *object, void *data)
{
struct cmd_backtrace_find_ctx *ctx = data;

if ((rt_uintptr_t)object == ctx->pid)
{
ctx->thread = (rt_thread_t)object;

return 1;
}

return RT_EOK;
}

static rt_bool_t cmd_backtrace_parse_pid(const char *arg, rt_uintptr_t *pid)
{
char *end_ptr;
rt_uintptr_t value;

if ((arg == RT_NULL) || (pid == RT_NULL))
{
return RT_FALSE;
}

value = (rt_uintptr_t)strtoul(arg, &end_ptr, 0);
if ((end_ptr == arg) || (*end_ptr != '\0') || (value == 0))
{
return RT_FALSE;
}

*pid = value;

return RT_TRUE;
}

static rt_thread_t cmd_backtrace_find_thread(rt_uintptr_t pid)
{
struct cmd_backtrace_find_ctx ctx =
{
.pid = pid,
.thread = RT_NULL,
};

rt_object_for_each(RT_Object_Class_Thread, cmd_backtrace_match_thread, &ctx);

return ctx.thread;
}

static void cmd_backtrace(int argc, char** argv)
{
rt_uintptr_t pid;
rt_thread_t target;

if (argc != 2)
{
Expand All @@ -770,21 +824,22 @@ static void cmd_backtrace(int argc, char** argv)
}
}

pid = strtoul(argv[1], &end_ptr, 0);
if (end_ptr == argv[1])
if (!cmd_backtrace_parse_pid(argv[1], &pid))
{
rt_kprintf("Invalid input: %s\n", argv[1]);
return ;
}

if (pid && rt_object_get_type((void *)pid) == RT_Object_Class_Thread)
target = cmd_backtrace_find_thread(pid);
if (target != RT_NULL)
{
rt_thread_t target = (rt_thread_t)pid;
rt_kprintf("backtrace %s(0x%lx), from %s\n", target->parent.name, pid, argv[1]);
rt_kprintf("backtrace %s(0x%lx), from %s\n", target->parent.name, (unsigned long)pid, argv[1]);
rt_backtrace_thread(target);
}
else
rt_kprintf("Invalid pid: %ld\n", pid);
{
rt_kprintf("Invalid pid: %lx\n", (unsigned long)pid);
}
}
MSH_CMD_EXPORT_ALIAS(cmd_backtrace, backtrace, print backtrace of a thread);

Expand Down
Loading