aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/breakpad/src/client/linux/handler/exception_trap.h
diff options
context:
space:
mode:
authoriddqd <iddqd@yandex-team.com>2024-12-19 10:46:06 +0300
committeriddqd <iddqd@yandex-team.com>2024-12-19 10:59:56 +0300
commitbb0840c0025a75dd3b85b746ebcec7deb7d9fe1c (patch)
tree85bc5522e873d9d5c37df278f0300c26fe9e729e /contrib/libs/breakpad/src/client/linux/handler/exception_trap.h
parent1353077f79bb3547792b2fc86c22a695f0bc76f9 (diff)
downloadydb-bb0840c0025a75dd3b85b746ebcec7deb7d9fe1c.tar.gz
Add contib/libs/breakpad to export
commit_hash:9d85255f8d9249f14105e4626bf4484805b8aed4
Diffstat (limited to 'contrib/libs/breakpad/src/client/linux/handler/exception_trap.h')
-rw-r--r--contrib/libs/breakpad/src/client/linux/handler/exception_trap.h73
1 files changed, 73 insertions, 0 deletions
diff --git a/contrib/libs/breakpad/src/client/linux/handler/exception_trap.h b/contrib/libs/breakpad/src/client/linux/handler/exception_trap.h
new file mode 100644
index 0000000000..1a9fdb7e17
--- /dev/null
+++ b/contrib/libs/breakpad/src/client/linux/handler/exception_trap.h
@@ -0,0 +1,73 @@
+#pragma once
+
+#include <array>
+#include <atomic>
+#include <exception>
+
+#include "google_breakpad/common/minidump_format.h"
+
+namespace google_breakpad {
+
+namespace detail {
+
+#ifdef __ANDROID__
+// In some versions of Android NDK the 'catch' blocks may have no affect in functions
+// with 'noexcept' specifier.
+constexpr bool can_catch_within_noexcept = false;
+#else
+constexpr bool can_catch_within_noexcept = true;
+#endif
+
+} // namespace detail
+
+// ExceptionDescriptor holds exception information and may be safely passed
+// between terminate handler context and signal handler context.
+//
+class ExceptionDescriptor {
+public:
+ // Copy |type_name| and |message| content to ExceptionDescriptor memory.
+ // Not thread-safe. Async-signal-safe.
+ // May be used in terminate handler.
+ void initialize(const char* type_name, const char* message) noexcept;
+
+ // isEmpty, getTypeName, getMessage are async-signal-safe.
+ // May be used in signal handler.
+ bool isEmpty() const noexcept;
+ const char* getTypeName() const noexcept;
+ const char* getMessage() const noexcept;
+
+private:
+ std::array<char, MAX_EXC_TYPE_LEN> type_name_{{'\0'}};
+ std::array<char, MAX_EXC_MSG_LEN> message_{{'\0'}};
+};
+
+// Singleton class. Wraps default terminate handler with ExceptionTrap::terminate_handler.
+// If terminate is caused by uncaught exception, ExceptionTrap stores information about exception
+// into ExceptionDescriptor before default terminate handler will call.
+class ExceptionTrap {
+public:
+ // Initialize single instance of ExceptionTrap if not initialized and return it.
+ // Must be called at least once before using it in terminate handler or signal handler.
+ static ExceptionTrap& getInstance() noexcept;
+
+ // Replace current terminate handler by ExceptionTrap::terminate_handler.
+ static void setupTerminateHandler();
+
+ // Return information about first exception that ExceptionTrap is "caught".
+ // If no exception was "caught", the empty ExceptionDescriptor will returned.
+ // Async-signal-safe.
+ const ExceptionDescriptor& getCurrentException() const noexcept;
+
+private:
+ bool initializeOnce(const char* type_name, const char* message) noexcept;
+
+ // Call original terminate handler and abort.
+ [[ noreturn ]] void terminate() const noexcept(detail::can_catch_within_noexcept);
+ [[ noreturn ]] static void terminate_handler() noexcept(detail::can_catch_within_noexcept);
+
+ std::atomic_flag initialized_ = ATOMIC_FLAG_INIT;
+ ExceptionDescriptor descriptor_{};
+ std::terminate_handler original_terminate_handler_{nullptr};
+};
+
+} //namespace google_breakpad