diff --git a/cspell.config.yaml b/cspell.config.yaml index ec0a522663..eeae3d12ff 100644 --- a/cspell.config.yaml +++ b/cspell.config.yaml @@ -112,6 +112,7 @@ words: - gpgcheck - gpgkey - hotwallet + - hwaddress - hwrap - ifndef - inequation diff --git a/include/xrpl/basics/contract.h b/include/xrpl/basics/contract.h index aba021b726..f41c272b61 100644 --- a/include/xrpl/basics/contract.h +++ b/include/xrpl/basics/contract.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -23,16 +24,28 @@ LogThrow(std::string const& title); When called from within a catch block, it will pass control to the next matching exception handler, if any. Otherwise, std::terminate will be called. + + ASAN can't handle sudden jumps in control flow very well. This + function is marked as XRPL_NO_SANITIZE_ADDRESS to prevent it from + triggering false positives, since it throws. */ -[[noreturn]] inline void +[[noreturn]] XRPL_NO_SANITIZE_ADDRESS inline void Rethrow() { LogThrow("Re-throwing exception"); throw; } +/* + Logs and throws an exception of type E. + + ASAN can't handle sudden jumps in control flow very well. This + function is marked as XRPL_NO_SANITIZE_ADDRESS to prevent it from + triggering false positives, since it throws. +*/ + template -[[noreturn]] inline void +[[noreturn]] XRPL_NO_SANITIZE_ADDRESS inline void Throw(Args&&... args) { static_assert( diff --git a/include/xrpl/basics/sanitizers.h b/include/xrpl/basics/sanitizers.h new file mode 100644 index 0000000000..b954952848 --- /dev/null +++ b/include/xrpl/basics/sanitizers.h @@ -0,0 +1,13 @@ +#pragma once + +// Helper to disable ASan/HwASan for specific functions +/* + ASAN flags some false positives with sudden jumps in control flow, like + exceptions, or when encountering coroutine stack switches. This macro can be used to disable ASAN + intrumentation for specific functions. +*/ +#if defined(__GNUC__) || defined(__clang__) +#define XRPL_NO_SANITIZE_ADDRESS __attribute__((no_sanitize("address", "hwaddress"))) +#else +#define XRPL_NO_SANITIZE_ADDRESS +#endif diff --git a/src/libxrpl/basics/Number.cpp b/src/libxrpl/basics/Number.cpp index 59a41157db..8bd048ae9e 100644 --- a/src/libxrpl/basics/Number.cpp +++ b/src/libxrpl/basics/Number.cpp @@ -258,7 +258,7 @@ Number::Guard::doRoundUp( } bringIntoRange(negative, mantissa, exponent, minMantissa); if (exponent > maxExponent) - throw std::overflow_error(location); + Throw(std::string(location)); } template @@ -298,7 +298,7 @@ Number::Guard::doRound(rep& drops, std::string location) // or "(maxRep + 1) / 10", neither of which will round up when // converting to rep, though the latter might overflow _before_ // rounding. - throw std::overflow_error(location); // LCOV_EXCL_LINE + Throw(std::string(location)); // LCOV_EXCL_LINE } ++drops; }