123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- #ifndef REALM_UTIL_BACKTRACE_HPP
- #define REALM_UTIL_BACKTRACE_HPP
- #include <string>
- #include <iosfwd>
- #include <stdexcept>
- namespace realm {
- namespace util {
- struct Backtrace {
-
-
-
-
-
-
-
- static Backtrace capture() noexcept;
-
-
- void print(std::ostream&) const;
-
- Backtrace() noexcept
- {
- }
-
- Backtrace(Backtrace&&) noexcept;
-
- Backtrace(const Backtrace&) noexcept;
- ~Backtrace();
-
- Backtrace& operator=(Backtrace&&) noexcept;
-
-
-
- Backtrace& operator=(const Backtrace&) noexcept;
- private:
- Backtrace(void* memory, const char* const* strs, size_t len)
- : m_memory(memory)
- , m_strs(strs)
- , m_len(len)
- {
- }
- Backtrace(void* memory, size_t len)
- : m_memory(memory)
- , m_strs(static_cast<char* const*>(memory))
- , m_len(len)
- {
- }
-
-
-
-
-
-
- void* m_memory = nullptr;
-
-
- const char* const* m_strs = nullptr;
-
- size_t m_len = 0;
- };
- namespace detail {
- class ExceptionWithBacktraceBase {
- public:
- ExceptionWithBacktraceBase()
- : m_backtrace(util::Backtrace::capture())
- {
- }
- const util::Backtrace& backtrace() const noexcept
- {
- return m_backtrace;
- }
- virtual const char* message() const noexcept = 0;
- protected:
- util::Backtrace m_backtrace;
-
-
- mutable bool m_has_materialized_message = false;
- mutable std::string m_materialized_message;
-
-
-
- const char* materialize_message() const noexcept;
- };
- }
- template <class Base = std::runtime_error>
- class ExceptionWithBacktrace : public Base, public detail::ExceptionWithBacktraceBase {
- public:
- template <class... Args>
- inline ExceptionWithBacktrace(Args&&... args)
- : Base(std::forward<Args>(args)...)
- , detail::ExceptionWithBacktraceBase()
- {
- }
-
-
- const char* what() const noexcept final
- {
- return materialize_message();
- }
-
-
- const char* message() const noexcept override
- {
- return Base::what();
- }
- };
- using runtime_error = ExceptionWithBacktrace<std::runtime_error>;
- using range_error = ExceptionWithBacktrace<std::range_error>;
- using overflow_error = ExceptionWithBacktrace<std::overflow_error>;
- using underflow_error = ExceptionWithBacktrace<std::underflow_error>;
- using bad_alloc = ExceptionWithBacktrace<std::bad_alloc>;
- using invalid_argument = ExceptionWithBacktrace<std::invalid_argument>;
- using out_of_range = ExceptionWithBacktrace<std::out_of_range>;
- using logic_error = ExceptionWithBacktrace<std::logic_error>;
- }
- }
- inline std::ostream& operator<<(std::ostream& os, const realm::util::Backtrace& bt)
- {
- bt.print(os);
- return os;
- }
- #endif
|