File indexing completed on 2026-03-28 07:46:14
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <cfenv>
0010 #include <csignal>
0011 #include <cstddef>
0012 #include <optional>
0013
0014 #include "FpeMonitorPlatform.hpp"
0015 #include "FpeMonitorPlatformDarwinCommon.hpp"
0016
0017 #if !defined(__APPLE__) || !defined(__x86_64__)
0018 #error "This translation unit is only valid for macOS x86_64"
0019 #endif
0020
0021 namespace ActsPlugins {
0022
0023
0024
0025 bool detail::isRuntimeSupported() {
0026 return true;
0027 }
0028
0029 std::optional<FpeType> detail::decodeFpeType(int signal, const siginfo_t* si,
0030 void* ctx) {
0031
0032
0033 static_cast<void>(ctx);
0034 if (signal != SIGFPE || si == nullptr) {
0035 return std::nullopt;
0036 }
0037 return fpeTypeFromSiCode(si->si_code);
0038 }
0039
0040 void detail::clearPendingExceptions(int excepts) {
0041
0042
0043 darwin::clearPendingExceptions(excepts);
0044 }
0045
0046 void detail::enableExceptions(int excepts) {
0047
0048
0049
0050 fenv_t env{};
0051 if (fegetenv(&env) != 0) {
0052 return;
0053 }
0054 env.__control &= ~static_cast<unsigned short>(excepts);
0055 env.__mxcsr &= ~(static_cast<unsigned int>(excepts) << 7u);
0056 env.__status &= ~static_cast<unsigned short>(FE_ALL_EXCEPT);
0057 env.__mxcsr &= ~static_cast<unsigned int>(FE_ALL_EXCEPT);
0058 fesetenv(&env);
0059 }
0060
0061 void detail::disableExceptions(int excepts) {
0062
0063 fenv_t env{};
0064 if (fegetenv(&env) != 0) {
0065 return;
0066 }
0067 env.__control |= static_cast<unsigned short>(excepts);
0068 env.__mxcsr |= (static_cast<unsigned int>(excepts) << 7u);
0069 fesetenv(&env);
0070 }
0071
0072 void detail::maskTrapsInSignalContext(void* ctx, FpeType type) {
0073
0074
0075 const int excepts = darwin::exceptMaskForType(type);
0076 auto* uc = static_cast<ucontext_t*>(ctx);
0077 uc->uc_mcontext->__fs.__fpu_fcw |= static_cast<unsigned short>(excepts);
0078 uc->uc_mcontext->__fs.__fpu_fsw &=
0079 ~static_cast<unsigned short>(FE_ALL_EXCEPT);
0080 uc->uc_mcontext->__fs.__fpu_mxcsr |=
0081 (static_cast<unsigned int>(excepts) << 7u);
0082 uc->uc_mcontext->__fs.__fpu_mxcsr &=
0083 ~static_cast<unsigned int>(FE_ALL_EXCEPT);
0084 }
0085
0086 std::size_t detail::captureStackFromSignalContext(void* ctx, void* buffer,
0087 std::size_t bufferBytes) {
0088
0089
0090 return darwin::captureStackFromSignalContext(
0091 ctx, buffer, bufferBytes, [](void* rawCtx) {
0092 const auto& uc = *static_cast<ucontext_t*>(rawCtx);
0093 return darwin::RegisterState{
0094 .sp = uc.uc_mcontext->__ss.__rsp,
0095 .fp = uc.uc_mcontext->__ss.__rbp,
0096 .pc = uc.uc_mcontext->__ss.__rip,
0097 };
0098 });
0099 }
0100
0101 std::size_t detail::safeDumpSkipFrames() {
0102
0103 return 1;
0104 }
0105
0106 bool detail::shouldFailFastOnUnknownSignal() {
0107
0108
0109 return false;
0110 }
0111
0112 void detail::installSignalHandlers(void (*handler)(int, siginfo_t*, void*)) {
0113
0114 struct sigaction action{};
0115 action.sa_sigaction = handler;
0116 action.sa_flags = SA_SIGINFO;
0117 sigaction(SIGFPE, &action, nullptr);
0118 }
0119
0120 }