You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ar...@apache.org on 2021/12/29 04:10:04 UTC
[incubator-nuttx] 03/03: sched/backtrace: Dump the complete stack regardless the depth
This is an automated email from the ASF dual-hosted git repository.
archer pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit dd942f0b0401f68df746ae067707a2460f3f7199
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Fri Dec 24 15:38:14 2021 +0800
sched/backtrace: Dump the complete stack regardless the depth
Signed-off-by: Xiang Xiao <xi...@xiaomi.com>
---
arch/arm/src/common/arm_backtrace_fp.c | 27 ++++++++-----
arch/arm/src/common/arm_backtrace_thumb.c | 54 +++++++++++++++++--------
arch/risc-v/src/common/riscv_backtrace.c | 31 +++++++++------
arch/xtensa/src/common/xtensa_backtrace.c | 66 +++++++++++++++++++------------
include/execinfo.h | 4 +-
include/nuttx/arch.h | 4 +-
include/sched.h | 2 +-
include/sys/syscall_lookup.h | 2 +-
libs/libc/sched/sched_backtrace.c | 10 ++---
libs/libc/sched/sched_dumpstack.c | 56 ++++++++++++++------------
sched/sched/sched_backtrace.c | 4 +-
syscall/syscall.csv | 2 +-
12 files changed, 160 insertions(+), 102 deletions(-)
diff --git a/arch/arm/src/common/arm_backtrace_fp.c b/arch/arm/src/common/arm_backtrace_fp.c
index 8d4d4f7..c9373ec 100644
--- a/arch/arm/src/common/arm_backtrace_fp.c
+++ b/arch/arm/src/common/arm_backtrace_fp.c
@@ -49,13 +49,17 @@ __attribute__((no_sanitize_address))
#endif
static int backtrace(FAR uintptr_t *base, FAR uintptr_t *limit,
FAR uintptr_t *fp, FAR uintptr_t *pc,
- FAR void **buffer, int size)
+ FAR void **buffer, int size, FAR int *skip)
{
int i = 0;
if (pc)
{
- buffer[i++] = pc;
+ i++;
+ if (*skip-- <= 0)
+ {
+ *buffer++ = pc;
+ }
}
for (; i < size; fp = (FAR uintptr_t *)*(fp - 1), i++)
@@ -65,7 +69,10 @@ static int backtrace(FAR uintptr_t *base, FAR uintptr_t *limit,
break;
}
- buffer[i] = (FAR void *)*fp;
+ if (*skip-- <= 0)
+ {
+ *buffer++ = (FAR void *)*fp;
+ }
}
return i;
@@ -93,6 +100,7 @@ static int backtrace(FAR uintptr_t *base, FAR uintptr_t *limit,
* tcb - Address of the task's TCB
* buffer - Return address from the corresponding stack frame
* size - Maximum number of addresses that can be stored in buffer
+ * skip - number of addresses to be skipped
*
* Returned Value:
* up_backtrace() returns the number of addresses returned in buffer
@@ -102,7 +110,8 @@ static int backtrace(FAR uintptr_t *base, FAR uintptr_t *limit,
#ifdef CONFIG_MM_KASAN
__attribute__((no_sanitize_address))
#endif
-int up_backtrace(FAR struct tcb_s *tcb, FAR void **buffer, int size)
+int up_backtrace(FAR struct tcb_s *tcb,
+ FAR void **buffer, int size, int skip)
{
FAR struct tcb_s *rtcb = running_task();
#if CONFIG_ARCH_INTERRUPTSTACK > 7
@@ -129,12 +138,12 @@ int up_backtrace(FAR struct tcb_s *tcb, FAR void **buffer, int size)
ret = backtrace(istacklimit - (CONFIG_ARCH_INTERRUPTSTACK & ~7),
istacklimit,
(FAR void *)__builtin_frame_address(0),
- NULL, buffer, size);
+ NULL, buffer, size, &skip);
#else
ret = backtrace(rtcb->stack_base_ptr,
rtcb->stack_base_ptr + rtcb->adj_stack_size,
(FAR void *)__builtin_frame_address(0),
- NULL, buffer, size);
+ NULL, buffer, size, &skip);
#endif /* CONFIG_ARCH_INTERRUPTSTACK > 7 */
if (ret < size)
{
@@ -142,7 +151,7 @@ int up_backtrace(FAR struct tcb_s *tcb, FAR void **buffer, int size)
rtcb->stack_base_ptr + rtcb->adj_stack_size,
(FAR void *)CURRENT_REGS[REG_FP],
(FAR void *)CURRENT_REGS[REG_PC],
- &buffer[ret], size - ret);
+ &buffer[ret], size - ret, &skip);
}
}
else
@@ -150,7 +159,7 @@ int up_backtrace(FAR struct tcb_s *tcb, FAR void **buffer, int size)
ret = backtrace(rtcb->stack_base_ptr,
rtcb->stack_base_ptr + rtcb->adj_stack_size,
(FAR void *)__builtin_frame_address(0),
- NULL, buffer, size);
+ NULL, buffer, size, &skip);
}
}
else
@@ -161,7 +170,7 @@ int up_backtrace(FAR struct tcb_s *tcb, FAR void **buffer, int size)
tcb->stack_base_ptr + tcb->adj_stack_size,
(FAR void *)tcb->xcp.regs[REG_FP],
(FAR void *)tcb->xcp.regs[REG_PC],
- buffer, size);
+ buffer, size, &skip);
leave_critical_section(flags);
}
diff --git a/arch/arm/src/common/arm_backtrace_thumb.c b/arch/arm/src/common/arm_backtrace_thumb.c
index ea766b0..83265c5 100644
--- a/arch/arm/src/common/arm_backtrace_thumb.c
+++ b/arch/arm/src/common/arm_backtrace_thumb.c
@@ -316,10 +316,10 @@ static FAR void *backtrace_push_internal(FAR void **psp,
#ifdef CONFIG_MM_KASAN
__attribute__((no_sanitize_address))
#endif
-static int backtrace_push(FAR void *limit, FAR void **sp,
- FAR void *pc, FAR void **buffer, int size)
+static int backtrace_push(FAR void *limit, FAR void **sp, FAR void *pc,
+ FAR void **buffer, int size, FAR int *skip)
{
- int i = 0;
+ int i = 1;
if (!in_code_region(pc))
{
@@ -328,7 +328,10 @@ static int backtrace_push(FAR void *limit, FAR void **sp,
pc = (uintptr_t)pc & 0xfffffffe;
- buffer[i++] = pc;
+ if (*skip-- <= 0)
+ {
+ *buffer++ = pc;
+ }
for (; i < size; i++)
{
@@ -337,11 +340,21 @@ static int backtrace_push(FAR void *limit, FAR void **sp,
break;
}
- buffer[i] = backtrace_push_internal(sp, &pc);
- if (!buffer[i])
+ pc = backtrace_push_internal(sp, &pc);
+ if (!pc)
{
break;
}
+
+ if (*skip-- <= 0)
+ {
+ *buffer++ = pc;
+ }
+
+ if (ip)
+ {
+ ip = NULL;
+ }
}
return i;
@@ -359,7 +372,7 @@ static int backtrace_push(FAR void *limit, FAR void **sp,
__attribute__((no_sanitize_address))
#endif
static int backtrace_branch(FAR void *limit, FAR void *sp,
- FAR void **buffer, int size)
+ FAR void **buffer, int size, FAR int *skip)
{
uint16_t ins16;
uint32_t addr;
@@ -377,7 +390,11 @@ static int backtrace_branch(FAR void *limit, FAR void *sp,
ins16 = *(FAR uint16_t *)addr;
if (INSTR_IS(ins16, T_BLX))
{
- buffer[i++] = addr;
+ i++;
+ if (*skip-- <= 0)
+ {
+ *buffer++ = addr;
+ }
}
/* BL Instruction
@@ -393,7 +410,11 @@ static int backtrace_branch(FAR void *limit, FAR void *sp,
ins16 = *(FAR uint16_t *)addr;
if (INSTR_IS(ins16, T_BL))
{
- buffer[i++] = addr;
+ i++;
+ if (*skip-- <= 0)
+ {
+ *buffer++ = addr;
+ }
}
}
}
@@ -468,7 +489,8 @@ void up_backtrace_init_code_regions(FAR void **regions)
#ifdef CONFIG_MM_KASAN
__attribute__((no_sanitize_address))
#endif
-int up_backtrace(FAR struct tcb_s *tcb, FAR void **buffer, int size)
+int up_backtrace(FAR struct tcb_s *tcb,
+ FAR void **buffer, int size, FAR int skip)
{
FAR struct tcb_s *rtcb = running_task();
irqstate_t flags;
@@ -504,7 +526,7 @@ int up_backtrace(FAR struct tcb_s *tcb, FAR void **buffer, int size)
ret = backtrace_push(rtcb->stack_base_ptr +
rtcb->adj_stack_size,
&sp, (FAR void *)up_backtrace + 10,
- buffer, size);
+ buffer, size, &skip);
#endif
if (ret < size)
{
@@ -512,7 +534,7 @@ int up_backtrace(FAR struct tcb_s *tcb, FAR void **buffer, int size)
ret += backtrace_push(rtcb->stack_base_ptr +
rtcb->adj_stack_size, &sp,
(FAR void *)CURRENT_REGS[REG_PC],
- &buffer[ret], size - ret);
+ &buffer[ret], size - ret, &skip);
}
}
else
@@ -520,14 +542,14 @@ int up_backtrace(FAR struct tcb_s *tcb, FAR void **buffer, int size)
ret = backtrace_push(rtcb->stack_base_ptr +
rtcb->adj_stack_size, &sp,
(FAR void *)up_backtrace + 10,
- buffer, size);
+ buffer, size, &skip);
}
if (ret < size)
{
ret += backtrace_branch(rtcb->stack_base_ptr +
rtcb->adj_stack_size, sp,
- &buffer[ret], size - ret);
+ &buffer[ret], size - ret, &skip);
}
}
else
@@ -544,13 +566,13 @@ int up_backtrace(FAR struct tcb_s *tcb, FAR void **buffer, int size)
ret += backtrace_push(tcb->stack_base_ptr +
tcb->adj_stack_size, &sp,
(FAR void *)tcb->xcp.regs[REG_LR],
- &buffer[ret], size - ret);
+ &buffer[ret], size - ret, &skip);
if (ret < size)
{
ret += backtrace_branch(tcb->stack_base_ptr +
tcb->adj_stack_size, sp,
- &buffer[ret], size - ret);
+ &buffer[ret], size - ret, &skip);
}
}
diff --git a/arch/risc-v/src/common/riscv_backtrace.c b/arch/risc-v/src/common/riscv_backtrace.c
index f328325..007815b 100644
--- a/arch/risc-v/src/common/riscv_backtrace.c
+++ b/arch/risc-v/src/common/riscv_backtrace.c
@@ -63,13 +63,17 @@ static inline uintptr_t getfp(void)
static int backtrace(uintptr_t *base, uintptr_t *limit,
uintptr_t *fp, uintptr_t *ra,
- void **buffer, int size)
+ void **buffer, int size, int *skip)
{
int i = 0;
if (ra)
{
- buffer[i++] = ra;
+ i++;
+ if (*skip-- <= 0)
+ {
+ *buffer++ = ra;
+ }
}
for (; i < size; fp = (uintptr_t *)*(fp - 2), i++)
@@ -85,7 +89,10 @@ static int backtrace(uintptr_t *base, uintptr_t *limit,
break;
}
- buffer[i] = ra;
+ if (*skip-- <= 0)
+ {
+ *buffer++ = ra;
+ }
}
return i;
@@ -113,13 +120,14 @@ static int backtrace(uintptr_t *base, uintptr_t *limit,
* tcb - Address of the task's TCB
* buffer - Return address from the corresponding stack frame
* size - Maximum number of addresses that can be stored in buffer
+ * skip - number of addresses to be skipped
*
* Returned Value:
* up_backtrace() returns the number of addresses returned in buffer
*
****************************************************************************/
-int up_backtrace(struct tcb_s *tcb, void **buffer, int size)
+int up_backtrace(struct tcb_s *tcb, void **buffer, int size, int skip)
{
struct tcb_s *rtcb = running_task();
irqstate_t flags;
@@ -137,28 +145,27 @@ int up_backtrace(struct tcb_s *tcb, void **buffer, int size)
#if CONFIG_ARCH_INTERRUPTSTACK > 15
ret = backtrace((void *)&g_intstackalloc,
(void *)((uint32_t)&g_intstackalloc +
- CONFIG_ARCH_INTERRUPTSTACK),
- (void *)getfp(), NULL, buffer, size);
+ CONFIG_ARCH_INTERRUPTSTACK),
+ (void *)getfp(), NULL, buffer, size, &skip);
#else
ret = backtrace(rtcb->stack_base_ptr,
rtcb->stack_base_ptr + rtcb->adj_stack_size,
- (void *)getfp(), NULL, buffer, size);
+ (void *)getfp(), NULL, buffer, size, &skip);
#endif
if (ret < size)
{
ret += backtrace(rtcb->stack_base_ptr,
- rtcb->stack_base_ptr +
- rtcb->adj_stack_size,
+ rtcb->stack_base_ptr + rtcb->adj_stack_size,
(void *)CURRENT_REGS[REG_FP],
(void *)CURRENT_REGS[REG_EPC],
- &buffer[ret], size - ret);
+ &buffer[ret], size - ret, &skip);
}
}
else
{
ret = backtrace(rtcb->stack_base_ptr,
rtcb->stack_base_ptr + rtcb->adj_stack_size,
- (void *)getfp(), NULL, buffer, size);
+ (void *)getfp(), NULL, buffer, size, &skip);
}
}
else
@@ -169,7 +176,7 @@ int up_backtrace(struct tcb_s *tcb, void **buffer, int size)
tcb->stack_base_ptr + tcb->adj_stack_size,
(void *)tcb->xcp.regs[REG_FP],
(void *)tcb->xcp.regs[REG_EPC],
- buffer, size);
+ buffer, size, &skip);
leave_critical_section(flags);
}
diff --git a/arch/xtensa/src/common/xtensa_backtrace.c b/arch/xtensa/src/common/xtensa_backtrace.c
index 3a6cc89..54b529f 100644
--- a/arch/xtensa/src/common/xtensa_backtrace.c
+++ b/arch/xtensa/src/common/xtensa_backtrace.c
@@ -106,8 +106,8 @@ static void get_window_regs(struct xtensa_windowregs_s *frame)
#ifndef __XTENSA_CALL0_ABI__
static int backtrace_window(uintptr_t *base, uintptr_t *limit,
- struct xtensa_windowregs_s *frame,
- void **buffer, int size)
+ struct xtensa_windowregs_s *frame,
+ void **buffer, int size, int *skip)
{
uint32_t windowstart;
uint32_t ra;
@@ -136,7 +136,11 @@ static int backtrace_window(uintptr_t *base, uintptr_t *limit,
continue;
}
- buffer[i++] = MAKE_PC_FROM_RA(ra);
+ i++;
+ if (*skip-- <= 0)
+ {
+ *buffer++ = MAKE_PC_FROM_RA(ra);
+ }
}
}
@@ -153,14 +157,18 @@ static int backtrace_window(uintptr_t *base, uintptr_t *limit,
****************************************************************************/
static int backtrace_stack(uintptr_t *base, uintptr_t *limit,
- uintptr_t *sp, uintptr_t *ra,
- void **buffer, int size)
+ uintptr_t *sp, uintptr_t *ra,
+ void **buffer, int size, int *skip)
{
int i = 0;
if (ra)
{
- buffer[i++] = MAKE_PC_FROM_RA((uintptr_t)ra);
+ i++;
+ if (*skip-- <= 0)
+ {
+ *buffer++ = MAKE_PC_FROM_RA((uintptr_t)ra);
+ }
}
for (; i < size; sp = (uintptr_t *)*(sp - 3), i++)
@@ -176,7 +184,10 @@ static int backtrace_stack(uintptr_t *base, uintptr_t *limit,
break;
}
- buffer[i] = MAKE_PC_FROM_RA((uintptr_t)ra);
+ if (*skip-- <= 0)
+ {
+ *buffer++ = MAKE_PC_FROM_RA((uintptr_t)ra);
+ }
}
return i;
@@ -204,13 +215,14 @@ static int backtrace_stack(uintptr_t *base, uintptr_t *limit,
* tcb - Address of the task's TCB
* buffer - Return address from the corresponding stack frame
* size - Maximum number of addresses that can be stored in buffer
+ * skip - number of addresses to be skipped
*
* Returned Value:
* up_backtrace() returns the number of addresses returned in buffer
*
****************************************************************************/
-int up_backtrace(struct tcb_s *tcb, void **buffer, int size)
+int up_backtrace(struct tcb_s *tcb, void **buffer, int size, int skip)
{
struct tcb_s *rtcb = running_task();
irqstate_t flags;
@@ -235,20 +247,21 @@ int up_backtrace(struct tcb_s *tcb, void **buffer, int size)
xtensa_window_spill();
ret = backtrace_stack((void *)istackbase,
- (void *)(istackbase +
- CONFIG_ARCH_INTERRUPTSTACK),
- (void *)up_getsp(), NULL, buffer, size);
+ (void *)(istackbase +
+ CONFIG_ARCH_INTERRUPTSTACK),
+ (void *)up_getsp(), NULL,
+ buffer, size, &skip);
#else
ret = backtrace_stack(rtcb->stack_base_ptr,
- rtcb->stack_base_ptr + rtcb->adj_stack_size,
- (void *)up_getsp(), NULL, buffer, size);
+ rtcb->stack_base_ptr + rtcb->adj_stack_size,
+ (void *)up_getsp(), NULL,
+ buffer, size, &skip);
#endif
ret += backtrace_stack(rtcb->stack_base_ptr,
- rtcb->stack_base_ptr +
- rtcb->adj_stack_size,
- (void *)CURRENT_REGS[REG_A1],
- (void *)CURRENT_REGS[REG_A0],
- &buffer[ret], size - ret);
+ rtcb->stack_base_ptr + rtcb->adj_stack_size,
+ (void *)CURRENT_REGS[REG_A1],
+ (void *)CURRENT_REGS[REG_A0],
+ &buffer[ret], size - ret, &skip);
}
else
{
@@ -268,12 +281,13 @@ int up_backtrace(struct tcb_s *tcb, void **buffer, int size)
get_window_regs(&frame);
ret = backtrace_window(rtcb->stack_base_ptr,
- rtcb->stack_base_ptr + rtcb->adj_stack_size,
- &frame, buffer, size);
+ rtcb->stack_base_ptr + rtcb->adj_stack_size,
+ &frame, buffer, size, &skip);
#endif
ret += backtrace_stack(rtcb->stack_base_ptr,
- rtcb->stack_base_ptr + rtcb->adj_stack_size,
- (void *)up_getsp(), NULL, buffer, size - ret);
+ rtcb->stack_base_ptr + rtcb->adj_stack_size,
+ (void *)up_getsp(), NULL,
+ buffer, size - ret, &skip);
}
}
else
@@ -283,10 +297,10 @@ int up_backtrace(struct tcb_s *tcb, void **buffer, int size)
flags = enter_critical_section();
ret = backtrace_stack(tcb->stack_base_ptr,
- tcb->stack_base_ptr + tcb->adj_stack_size,
- (void *)tcb->xcp.regs[REG_A1],
- (void *)tcb->xcp.regs[REG_A0],
- buffer, size);
+ tcb->stack_base_ptr + tcb->adj_stack_size,
+ (void *)tcb->xcp.regs[REG_A1],
+ (void *)tcb->xcp.regs[REG_A0],
+ buffer, size, &skip);
leave_critical_section(flags);
}
diff --git a/include/execinfo.h b/include/execinfo.h
index 6380eaf..30e56cd 100644
--- a/include/execinfo.h
+++ b/include/execinfo.h
@@ -38,8 +38,8 @@
* ARRAY and return the exact number of values stored.
*/
-#define backtrace(buffer, size) sched_backtrace(gettid(), buffer, size)
-#define dump_stack() sched_dumpstack(gettid())
+# define backtrace(buffer, size) sched_backtrace(gettid(), buffer, size, 0)
+# define dump_stack() sched_dumpstack(gettid())
#else
# define backtrace(buffer, size) 0
diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h
index e7e2f36..ca4b6cb 100644
--- a/include/nuttx/arch.h
+++ b/include/nuttx/arch.h
@@ -513,13 +513,15 @@ void up_assert(FAR const char *filename, int linenum);
* tcb - Address of the task's TCB, NULL means dump the running task
* buffer - Return address from the corresponding stack frame
* size - Maximum number of addresses that can be stored in buffer
+ * skip - number of addresses to be skipped
*
* Returned Value:
* up_backtrace() returns the number of addresses returned in buffer
*
****************************************************************************/
-int up_backtrace(FAR struct tcb_s *tcb, FAR void **buffer, int size);
+int up_backtrace(FAR struct tcb_s *tcb,
+ FAR void **buffer, int size, int skip);
#endif /* CONFIG_ARCH_HAVE_BACKTRACE */
/****************************************************************************
diff --git a/include/sched.h b/include/sched.h
index 842ce4d..f3cbcd9 100644
--- a/include/sched.h
+++ b/include/sched.h
@@ -264,7 +264,7 @@ bool sched_idletask(void);
/* Task Backtrace */
-int sched_backtrace(pid_t tid, FAR void **buffer, int size);
+int sched_backtrace(pid_t tid, FAR void **buffer, int size, int skip);
void sched_dumpstack(pid_t tid);
#undef EXTERN
diff --git a/include/sys/syscall_lookup.h b/include/sys/syscall_lookup.h
index 8b4e0a1..47310c2 100644
--- a/include/sys/syscall_lookup.h
+++ b/include/sys/syscall_lookup.h
@@ -45,7 +45,7 @@ SYSCALL_LOOKUP(sched_yield, 0)
SYSCALL_LOOKUP(nxsched_get_stackinfo, 2)
#ifdef CONFIG_SCHED_BACKTRACE
- SYSCALL_LOOKUP(sched_backtrace, 3)
+ SYSCALL_LOOKUP(sched_backtrace, 4)
#endif
#ifdef CONFIG_SMP
diff --git a/libs/libc/sched/sched_backtrace.c b/libs/libc/sched/sched_backtrace.c
index 5c35bda..9e27d1f 100644
--- a/libs/libc/sched/sched_backtrace.c
+++ b/libs/libc/sched/sched_backtrace.c
@@ -64,7 +64,7 @@ backtrace_helper(FAR struct _Unwind_Context *ctx, FAR void *a)
* Skip it.
*/
- if (arg->cnt != -1)
+ if (arg->cnt >= 0)
{
arg->array[arg->cnt] = (FAR void *)_Unwind_GetIP(ctx);
if (arg->cnt > 0)
@@ -88,7 +88,7 @@ backtrace_helper(FAR struct _Unwind_Context *ctx, FAR void *a)
arg->cfa = cfa;
}
- if (++arg->cnt == arg->size)
+ if (++arg->cnt >= arg->size)
{
return _URC_END_OF_STACK;
}
@@ -108,7 +108,7 @@ backtrace_helper(FAR struct _Unwind_Context *ctx, FAR void *a)
*
****************************************************************************/
-int sched_backtrace(pid_t tid, FAR void **buffer, int size)
+int sched_backtrace(pid_t tid, FAR void **buffer, int size, int skip)
{
struct trace_arg arg;
@@ -120,7 +120,7 @@ int sched_backtrace(pid_t tid, FAR void **buffer, int size)
arg.array = buffer;
arg.cfa = 0;
arg.size = size;
- arg.cnt = -1;
+ arg.cnt = -skip - 1;
if (size <= 0)
{
@@ -138,7 +138,7 @@ int sched_backtrace(pid_t tid, FAR void **buffer, int size)
--arg.cnt;
}
- return arg.cnt != -1 ? arg.cnt : 0;
+ return arg.cnt > 0 ? arg.cnt : 0;
}
#endif /* !CONFIG_ARCH_HAVE_BACKTRACE */
diff --git a/libs/libc/sched/sched_dumpstack.c b/libs/libc/sched/sched_dumpstack.c
index a6b871c..c504c11 100644
--- a/libs/libc/sched/sched_dumpstack.c
+++ b/libs/libc/sched/sched_dumpstack.c
@@ -29,7 +29,6 @@
#include <stdio.h>
#include <syslog.h>
-#include <execinfo.h>
/****************************************************************************
* Pre-processor Definitions
@@ -54,38 +53,43 @@
void sched_dumpstack(pid_t tid)
{
- FAR void *address[DUMP_DEPTH];
+ int size = DUMP_DEPTH;
+ int skip;
+
+ for (skip = 0; size == DUMP_DEPTH; skip += size)
+ {
+ FAR void *address[DUMP_DEPTH];
#ifndef CONFIG_ALLSYMS
- const char *format = " %0*p";
- char line[DUMP_LINESZ + 1];
- int ret = 0;
+ const char *format = " %0*p";
+ char line[DUMP_LINESZ + 1];
+ int ret = 0;
#endif
- int size;
- int i;
+ int i;
- size = sched_backtrace(tid, address, DUMP_DEPTH);
- if (size <= 0)
- {
- return;
- }
+ size = sched_backtrace(tid, address, DUMP_DEPTH, skip);
+ if (size <= 0)
+ {
+ break;
+ }
#ifndef CONFIG_ALLSYMS
- for (i = 0; i < size; i++)
- {
- ret += snprintf(line + ret, sizeof(line) - ret,
- format, DUMP_WIDTH, address[i]);
- if (i == size - 1 || ret % DUMP_LINESZ == 0)
+ for (i = 0; i < size; i++)
{
- syslog(LOG_EMERG, "backtrace|%2d:%s\n", tid, line);
- ret = 0;
+ ret += snprintf(line + ret, sizeof(line) - ret,
+ format, DUMP_WIDTH, address[i]);
+ if (i == size - 1 || ret % DUMP_LINESZ == 0)
+ {
+ syslog(LOG_EMERG, "backtrace|%2d:%s\n", tid, line);
+ ret = 0;
+ }
}
- }
#else
- syslog(LOG_EMERG, "backtrace:\n");
- for (i = 0; i < size; i++)
- {
- syslog(LOG_EMERG, "[%2d] [<%p>] %pS\n",
- tid, address[i], address[i]);
- }
+ syslog(LOG_EMERG, "backtrace:\n");
+ for (i = 0; i < size; i++)
+ {
+ syslog(LOG_EMERG, "[%2d] [<%p>] %pS\n",
+ tid, address[i], address[i]);
+ }
#endif
+ }
}
diff --git a/sched/sched/sched_backtrace.c b/sched/sched/sched_backtrace.c
index 6c3ab7d..16fe43c 100644
--- a/sched/sched/sched_backtrace.c
+++ b/sched/sched/sched_backtrace.c
@@ -40,7 +40,7 @@
*
****************************************************************************/
-int sched_backtrace(pid_t tid, FAR void **buffer, int size)
+int sched_backtrace(pid_t tid, FAR void **buffer, int size, int skip)
{
FAR struct tcb_s *rtcb = NULL;
@@ -53,5 +53,5 @@ int sched_backtrace(pid_t tid, FAR void **buffer, int size)
}
}
- return up_backtrace(rtcb, buffer, size);
+ return up_backtrace(rtcb, buffer, size, skip);
}
diff --git a/syscall/syscall.csv b/syscall/syscall.csv
index fd53acb..21445cf 100644
--- a/syscall/syscall.csv
+++ b/syscall/syscall.csv
@@ -132,7 +132,7 @@
"sched_setscheduler","sched.h","","int","pid_t","int","const struct sched_param *"
"sched_unlock","sched.h","","int"
"sched_yield","sched.h","","int"
-"sched_backtrace","sched.h","defined(CONFIG_SCHED_BACKTRACE)","int","pid_t","FAR void **","int"
+"sched_backtrace","sched.h","defined(CONFIG_SCHED_BACKTRACE)","int","pid_t","FAR void **","int","int"
"seekdir","dirent.h","","void","FAR DIR *","off_t"
"select","sys/select.h","","int","int","FAR fd_set *","FAR fd_set *","FAR fd_set *","FAR struct timeval *"
"sem_clockwait","semaphore.h","","int","FAR sem_t *","clockid_t","FAR const struct timespec *"