1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2014 Intel Corporation
15 #define BACKTRACE_SIZE 256
18 * Convert number to string and return start of string.
19 * Note: string does not start at beginning of buffer.
21 static char *safe_itoa(long val, char *buf, size_t len, unsigned int radix)
24 static const char hexdigit[] = "0123456789abcdef";
26 *--bp = '\0'; /* Null terminate the string */
28 /* if buffer is not big enough, then truncate */
32 *--bp = hexdigit[val % radix];
40 * Dump the stack of the calling core
42 * To be safe in signal handler requires limiting what functions are
43 * used in this code since may be called from inside libc or
44 * when malloc poll is corrupt.
46 * Most of libc is therefore not safe, include RTE_LOG (calls syslog);
47 * backtrace_symbols (calls malloc), etc.
49 void rte_dump_stack(void)
51 void *func[BACKTRACE_SIZE];
53 char buf1[8], buf2[32], buf3[32], buf4[32];
57 size = backtrace(func, BACKTRACE_SIZE);
59 for (i = 0; i < size; i++) {
60 struct iovec *io = iov;
67 * Macro to put string onto set of iovecs.
68 * cast is to suppress warnings about lose of const qualifier.
70 #define PUSH_IOV(io, str) { \
71 (io)->iov_base = (char *)(uintptr_t)str; \
72 (io)->iov_len = strlen(str); \
75 /* output stack frame number */
76 str = safe_itoa(i, buf1, sizeof(buf1), 10);
77 PUSH_IOV(io, str); /* iov[0] */
78 PUSH_IOV(io, ": "); /* iov[1] */
80 /* Lookup the symbol information */
81 if (dladdr(pc, &info) == 0) {
86 if (info.dli_fname && *info.dli_fname)
87 fname = info.dli_fname;
90 PUSH_IOV(io, fname); /* iov[2] */
91 PUSH_IOV(io, " ("); /* iov[3] */
93 if (info.dli_saddr != NULL) {
94 PUSH_IOV(io, info.dli_sname); /* iov[4] */
95 base = (uintptr_t)info.dli_saddr;
97 str = safe_itoa((unsigned long)info.dli_fbase,
98 buf3, sizeof(buf3), 16);
100 base = (uintptr_t)info.dli_fbase;
103 PUSH_IOV(io, "+0x"); /* iov[5] */
105 offset = (uintptr_t)pc - base;
106 str = safe_itoa(offset, buf4, sizeof(buf4), 16);
107 PUSH_IOV(io, str); /* iov[6] */
109 PUSH_IOV(io, ") ["); /* iov[7] */
112 str = safe_itoa((unsigned long)pc, buf2, sizeof(buf2), 16);
113 PUSH_IOV(io, str); /* iov[8] */
114 PUSH_IOV(io, "]\n"); /* iov[9] */
116 if (writev(STDERR_FILENO, iov, io - iov) < 0)
122 #else /* !RTE_BACKTRACE */
124 /* stub if not enabled */
125 void rte_dump_stack(void) { }
127 #endif /* RTE_BACKTRACE */