net/cnxk: remove restriction on VF for PFC config
[dpdk.git] / lib / eal / unix / eal_debug.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4
5 #include <rte_debug.h>
6
7 #ifdef RTE_BACKTRACE
8
9 #include <dlfcn.h>
10 #include <execinfo.h>
11 #include <string.h>
12 #include <sys/uio.h>
13 #include <unistd.h>
14
15 #define BACKTRACE_SIZE 256
16
17 /*
18  * Convert number to string and return start of string.
19  * Note: string does not start at beginning of buffer.
20  */
21 static char *safe_itoa(long val, char *buf, size_t len, unsigned int radix)
22 {
23         char *bp = buf + len;
24         static const char hexdigit[] = "0123456789abcdef";
25
26         *--bp = '\0'; /* Null terminate the string */
27         do {
28                 /* if buffer is not big enough, then truncate */
29                 if (bp == buf)
30                         return bp;
31
32                 *--bp = hexdigit[val % radix];
33                 val /= radix;
34         } while (val != 0);
35
36         return bp;
37 }
38
39 /*
40  * Dump the stack of the calling core
41  *
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.
45  *
46  * Most of libc is therefore not safe, include RTE_LOG (calls syslog);
47  * backtrace_symbols (calls malloc), etc.
48  */
49 void rte_dump_stack(void)
50 {
51         void *func[BACKTRACE_SIZE];
52         Dl_info info;
53         char buf1[8], buf2[32], buf3[32], buf4[32];
54         struct iovec iov[10];
55         int i, size;
56
57         size = backtrace(func, BACKTRACE_SIZE);
58
59         for (i = 0; i < size; i++) {
60                 struct iovec *io = iov;
61                 char *str;
62                 uintptr_t base;
63                 long offset;
64                 void *pc = func[i];
65
66 /*
67  * Macro to put string onto set of iovecs.
68  * cast is to suppress warnings about lose of const qualifier.
69  */
70 #define PUSH_IOV(io, str) {                                     \
71                 (io)->iov_base = (char *)(uintptr_t)str;        \
72                 (io)->iov_len = strlen(str);                    \
73                 ++io; }
74
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] */
79
80                 /* Lookup the symbol information */
81                 if (dladdr(pc, &info) == 0) {
82                         PUSH_IOV(io, "?? [");
83                 } else {
84                         const char *fname;
85
86                         if (info.dli_fname && *info.dli_fname)
87                                 fname = info.dli_fname;
88                         else
89                                 fname = "(vdso)";
90                         PUSH_IOV(io, fname);    /* iov[2] */
91                         PUSH_IOV(io, " (");     /* iov[3] */
92
93                         if (info.dli_saddr != NULL) {
94                                 PUSH_IOV(io, info.dli_sname);   /* iov[4] */
95                                 base = (uintptr_t)info.dli_saddr;
96                         } else {
97                                 str = safe_itoa((unsigned long)info.dli_fbase,
98                                         buf3, sizeof(buf3), 16);
99                                 PUSH_IOV(io, str);
100                                 base = (uintptr_t)info.dli_fbase;
101                         }
102
103                         PUSH_IOV(io, "+0x");    /* iov[5] */
104
105                         offset = (uintptr_t)pc - base;
106                         str = safe_itoa(offset, buf4, sizeof(buf4), 16);
107                         PUSH_IOV(io, str);      /* iov[6] */
108
109                         PUSH_IOV(io, ") [");    /* iov[7] */
110                 }
111
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] */
115
116                 if (writev(STDERR_FILENO, iov, io - iov) < 0)
117                         break;
118 #undef PUSH_IOV
119         }
120 }
121
122 #else /* !RTE_BACKTRACE */
123
124 /* stub if not enabled */
125 void rte_dump_stack(void) { }
126
127 #endif /* RTE_BACKTRACE */