/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2019, Danny Robson */ #include "backtrace.hpp" #include "cast.hpp" #include "iterator/zip.hpp" #include #include #include #include using cruft::backtrace; static constexpr std::size_t DEFAULT_DEPTH = 16; /////////////////////////////////////////////////////////////////////////////// backtrace::backtrace (void) : m_frames (DEFAULT_DEPTH) { do { int const target = static_cast (m_frames.size ()); int const last = ::backtrace ( m_frames.data (), target ); if (last < target) { m_frames.resize (last); break; } m_frames.resize (m_frames.size () * 2); } while (1); } /////////////////////////////////////////////////////////////////////////////// std::ostream& cruft::operator <<(std::ostream &os, backtrace const &rhs) { fmt::print (os, "{}", rhs); return os; } /////////////////////////////////////////////////////////////////////////////// fmt::format_context::iterator fmt::formatter::format ( cruft::backtrace const &obj, fmt::format_context &ctx ) { fmt::format_to (ctx.out (), "[ "); auto const &frames = obj.frames (); using strings_t = std::unique_ptr; strings_t const names ( backtrace_symbols ( frames.data (), cruft::cast::lossless (frames.size ()) ), ::free ); for (auto const [idx,addr]: cruft::iterator::izip (frames)) { fmt::format_to ( ctx.out (), "{{ addr: {}, name: '{}', }}, ", frames[idx], names.get()[idx] ); } return fmt::format_to (ctx.out (), " ]"); }