// Matrix Construct // // Copyright (C) Matrix Construct Developers, Authors & Contributors // Copyright (C) 2016-2019 Jason Volk // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice is present in all copies. The // full license for this software is available in the LICENSE file. #include This is a global variable set at program start time. It marks the // > highest used stack address. // extern void * __libc_stack_end; void __attribute__((constructor)) ircd_backtrace_allow_libc_fix() { static const auto &prot { PROT_READ | PROT_WRITE }; const auto &addr { uintptr_t(&__libc_stack_end) & ~(getpagesize() - 1UL) }; ircd::syscall(::mprotect, (void *)addr, sizeof(__libc_stack_end), prot); } #endif defined(IRCD_BACKTRACE_GLIBC_WORKAROUND) // // backtrace::backtrace // namespace ircd { static thread_local std::array backtrace_buffer; } ircd::backtrace::backtrace() :backtrace { backtrace_buffer.data(), backtrace_buffer.size() } { } ircd::backtrace::backtrace(const mutable_buffer &buf) :backtrace { reinterpret_cast ( const_cast ( std::addressof(data(buf)) ) ), buffer::size(buf) / sizeof(void *) } { } ircd::backtrace::backtrace(const void **const &array, const size_t &count) :array { array } ,count { 0UL } { #if defined(IRCD_BACKTRACE_GLIBC_WORKAROUND) const scope_restore stack_check_workaround { __libc_stack_end, reinterpret_cast(uintptr_t(-1UL)) }; #endif #if defined(IRCD_BACKTRACE_SUPPORT) this->count = ::backtrace(const_cast(this->array), count); #endif }