MCPcopy Create free account
hub / github.com/apache/nifi-minifi-cpp / pull_trace

Function pull_trace

libminifi/src/utils/BackTrace.cpp:58–122  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

56#endif
57
58void pull_trace(uint8_t frames_to_skip /* = 1 */) {
59#ifdef HAS_EXECINFO
60 void* stack_buffer[TRACE_BUFFER_SIZE + 1];
61
62 /* Get the backtrace of the current thread */
63 int trace_size = backtrace(stack_buffer, TRACE_BUFFER_SIZE);
64
65 /* We can skip the signal handler, call to pull_trace, and the first entry for backtrace_symbols */
66 for (int i = frames_to_skip; i < trace_size; i++) {
67 const char* file_name = "???";
68 uintptr_t symbol_offset = 0;
69
70 /* Translate the address to symbolic information */
71 Dl_info dl_info{};
72#ifdef __linux__
73 struct link_map* l_map = nullptr;
74 int res = dladdr1(stack_buffer[i], &dl_info, reinterpret_cast<void**>(&l_map), RTLD_DL_LINKMAP);
75#else
76 int res = dladdr(stack_buffer[i], &dl_info);
77#endif
78 if (res == 0 || dl_info.dli_fname == nullptr || dl_info.dli_fname[0] == '\0') {
79 /* We could not determine symbolic information for this address*/
80 TraceResolver::getResolver().addTraceLine(file_name, nullptr, symbol_offset);
81 continue;
82 }
83
84 /* Determine the filename of the shared object */
85 if (dl_info.dli_fname != nullptr) {
86 const char* last_slash = nullptr;
87 /* If the shared object name is a full path, we still only want the filename component */
88 if ((last_slash = strrchr(dl_info.dli_fname, '/')) != nullptr) {
89 file_name = last_slash + 1;
90 } else {
91 file_name = dl_info.dli_fname;
92 }
93 }
94
95 const std::string symbol_name = dl_info.dli_sname
96 ? demangle_symbol(dl_info.dli_sname).value_or(file_name)
97 : file_name;
98
99 /* Determine our offset */
100 uintptr_t base_address = 0;
101 if (dl_info.dli_sname != nullptr) {
102 /* If we could determine our symbol we will display our offset from the address of the symbol */
103 base_address = reinterpret_cast<uintptr_t>(dl_info.dli_saddr);
104 } else {
105 /* Otherwise we will display our offset from base address of the shared object */
106#ifdef __linux__
107 /*
108 * glibc uses l_addr from the link map instead of dli_fbase in backtrace_symbols for calculating this offset.
109 * I could not find a difference between the two in my limited measurements, but we will use it too, just to be sure.
110 */
111 if (l_map != nullptr) {
112 dl_info.dli_fbase = reinterpret_cast<void*>(l_map->l_addr);
113 }
114#endif
115 base_address = reinterpret_cast<uintptr_t>(dl_info.dli_fbase);

Callers 2

getBackTraceMethod · 0.85
handlerFunction · 0.85

Calls 3

demangle_symbolFunction · 0.85
addTraceLineMethod · 0.80
c_strMethod · 0.80

Tested by

no test coverage detected