File stacktraceplainptrs.h
File List > code_source > templat > include > TempLat > util > debug > stacktraceplainptrs.h
Go to the documentation of this file
#ifndef TEMPLAT_UTIL_DEBUG_STACKTRACEPLAINPTRS_H
#define TEMPLAT_UTIL_DEBUG_STACKTRACEPLAINPTRS_H
/* This file is part of TempLat, available at https://cosmolattice.github.io/templat .
Copyright 2021-2026 The TempLat authors, see AUTHORS.md.
Released under the MIT license, see LICENSE.md. */
// File info: Main contributor(s): Wessel Valkenburg, Year: 2019
#include <stdio.h>
#include <stdlib.h>
#include <execinfo.h>
#include <string>
#include <sstream>
#include <map>
#include <algorithm>
#include <signal.h>
#include <cxxabi.h>
#include <thread>
#include <chrono>
#include <vector>
#include <array>
#include <iostream>
#ifdef TempLatPOSIXDETECTED
#undef TempLatPOSIXDETECTED
#endif
#ifdef __linux__
#define TempLatPOSIXDETECTED
/* File created by Wessel Valkenburg, 2019 */
/* Released under the MIT license, see LICENSE.md. */
#elif defined(__APPLE__)
#define TempLatPOSIXDETECTED
/* File created by Wessel Valkenburg, 2019 */
/* Released under the MIT license, see LICENSE.md. */
#else
#error "posix detection failed"
#endif
#ifdef TempLatPOSIXDETECTED
#include <unistd.h>
#ifdef __APPLE__
#include <dlfcn.h>
#include <mach-o/dyld.h>
#endif
#endif
/* undefine this if you cannot compile. */
// #define HAVE_LIBUNWIND
#ifdef HAVE_LIBUNWIND
#include <libunwind.h>
#define TEMPLATEUNWIND true
#else
#define TEMPLATEUNWIND false
#endif
namespace TempLat
{
template <size_t N>
requires(N != 1 && N != 0 && !TEMPLATEUNWIND)
inline void StacktracePlainptrs(std::array<void *, N> *result, int *addrlen)
{
#ifdef TempLatPOSIXDETECTED
// retrieve current stack addresses
*addrlen = backtrace(result->data(), N > 1u ? N - 1u : N);
/* N > 1 */
result->operator[](*addrlen) = NULL;
#endif
return;
}
template <size_t N>
requires(N != 1 && N != 0 && TEMPLATEUNWIND)
inline void StacktracePlainptrs(std::array<void *, N> *result, int *addrlen)
{
#ifdef HAVE_LIBUNWIND
unw_cursor_t cursor;
unw_context_t uc;
unw_word_t ip;
// unw_word_t sp;
unw_getcontext(&uc);
unw_init_local(&cursor, &uc);
*addrlen = 0;
while (unw_step(&cursor) > 0 && *addrlen < ((ptrdiff_t)N) - 1) {
unw_get_reg(&cursor, UNW_REG_IP, &ip);
// unw_get_reg(&cursor, UNW_REG_SP, &sp);
// printf ("ip = %lx, sp = %lx\n", (long) ip, (long) sp);
result->operator[]((*addrlen)++) = (void *)ip;
}
// retrieve current stack addresses
/* N > 1 */
result->operator[](*addrlen) = NULL;
#endif
return;
}
} // namespace TempLat
#endif