UncaughtExceptions.h 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. /*
  2. * Copyright 2013-present Facebook, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #pragma once
  17. #include <exception>
  18. #if !defined(FOLLY_FORCE_EXCEPTION_COUNT_USE_STD) && \
  19. (defined(__GNUG__) || defined(__clang__))
  20. #define FOLLY_EXCEPTION_COUNT_USE_CXA_GET_GLOBALS
  21. namespace __cxxabiv1 {
  22. // forward declaration (originally defined in unwind-cxx.h from from libstdc++)
  23. struct __cxa_eh_globals;
  24. // declared in cxxabi.h from libstdc++-v3
  25. extern "C" __cxa_eh_globals* __cxa_get_globals() noexcept;
  26. } // namespace __cxxabiv1
  27. #elif defined(_MSC_VER) && (_MSC_VER >= 1400) && \
  28. (_MSC_VER < 1900) // MSVC++ 8.0 or greater
  29. #define FOLLY_EXCEPTION_COUNT_USE_GETPTD
  30. // forward declaration (originally defined in mtdll.h from MSVCRT)
  31. struct _tiddata;
  32. extern "C" _tiddata* _getptd(); // declared in mtdll.h from MSVCRT
  33. #elif defined(FOLLY_FORCE_EXCEPTION_COUNT_USE_STD) || \
  34. (defined(_MSC_VER) && (_MSC_VER >= 1900)) // MSVC++ 2015
  35. #define FOLLY_EXCEPTION_COUNT_USE_STD
  36. #else
  37. // Raise an error when trying to use this on unsupported platforms.
  38. #error "Unsupported platform, don't include this header."
  39. #endif
  40. namespace folly {
  41. /**
  42. * Returns the number of uncaught exceptions.
  43. *
  44. * This function is based on Evgeny Panasyuk's implementation from here:
  45. * http://fburl.com/15190026
  46. */
  47. inline int uncaught_exceptions() noexcept {
  48. #if defined(FOLLY_EXCEPTION_COUNT_USE_CXA_GET_GLOBALS)
  49. // __cxa_get_globals returns a __cxa_eh_globals* (defined in unwind-cxx.h).
  50. // The offset below returns __cxa_eh_globals::uncaughtExceptions.
  51. return *(reinterpret_cast<unsigned int*>(
  52. static_cast<char*>(static_cast<void*>(__cxxabiv1::__cxa_get_globals())) +
  53. sizeof(void*)));
  54. #elif defined(FOLLY_EXCEPTION_COUNT_USE_GETPTD)
  55. // _getptd() returns a _tiddata* (defined in mtdll.h).
  56. // The offset below returns _tiddata::_ProcessingThrow.
  57. return *(reinterpret_cast<int*>(
  58. static_cast<char*>(static_cast<void*>(_getptd())) + sizeof(void*) * 28 +
  59. 0x4 * 8));
  60. #elif defined(FOLLY_EXCEPTION_COUNT_USE_STD)
  61. return std::uncaught_exceptions();
  62. #endif
  63. }
  64. } // namespace folly