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 }