File indexing completed on 2024-05-12 17:15:55
0001 /* 0002 SPDX-FileCopyrightText: 2014-2019 Milian Wolff <mail@milianw.de> 0003 0004 SPDX-License-Identifier: LGPL-2.1-or-later 0005 */ 0006 0007 /** 0008 * @brief A libunwind based backtrace. 0009 */ 0010 0011 #include "trace.h" 0012 0013 #include "util/libunwind_config.h" 0014 0015 #include <cinttypes> 0016 #include <cstdio> 0017 0018 #define UNW_LOCAL_ONLY 1 0019 #include <libunwind.h> 0020 0021 void Trace::print() 0022 { 0023 #if LIBUNWIND_HAS_UNW_GETCONTEXT && LIBUNWIND_HAS_UNW_INIT_LOCAL 0024 unw_context_t context; 0025 unw_getcontext(&context); 0026 0027 unw_cursor_t cursor; 0028 unw_init_local(&cursor, &context); 0029 0030 int frameNr = 0; 0031 while (unw_step(&cursor)) { 0032 ++frameNr; 0033 unw_word_t ip = 0; 0034 unw_get_reg(&cursor, UNW_REG_IP, &ip); 0035 0036 unw_word_t sp = 0; 0037 unw_get_reg(&cursor, UNW_REG_SP, &sp); 0038 0039 char symbol[256] = {"<unknown>"}; 0040 unw_word_t offset = 0; 0041 unw_get_proc_name(&cursor, symbol, sizeof(symbol), &offset); 0042 0043 fprintf(stderr, "#%-2d 0x%016" PRIxPTR " sp=0x%016" PRIxPTR " %s + 0x%" PRIxPTR "\n", frameNr, 0044 static_cast<uintptr_t>(ip), static_cast<uintptr_t>(sp), symbol, static_cast<uintptr_t>(offset)); 0045 } 0046 #endif 0047 } 0048 0049 void Trace::setup() 0050 { 0051 // configure libunwind for better speed 0052 #if LIBUNWIND_HAS_UNW_CACHE_PER_THREAD 0053 if (unw_set_caching_policy(unw_local_addr_space, UNW_CACHE_PER_THREAD)) { 0054 fprintf(stderr, "WARNING: Failed to enable per-thread libunwind caching.\n"); 0055 } 0056 #endif 0057 0058 #if LIBUNWIND_HAS_UNW_SET_CACHE_SIZE 0059 if (unw_set_cache_size(unw_local_addr_space, 1024, 0)) { 0060 fprintf(stderr, "WARNING: Failed to set libunwind cache size.\n"); 0061 } 0062 #endif 0063 } 0064 0065 int Trace::unwind(void** data) 0066 { 0067 return unw_backtrace(data, MAX_SIZE); 0068 }