github.com/searKing/golang/go@v1.2.117/os/signal/cgo/include/boost/stacktrace/detail/frame_unwind.ipp (about)

     1  // Copyright Antony Polukhin, 2016-2023.
     2  //
     3  // Distributed under the Boost Software License, Version 1.0. (See
     4  // accompanying file LICENSE_1_0.txt or copy at
     5  // http://www.boost.org/LICENSE_1_0.txt)
     6  
     7  #ifndef BOOST_STACKTRACE_DETAIL_FRAME_UNWIND_IPP
     8  #define BOOST_STACKTRACE_DETAIL_FRAME_UNWIND_IPP
     9  
    10  #include <boost/config.hpp>
    11  #ifdef BOOST_HAS_PRAGMA_ONCE
    12  #   pragma once
    13  #endif
    14  
    15  #include <boost/stacktrace/frame.hpp>
    16  
    17  #include <boost/stacktrace/detail/to_hex_array.hpp>
    18  #include <boost/stacktrace/detail/location_from_symbol.hpp>
    19  #include <boost/stacktrace/detail/to_dec_array.hpp>
    20  #include <boost/core/demangle.hpp>
    21  
    22  #include <cstdio>
    23  
    24  #ifdef BOOST_STACKTRACE_USE_BACKTRACE
    25  #   include <boost/stacktrace/detail/libbacktrace_impls.hpp>
    26  #elif defined(BOOST_STACKTRACE_USE_ADDR2LINE)
    27  #   include <boost/stacktrace/detail/addr2line_impls.hpp>
    28  #else
    29  #   include <boost/stacktrace/detail/unwind_base_impls.hpp>
    30  #endif
    31  
    32  namespace boost { namespace stacktrace { namespace detail {
    33  
    34  template <class Base>
    35  class to_string_impl_base: private Base {
    36  public:
    37      std::string operator()(boost::stacktrace::detail::native_frame_ptr_t addr) {
    38          Base::res.clear();
    39          Base::prepare_function_name(addr);
    40          if (!Base::res.empty()) {
    41              Base::res = boost::core::demangle(Base::res.c_str());
    42          } else {
    43              Base::res = to_hex_array(addr).data();
    44          }
    45  
    46          if (Base::prepare_source_location(addr)) {
    47              return Base::res;
    48          }
    49  
    50          boost::stacktrace::detail::location_from_symbol loc(addr);
    51          if (!loc.empty()) {
    52              Base::res += " in ";
    53              Base::res += loc.name();
    54          }
    55  
    56          return Base::res;
    57      }
    58  };
    59  
    60  std::string to_string(const frame* frames, std::size_t size) {
    61      std::string res;
    62      if (size == 0) {
    63          return res;
    64      }
    65      res.reserve(64 * size);
    66  
    67      to_string_impl impl;
    68  
    69      for (std::size_t i = 0; i < size; ++i) {
    70          if (i < 10) {
    71              res += ' ';
    72          }
    73          res += boost::stacktrace::detail::to_dec_array(i).data();
    74          res += '#';
    75          res += ' ';
    76          res += impl(frames[i].address());
    77          res += '\n';
    78      }
    79  
    80      return res;
    81  }
    82  
    83  
    84  } // namespace detail
    85  
    86  
    87  std::string frame::name() const {
    88      if (!addr_) {
    89          return std::string();
    90      }
    91  
    92  #if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
    93      ::Dl_info dli;
    94      const bool dl_ok = !!::dladdr(const_cast<void*>(addr_), &dli); // `dladdr` on Solaris accepts nonconst addresses
    95      if (dl_ok && dli.dli_sname) {
    96          return boost::core::demangle(dli.dli_sname);
    97      }
    98  #endif
    99      return boost::stacktrace::detail::name_impl(addr_);
   100  }
   101  
   102  std::string to_string(const frame& f) {
   103      if (!f) {
   104          return std::string();
   105      }
   106  
   107      boost::stacktrace::detail::to_string_impl impl;
   108      return impl(f.address());
   109  }
   110  
   111  
   112  }} // namespace boost::stacktrace
   113  
   114  #endif // BOOST_STACKTRACE_DETAIL_FRAME_UNWIND_IPP