Commit ec55993d authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook GitHub Bot

Let exceptionStr peek into unknown exception types

Summary: [Folly] Let `exceptionStr` peek into unknown exception types when building with libstdc++ via `std::exception_ptr::__cxa_exception_type()`.

Reviewed By: ot, luciang

Differential Revision: D22521812

fbshipit-source-id: b75811ed4159df81e651c5df1386c406f6ac6d60
parent dde95013
...@@ -18,6 +18,9 @@ ...@@ -18,6 +18,9 @@
#include <utility> #include <utility>
#include <folly/CPortability.h>
#include <folly/CppAttributes.h>
#include <folly/functional/Invoke.h>
#include <folly/lang/Exception.h> #include <folly/lang/Exception.h>
namespace folly { namespace folly {
...@@ -37,17 +40,44 @@ fbstring exceptionStr(const std::exception& e) { ...@@ -37,17 +40,44 @@ fbstring exceptionStr(const std::exception& e) {
return rv; return rv;
} }
namespace {
FOLLY_CREATE_MEMBER_INVOKER(invoke_cxa_exception_type_fn, __cxa_exception_type);
struct fallback_cxa_exception_type_fn {
FOLLY_MAYBE_UNUSED FOLLY_ERASE_HACK_GCC std::type_info const* operator()(
std::exception_ptr const&) const noexcept {
return nullptr;
}
};
using invoke_or_fallback_cxa_exception_type_fn = std::conditional_t<
is_invocable_r_v<
std::type_info const*,
invoke_cxa_exception_type_fn,
std::exception_ptr const&>,
invoke_cxa_exception_type_fn,
fallback_cxa_exception_type_fn>;
FOLLY_INLINE_VARIABLE constexpr invoke_or_fallback_cxa_exception_type_fn
invoke_or_fallback_cxa_exception_type;
} // namespace
fbstring exceptionStr(std::exception_ptr ep) { fbstring exceptionStr(std::exception_ptr ep) {
if (!kHasExceptions) { if (!kHasExceptions) {
return "Exception (catch unavailable)"; return "Exception (catch unavailable)";
} }
auto type = invoke_or_fallback_cxa_exception_type(ep);
return catch_exception( return catch_exception(
[&]() -> fbstring { [&]() -> fbstring {
return catch_exception<std::exception const&>( return catch_exception<std::exception const&>(
[&]() -> fbstring { std::rethrow_exception(std::move(ep)); }, [&]() -> fbstring { std::rethrow_exception(std::move(ep)); },
[](auto&& e) { return exceptionStr(e); }); [](auto&& e) { return exceptionStr(e); });
}, },
[]() -> fbstring { return "<unknown exception>"; }); [&]() -> fbstring {
return type ? demangle(*type) : "<unknown exception>";
});
} }
} // namespace folly } // namespace folly
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <folly/ExceptionString.h> #include <folly/ExceptionString.h>
#include <folly/Portability.h>
#include <folly/portability/GTest.h> #include <folly/portability/GTest.h>
class ExceptionStringTest : public testing::Test {}; class ExceptionStringTest : public testing::Test {};
...@@ -26,3 +27,10 @@ TEST_F(ExceptionStringTest, exception_ptr) { ...@@ -26,3 +27,10 @@ TEST_F(ExceptionStringTest, exception_ptr) {
auto actual = folly::exceptionStr(ptr).toStdString(); auto actual = folly::exceptionStr(ptr).toStdString();
EXPECT_EQ(expected, actual); EXPECT_EQ(expected, actual);
} }
TEST_F(ExceptionStringTest, exception_ptr_unknown) {
auto ptr = std::make_exception_ptr(7);
auto expected = folly::kIsLibstdcpp ? "int" : "<unknown exception>";
auto actual = folly::exceptionStr(ptr).toStdString();
EXPECT_EQ(expected, actual);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment