Skip to content

Commit

Permalink
sched_backtrace: fix when dump running thread in other-core
Browse files Browse the repository at this point in the history
Signed-off-by: hujun5 <[email protected]>
  • Loading branch information
hujun260 committed Oct 12, 2024
1 parent 6e12b3d commit 177e9e8
Showing 1 changed file with 100 additions and 8 deletions.
108 changes: 100 additions & 8 deletions sched/sched/sched_backtrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,64 @@
****************************************************************************/

#include <nuttx/config.h>
#include <nuttx/sched.h>
#include <nuttx/init.h>

#include "sched.h"

#ifdef CONFIG_ARCH_HAVE_BACKTRACE

/****************************************************************************
* Private Type Declarations
****************************************************************************/

#ifdef CONFIG_SMP
struct backtrace_arg_s
{
pid_t pid;
FAR void **buffer;
int size;
int skip;
cpu_set_t saved_affinity;
uint16_t saved_flags;
bool need_restore;
};

/****************************************************************************
* Private Functions
****************************************************************************/

static int sched_backtrace_handler(FAR void *cookie)
{
FAR struct backtrace_arg_s *arg = cookie;
FAR struct tcb_s *tcb;
irqstate_t flags;

flags = enter_critical_section();

tcb = nxsched_get_tcb(arg->pid);

if (!tcb || tcb->task_state == TSTATE_TASK_INVALID ||
(tcb->flags & TCB_FLAG_EXIT_PROCESSING) != 0)
{
/* There is no TCB with this pid or, if there is, it is not a task. */

leave_critical_section(flags);
return -ESRCH;
}

if (arg->need_restore)
{
tcb->affinity = arg->saved_affinity;
tcb->flags = arg->saved_flags;
}

leave_critical_section(flags);

return up_backtrace(tcb, arg->buffer, arg->size, arg->skip);
}
#endif

/****************************************************************************
* Public Functions
****************************************************************************/
Expand All @@ -42,19 +97,56 @@
*
****************************************************************************/

#ifdef CONFIG_ARCH_HAVE_BACKTRACE
int sched_backtrace(pid_t tid, FAR void **buffer, int size, int skip)
{
FAR struct tcb_s *rtcb;
irqstate_t flags;
FAR struct tcb_s *tcb = this_task();
int ret = 0;
if (tid >= 0)

if (tcb->pid == tid)
{
flags = enter_critical_section();
rtcb = nxsched_get_tcb(tid);
if (rtcb != NULL)
ret = up_backtrace(tcb, buffer, size, skip);
}
else
{
irqstate_t flags = enter_critical_section();

tcb = nxsched_get_tcb(tid);
if (tcb != NULL)
{
ret = up_backtrace(rtcb, buffer, size, skip);
#ifdef CONFIG_SMP
if (tcb->task_state == TSTATE_TASK_RUNNING &&
g_nx_initstate != OSINIT_PANIC)
{
struct backtrace_arg_s arg;

if ((tcb->flags & TCB_FLAG_CPU_LOCKED) != 0)
{
arg.pid = tcb->pid;
arg.need_restore = false;
}
else
{
arg.pid = tcb->pid;
arg.saved_flags = tcb->flags;
arg.saved_affinity = tcb->affinity;
arg.need_restore = true;

tcb->flags |= TCB_FLAG_CPU_LOCKED;
CPU_SET(tcb->cpu, &tcb->affinity);
}

arg.buffer = buffer;
arg.size = size;
arg.skip = skip;
ret = nxsched_smp_call_single(tcb->cpu,
sched_backtrace_handler,
&arg, true);
}
else
#endif
{
ret = up_backtrace(tcb, buffer, size, skip);
}
}

leave_critical_section(flags);
Expand Down

0 comments on commit 177e9e8

Please sign in to comment.