[v2,1/2] eal_debug: do not use malloc in rte_dump_stack
Checks
Commit Message
The glibc backtrace_symbols() calls malloc which makes it
dangerous to use rte_dump_stack() in a signal handler that
is handling errors that maybe due to memory corruption.
Instead, use dladdr() to lookup up symbols incrementally.
The format of the messages is based on what X org server
has been doing for many years. It changes from bottom up
to top down order.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/eal/linux/eal_debug.c | 46 +++++++++++++++++++++++++++++----------
1 file changed, 34 insertions(+), 12 deletions(-)
Comments
12/02/2022 19:44, Stephen Hemminger:
> The glibc backtrace_symbols() calls malloc which makes it
> dangerous to use rte_dump_stack() in a signal handler that
> is handling errors that maybe due to memory corruption.
>
> Instead, use dladdr() to lookup up symbols incrementally.
>
> The format of the messages is based on what X org server
> has been doing for many years. It changes from bottom up
> to top down order.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Morten acked the RFC.
Is there any significant change?
On Sun, 13 Feb 2022 12:41:59 +0100
Thomas Monjalon <thomas@monjalon.net> wrote:
> 12/02/2022 19:44, Stephen Hemminger:
> > The glibc backtrace_symbols() calls malloc which makes it
> > dangerous to use rte_dump_stack() in a signal handler that
> > is handling errors that maybe due to memory corruption.
> >
> > Instead, use dladdr() to lookup up symbols incrementally.
> >
> > The format of the messages is based on what X org server
> > has been doing for many years. It changes from bottom up
> > to top down order.
> >
> > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
>
> Morten acked the RFC.
> Is there any significant change?
>
>
>
The change was making it not RFC.
Lets make a common code for this FreeBSD should have same code.
@@ -4,6 +4,7 @@
#ifdef RTE_BACKTRACE
#include <execinfo.h>
+#include <dlfcn.h>
#endif
#include <stdarg.h>
#include <signal.h>
@@ -18,26 +19,47 @@
#define BACKTRACE_SIZE 256
-/* dump the stack of the calling core */
+/* Dump the stack of the calling core
+ *
+ * Note: this requires limiting what functions are used in this code to stay safe
+ * when called from a signal handler and malloc pool maybe corrupt.
+ */
void rte_dump_stack(void)
{
#ifdef RTE_BACKTRACE
void *func[BACKTRACE_SIZE];
- char **symb = NULL;
- int size;
+ int i, size;
size = backtrace(func, BACKTRACE_SIZE);
- symb = backtrace_symbols(func, size);
- if (symb == NULL)
- return;
+ for (i = 0; i < size; i++) {
+ void *pc = func[i];
+ const char *fname;
+ Dl_info info;
- while (size > 0) {
- rte_log(RTE_LOG_ERR, RTE_LOGTYPE_EAL,
- "%d: [%s]\n", size, symb[size - 1]);
- size --;
- }
+ if (dladdr(pc, &info) == 0) {
+ /* If symbol information not found print in hex */
+ rte_log(RTE_LOG_ERR, RTE_LOGTYPE_EAL,
+ "%d: ?? [%p]\n", i, pc);
+ continue;
+ }
- free(symb);
+ /* Is file name known? */
+ fname = (info.dli_fname && *info.dli_fname) ? info.dli_fname : "(vdso)";
+
+ /* Is symbol name known? */
+ if (info.dli_sname != NULL)
+ rte_log(RTE_LOG_ERR, RTE_LOGTYPE_EAL,
+ "%d: %s (%s+%#tx) [%p]\n",
+ i, fname, info.dli_sname,
+ (ptrdiff_t)((uintptr_t)pc - (uintptr_t)info.dli_saddr),
+ pc);
+ else
+ rte_log(RTE_LOG_ERR, RTE_LOGTYPE_EAL,
+ "%d: %s (%p+%#tx) [%p]\n",
+ i, fname, info.dli_fbase,
+ (ptrdiff_t)((uintptr_t)pc - (uintptr_t)info.dli_fbase),
+ pc);
+ }
#endif /* RTE_BACKTRACE */
}