subsys/profiling: fix extra frame in the traces
Check if the frame is within the text address before saving into the buffer, this eliminates the extra, uninitialized frame at the end of the unwind. 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
55c7b9fad6
commit
44c070fdcd
3 changed files with 33 additions and 0 deletions
|
@ -12,6 +12,13 @@ static bool valid_stack(uintptr_t addr, k_tid_t current)
|
||||||
addr < current->stack_info.start + current->stack_info.size;
|
addr < current->stack_info.start + current->stack_info.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool in_text_region(uintptr_t addr)
|
||||||
|
{
|
||||||
|
extern uintptr_t __text_region_start, __text_region_end;
|
||||||
|
|
||||||
|
return (addr >= (uintptr_t)&__text_region_start) && (addr < (uintptr_t)&__text_region_end);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function use frame pointers to unwind stack and get trace of return addresses.
|
* This function use frame pointers to unwind stack and get trace of return addresses.
|
||||||
* Return addresses are translated in corresponding function's names using .elf file.
|
* Return addresses are translated in corresponding function's names using .elf file.
|
||||||
|
@ -75,6 +82,10 @@ size_t arch_perf_current_stack_trace(uintptr_t *buf, size_t size)
|
||||||
if (idx >= size)
|
if (idx >= size)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (!in_text_region((uintptr_t)fp[-1])) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
buf[idx++] = (uintptr_t)fp[-1];
|
buf[idx++] = (uintptr_t)fp[-1];
|
||||||
new_fp = (void **)fp[-2];
|
new_fp = (void **)fp[-2];
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,13 @@ static bool valid_stack(uintptr_t addr, k_tid_t current)
|
||||||
addr < current->stack_info.start + current->stack_info.size;
|
addr < current->stack_info.start + current->stack_info.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool in_text_region(uintptr_t addr)
|
||||||
|
{
|
||||||
|
extern uintptr_t __text_region_start, __text_region_end;
|
||||||
|
|
||||||
|
return (addr >= (uintptr_t)&__text_region_start) && (addr < (uintptr_t)&__text_region_end);
|
||||||
|
}
|
||||||
|
|
||||||
/* interruption stack frame */
|
/* interruption stack frame */
|
||||||
struct isf {
|
struct isf {
|
||||||
uint32_t ebp;
|
uint32_t ebp;
|
||||||
|
@ -63,6 +70,10 @@ size_t arch_perf_current_stack_trace(uintptr_t *buf, size_t size)
|
||||||
if (idx >= size)
|
if (idx >= size)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (!in_text_region((uintptr_t)fp[1])) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
buf[idx++] = (uintptr_t)fp[1];
|
buf[idx++] = (uintptr_t)fp[1];
|
||||||
void **new_fp = (void **)fp[0];
|
void **new_fp = (void **)fp[0];
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,13 @@ static bool valid_stack(uintptr_t addr, k_tid_t current)
|
||||||
addr < current->stack_info.start + current->stack_info.size;
|
addr < current->stack_info.start + current->stack_info.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool in_text_region(uintptr_t addr)
|
||||||
|
{
|
||||||
|
extern uintptr_t __text_region_start, __text_region_end;
|
||||||
|
|
||||||
|
return (addr >= (uintptr_t)&__text_region_start) && (addr < (uintptr_t)&__text_region_end);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function use frame pointers to unwind stack and get trace of return addresses.
|
* This function use frame pointers to unwind stack and get trace of return addresses.
|
||||||
* Return addresses are translated in corresponding function's names using .elf file.
|
* Return addresses are translated in corresponding function's names using .elf file.
|
||||||
|
@ -49,6 +56,10 @@ size_t arch_perf_current_stack_trace(uintptr_t *buf, size_t size)
|
||||||
if (idx >= size)
|
if (idx >= size)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (!in_text_region((uintptr_t)fp[1])) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
buf[idx++] = (uintptr_t)fp[1];
|
buf[idx++] = (uintptr_t)fp[1];
|
||||||
void **new_fp = (void **)fp[0];
|
void **new_fp = (void **)fp[0];
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue