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