bitsery icon indicating copy to clipboard operation
bitsery copied to clipboard

bug in apple libc++ ARM hash_code function

Open victorstewart opened this issue 1 year ago • 2 comments

if you check the backtrace below you'll see that the code crashes on the __ptr dereference in __non_unique_impl:: __hash because it's dereferencing a junk address.

apparently __non_unique_impl is a specialization specifically and only for apple arm. crazy that it's broken out of the box.

so we definitely need some kind of workaround for when called on apple platforms.

struct __non_unique_impl : __string_impl_base {
    _LIBCPP_INLINE_VISIBILITY _LIBCPP_ALWAYS_INLINE
    static size_t __hash(__type_name_t __ptr) _NOEXCEPT {
      size_t __hash = 5381;
      while (unsigned char __c = static_cast<unsigned char>(*__ptr++))
        __hash = (__hash * 33) ^ __c;
      return __hash;
    }
...

#0 0x0000000102672e5c in std::__type_info_implementations::__non_unique_impl::__hash(char const*) [inlined] at /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.0.sdk/usr/include/c++/v1/typeinfo:222 #1 0x0000000102672e48 in std::__type_info_implementations::__non_unique_arm_rtti_bit_impl::__hash(unsigned long) [inlined] at /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.0.sdk/usr/include/c++/v1/typeinfo:253 #2 0x0000000102672e14 in std::type_info::hash_code() const at /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.0.sdk/usr/include/c++/v1/typeinfo:338 #3 0x0000000102692efc in unsigned long bitsery::ext::StandardRTTI::get<Person>(Person&) at /x/libraries/include/bitsery/ext/utils/rtti_utils.h:41 #4 0x0000000102692e50 in void bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI::deserialize<bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >, Person, void bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI>::deserializeImpl<bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >, Person*, void bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >::ext<Person*, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI> >(Person*&, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI> const&)::'lambda'(bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >&, Person&)>(bitsery::ext::MemResourceBase*, bitsery::ext::pointer_utils::PLCInfoDeserializer&, Person*&, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI>&, void bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >::ext<Person*, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI> >(Person*&, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI> const&)::'lambda'(bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >&, Person&)&&, std::__1::integral_constant<bool, true>, std::__1::integral_constant<bitsery::ext::PointerOwnershipType, (bitsery::ext::PointerOwnershipType)1>) const::'lambda'(std::__1::shared_ptrbitsery::ext::PolymorphicHandlerBase const&), void bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI>::deserializeImpl<bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >, Person*, void bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >::ext<Person*, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI> >(Person*&, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI> const&)::'lambda'(bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >&, Person&)>(bitsery::ext::MemResourceBase*, bitsery::ext::pointer_utils::PLCInfoDeserializer&, Person*&, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI>&, void bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >::ext<Person*, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI> >(Person*&, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI> const&)::'lambda'(bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >&, Person&)&&, std::__1::integral_constant<bool, true>, std::__1::integral_constant<bitsery::ext::PointerOwnershipType, (bitsery::ext::PointerOwnershipType)1>) const::'lambda0'(std::__1::shared_ptrbitsery::ext::PolymorphicHandlerBase const&)>(Person*&, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI>, void bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >::ext<Person, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI> >(Person*&, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI> const&)::'lambda'(bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >&, Person&), void bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI>::deserializeImpl<bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >, Person*, void bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >::ext<Person*, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI> >(Person*&, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI> const&)::'lambda'(bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >&, Person&)>(bitsery::ext::MemResourceBase*, bitsery::ext::pointer_utils::PLCInfoDeserializer&, Person*&, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI>&, void bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >::ext<Person*, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI> >(Person*&, bitsery::ext::pointer_utils::PointerObjectExtensionBase<bitsery::ext::pointer_details::PtrOwnerManager, bitsery::ext::PolymorphicContext, bitsery::ext::StandardRTTI> const&)::'lambda'(bitsery::Deserializer<bitsery::InputBufferAdapter<String, FastConfig>, std::__1::tuple<bitsery::ext::PointerLinkingContext, bitsery::ext::PolymorphicContextbitsery::ext::StandardRTTI > >&, Person&)&&, std::__1::integral_constant<bool, true>, std::__1::integral_constant<bitsery::ext::PointerOwnershipType, (bitsery::ext::PointerOwnershipType)1>) const::'lambda0'(std::__1::shared_ptrbitsery::ext::PolymorphicHandlerBase const&)) const at /x/libraries/include/bitsery/ext/utils/polymorphism_utils.h:261

victorstewart avatar Oct 23 '22 15:10 victorstewart

i solved this by creating my own RTTI type then my own pointer extension, but the fundamental issue remains

struct StaticRTTI {

   template<typename TBase>
   static size_t get(TBase& obj) 
    {
        return (size_t)static_type_info::getTypeIndex<TBase>();
    }

     template<typename TBase>
     static constexpr size_t get() 
     {
        return (size_t)static_type_info::getTypeIndex<TBase>();
     }

     template<typename TBase, typename TDerived>
     static constexpr TDerived* cast(TBase* obj) 
     {
        static_assert(!std::is_pointer<TDerived>::value, "");
        return dynamic_cast<TDerived*>(obj);
     }

     template<typename TBase>
     static constexpr bool isPolymorphic() 
     {
        return std::is_polymorphic<TBase>::value;
     }
  };

using PointerOwner = bitsery::ext::PointerOwnerBase<bitsery::ext::StaticRTTI>;

victorstewart avatar Oct 25 '22 00:10 victorstewart

Thanks for sharing!

I'll leave this ticket open, so people would know about it.

fraillt avatar Dec 01 '22 11:12 fraillt