File indexing completed on 2024-05-12 17:15:55
0001 /* 0002 SPDX-FileCopyrightText: 2014-2017 Milian Wolff <mail@milianw.de> 0003 0004 SPDX-License-Identifier: LGPL-2.1-or-later 0005 */ 0006 0007 #ifndef TRACE_H 0008 #define TRACE_H 0009 0010 #include <cassert> 0011 #include <cstdint> 0012 0013 /** 0014 * @brief Backtrace interface. 0015 */ 0016 struct Trace 0017 { 0018 using ip_t = void*; 0019 0020 enum : int 0021 { 0022 MAX_SIZE = 64 0023 }; 0024 0025 const ip_t* begin() const 0026 { 0027 return m_data + m_skip; 0028 } 0029 0030 const ip_t* end() const 0031 { 0032 return begin() + m_size; 0033 } 0034 0035 ip_t operator[](int i) const 0036 { 0037 return m_data[m_skip + i]; 0038 } 0039 0040 int size() const 0041 { 0042 return m_size; 0043 } 0044 0045 bool fill(int skip) 0046 { 0047 int size = unwind(m_data); 0048 // filter bogus frames at the end, which sometimes get returned by tracer backend 0049 // cf.: https://bugs.kde.org/show_bug.cgi?id=379082 0050 while (size > 0 && !m_data[size - 1]) { 0051 --size; 0052 } 0053 m_size = size > skip ? size - skip : 0; 0054 m_skip = skip; 0055 return m_size > 0; 0056 } 0057 0058 void fillTestData(uintptr_t n, uintptr_t leaf) 0059 { 0060 assert(n < MAX_SIZE); 0061 m_data[0] = reinterpret_cast<ip_t>(leaf); 0062 for (uintptr_t i = 1; i <= n; ++i) { 0063 m_data[i] = reinterpret_cast<ip_t>(i); 0064 } 0065 0066 m_size = n + 1; 0067 m_skip = 0; 0068 } 0069 0070 static void setup(); 0071 0072 static void print(); 0073 0074 private: 0075 static int unwind(void** data); 0076 0077 private: 0078 int m_size = 0; 0079 int m_skip = 0; 0080 ip_t m_data[MAX_SIZE]; 0081 }; 0082 0083 #endif // TRACE_H