首页 > 解决方案 > FireStore 的未定义行为

问题描述

我在 Mac High Sierra v10.13.4 上使用 Xcode 9.4。我已将 FireStore 集成到我的应用程序中,并启用了“未定义的行为清理程序”。

当我执行以下命令时

- (void)updateData:(NSDictionary<id, id> *)fields
    completion:(nullable void (^)(NSError *_Nullable error))completion

我在控制台中收到此错误

/Users/<folderName>/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/ordered_code.cc:172:21: runtime error: load of misaligned address 0x000106af8a41 for type 'const uint32_t' (aka 'const unsigned int'), which requires 4 byte alignment
0x000106af8a41: note: pointer points here
 69 6e 67  00 76 65 72 73 69 6f 6e  00 54 40 22 4e 53 4e 75  6d 62 65 72 22 2c 52 2c  56 5f 76 65 72

SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /Users/<folderName>/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/ordered_code.cc:172:21 in 
/Users/<folderName>/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/ordered_code.cc:102:3: runtime error: load of misaligned address 0x000106af8a41 for type 'const uint32_t' (aka 'const unsigned int'), which requires 4 byte alignment

0x000106af8a41: note: pointer points here
69 6e 67  00 76 65 72 73 69 6f 6e  00 54 40 22 4e 53 4e 75  6d 62 65 72 22 2c 52 2c  56 5f 76 65 72


SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /Users/<folderName>/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/ordered_code.cc:102:3 in 

这很容易重现

当我在 Xcode 中同时启用 'Thread Sanitizer' 和 'Undefined Behavior' 时,我会在控制台中看到此消息。

================== WARNING: ThreadSanitizer: data race (pid=59902)

Read of size 8 at 0x7b4c00051750 by thread T10:
#0 leveldb::port::AtomicPointer::Acquire_Load() const atomic_pointer.h:135 (leveldb:x86_64+0x73d55)
#1 leveldb::(anonymous namespace)::Limiter::GetAllowed() const env_posix.cc:80 (leveldb:x86_64+0x15ccd6)
#2 leveldb::(anonymous namespace)::Limiter::Acquire() env_posix.cc:55 (leveldb:x86_64+0x15c768)
#3 leveldb::(anonymous namespace)::PosixEnv::NewRandomAccessFile(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, leveldb::RandomAccessFile**) env_posix.cc:354 (leveldb:x86_64+0x1461d6)
#4 leveldb::TableCache::FindTable(unsigned long long, unsigned long long, leveldb::Cache::Handle**) table_cache.cc:56 (leveldb:x86_64+0x228a50)
#5 leveldb::TableCache::Get(leveldb::ReadOptions const&, unsigned long long, unsigned long long, leveldb::Slice const&, void*, void (*)(void*, leveldb::Slice const&, leveldb::Slice const&)) table_cache.cc:112 (leveldb:x86_64+0x229cf9)
#6 leveldb::Version::Get(leveldb::ReadOptions const&, leveldb::LookupKey const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, leveldb::Version::GetStats*) version_set.cc:408 (leveldb:x86_64+0x27fbd6)
#7 leveldb::DBImpl::Get(leveldb::ReadOptions const&, leveldb::Slice const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*) db_impl.cc:1141 (leveldb:x86_64+0x8f922)
#8 firebase::firestore::local::LevelDbTransaction::Get(absl::string_view const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*) <null>:5344896 (SampleApp:x86_64+0x10109be79)
#9 +[FSTLevelDBMigrations schemaVersionWithTransaction:] <null>:5344896 (SampleApp:x86_64+0x100cedd6a)
#10 +[FSTLevelDBMigrations runMigrationsWithTransaction:] <null>:5344896 (SampleApp:x86_64+0x100cedf3e)
#11 -[FSTLevelDB start:] <null>:5344896 (SampleApp:x86_64+0x100cbbf1e)
#12 -[FSTFirestoreClient initializeWithUser:usePersistence:] <null>:5344896 (SampleApp:x86_64+0x100c5f2d3)
#13 __111-[FSTFirestoreClient initWithDatabaseInfo:usePersistence:credentialsProvider:userExecutor:workerDispatchQueue:]_block_invoke <null>:5344896 (SampleApp:x86_64+0x100c5c87a)
#14 -[FSTDispatchQueue dispatchAsync:]::$_1::operator()() const <null>:5344896 (SampleApp:x86_64+0x100bf6a7b)
#15 void std::__1::__invoke_void_return_wrapper<void>::__call<-[FSTDispatchQueue dispatchAsync:]::$_1&>(-[FSTDispatchQueue dispatchAsync:]::$_1&&&) <null>:5344896 (SampleApp:x86_64+0x100bf69cc)
#16 std::__1::__function::__func<-[FSTDispatchQueue dispatchAsync:]::$_1, std::__1::allocator<-[FSTDispatchQueue dispatchAsync:]::$_1>, void ()>::operator()() <null>:5344896 (SampleApp:x86_64+0x100bf5e6e)
#17 std::__1::function<void ()>::operator()() const <null>:5344896 (SampleApp:x86_64+0x100be643b)
#18 firebase::firestore::util::AsyncQueue::ExecuteBlocking(std::__1::function<void ()> const&) <null>:5344896 (SampleApp:x86_64+0x100a67d40)
#19 firebase::firestore::util::AsyncQueue::Wrap(std::__1::function<void ()> const&)::$_0::operator()() const <null>:5344896 (SampleApp:x86_64+0x100a774ac)
#20 void std::__1::__invoke_void_return_wrapper<void>::__call<firebase::firestore::util::AsyncQueue::Wrap(std::__1::function<void ()> const&)::$_0&>(firebase::firestore::util::AsyncQueue::Wrap(std::__1::function<void ()> const&)::$_0&&&) <null>:5344896 (SampleApp:x86_64+0x100a773cc)
#21 std::__1::__function::__func<firebase::firestore::util::AsyncQueue::Wrap(std::__1::function<void ()> const&)::$_0, std::__1::allocator<firebase::firestore::util::AsyncQueue::Wrap(std::__1::function<void ()> const&)::$_0>, void ()>::operator()() <null>:5344896 (SampleApp:x86_64+0x100a7662e)
#22 std::__1::function<void ()>::operator()() const <null>:5344896 (SampleApp:x86_64+0x100be643b)
#23 firebase::firestore::util::internal::DispatchAsync(NSObject<OS_dispatch_queue>*, std::__1::function<void ()>&&)::$_0::operator()(void*) const <null>:5344896 (SampleApp:x86_64+0x100ac1d99)
#24 firebase::firestore::util::internal::DispatchAsync(NSObject<OS_dispatch_queue>*, std::__1::function<void ()>&&)::$_0::__invoke(void*) <null>:5344896 (SampleApp:x86_64+0x100ac1cf8)
#25 __tsan::dispatch_callback_wrap(void*) <null>:5344896 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x62401)
#26 _dispatch_client_callout <null>:5344896 (libdispatch.dylib:x86_64+0x37eb)


Previous write of size 8 at 0x7b4c00051750 by thread T20 (mutexes: write M1134761197468718864):
#0 leveldb::port::AtomicPointer::Release_Store(void*) atomic_pointer.h:141 (leveldb:x86_64+0x57b76)
#1 leveldb::(anonymous namespace)::Limiter::SetAllowed(long) env_posix.cc:85 (leveldb:x86_64+0x158646)
#2 leveldb::(anonymous namespace)::Limiter::Acquire() env_posix.cc:63 (leveldb:x86_64+0x15c82e)
#3 leveldb::(anonymous namespace)::PosixEnv::NewRandomAccessFile(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, leveldb::RandomAccessFile**) env_posix.cc:354 (leveldb:x86_64+0x1461d6)
#4 leveldb::TableCache::FindTable(unsigned long long, unsigned long long, leveldb::Cache::Handle**) table_cache.cc:56 (leveldb:x86_64+0x228a50)
#5 leveldb::TableCache::NewIterator(leveldb::ReadOptions const&, unsigned long long, unsigned long long, leveldb::Table**) table_cache.cc:91 (leveldb:x86_64+0x229712)
#6 leveldb::VersionSet::MakeInputIterator(leveldb::Compaction*) version_set.cc:1274 (leveldb:x86_64+0x2b6b61)
#7 leveldb::DBImpl::DoCompactionWork(leveldb::DBImpl::CompactionState*) db_impl.cc:909 (leveldb:x86_64+0x7ffeb)
#8 leveldb::DBImpl::BackgroundCompaction() db_impl.cc:737 (leveldb:x86_64+0x7c79f)
#9 leveldb::DBImpl::BackgroundCall() db_impl.cc:675 (leveldb:x86_64+0x77f0a)
#10 leveldb::DBImpl::BGWork(void*) db_impl.cc:664 (leveldb:x86_64+0x77cf5)
#11 leveldb::(anonymous namespace)::PosixEnv::BGThread() env_posix.cc:648 (leveldb:x86_64+0x18885b)
#12 leveldb::(anonymous namespace)::PosixEnv::BGThreadWrapper(void*) env_posix.cc:555 (leveldb:x86_64+0x186995)


Location is heap block of size 416 at 0x7b4c00051600 allocated by thread     T10:
#0 operator new(unsigned long) <null>:5344912 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x67bd3)
#1 leveldb::InitDefaultEnv() env_posix.cc:678 (leveldb:x86_64+0x142aac)
#2 pthread_once <null>:5344912 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x28236)
#3 leveldb::Env::Default() env_posix.cc:691 (leveldb:x86_64+0x142a43)
#4 leveldb::Options::Options() options.cc:17 (leveldb:x86_64+0x1ea333)
#5 leveldb::Options::Options() options.cc:27 (leveldb:x86_64+0x1ea5a9)
#6 -[FSTLevelDB createDBWithDirectory:error:] <null>:5344912 (SampleApp:x86_64+0x100cbcb5d)
#7 -[FSTLevelDB start:] <null>:5344912 (SampleApp:x86_64+0x100cbb45d)
#8 -[FSTFirestoreClient initializeWithUser:usePersistence:] <null>:5344912 (SampleApp:x86_64+0x100c5f2d3)
#9 __111-[FSTFirestoreClient initWithDatabaseInfo:usePersistence:credentialsProvider:userExecutor:workerDispatchQueue:]_block_invoke <null>:5344912 (SampleApp:x86_64+0x100c5c87a)
#10 -[FSTDispatchQueue dispatchAsync:]::$_1::operator()() const <null>:5344912 (SampleApp:x86_64+0x100bf6a7b)
#11 void std::__1::__invoke_void_return_wrapper<void>::__call<-[FSTDispatchQueue dispatchAsync:]::$_1&>(-[FSTDispatchQueue dispatchAsync:]::$_1&&&) <null>:5344912 (SampleApp:x86_64+0x100bf69cc)
#12 std::__1::__function::__func<-[FSTDispatchQueue dispatchAsync:]::$_1, std::__1::allocator<-[FSTDispatchQueue dispatchAsync:]::$_1>, void ()>::operator()() <null>:5344912 (SampleApp:x86_64+0x100bf5e6e)
#13 std::__1::function<void ()>::operator()() const <null>:5344912 (SampleApp:x86_64+0x100be643b)
#14 firebase::firestore::util::AsyncQueue::ExecuteBlocking(std::__1::function<void ()> const&) <null>:5344912 (SampleApp:x86_64+0x100a67d40)
#15 firebase::firestore::util::AsyncQueue::Wrap(std::__1::function<void ()> const&)::$_0::operator()() const <null>:5344912 (SampleApp:x86_64+0x100a774ac)
#16 void std::__1::__invoke_void_return_wrapper<void>::__call<firebase::firestore::util::AsyncQueue::Wrap(std::__1::function<void ()> const&)::$_0&>(firebase::firestore::util::AsyncQueue::Wrap(std::__1::function<void ()> const&)::$_0&&&) <null>:5344912 (SampleApp:x86_64+0x100a773cc)
#17 std::__1::__function::__func<firebase::firestore::util::AsyncQueue::Wrap(std::__1::function<void ()> const&)::$_0, std::__1::allocator<firebase::firestore::util::AsyncQueue::Wrap(std::__1::function<void ()> const&)::$_0>, void ()>::operator()() <null>:5344912 (SampleApp:x86_64+0x100a7662e)
#18 std::__1::function<void ()>::operator()() const <null>:5344912 (SampleApp:x86_64+0x100be643b)
#19 firebase::firestore::util::internal::DispatchAsync(NSObject<OS_dispatch_queue>*, std::__1::function<void ()>&&)::$_0::operator()(void*) const <null>:5344912 (SampleApp:x86_64+0x100ac1d99)
#20 firebase::firestore::util::internal::DispatchAsync(NSObject<OS_dispatch_queue>*, std::__1::function<void ()>&&)::$_0::__invoke(void*) <null>:5344912 (SampleApp:x86_64+0x100ac1cf8)
#21 __tsan::dispatch_callback_wrap(void*) <null>:5344912 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x62401)
#22 _dispatch_client_callout <null>:5344912 (libdispatch.dylib:x86_64+0x37eb)

Mutex M1134761197468718864 is already destroyed.

Thread T10 (tid=26697881, running) is a GCD worker thread

Thread T20 (tid=26701255, running) created by thread T10 at:
#0 pthread_create <null>:5344976 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x2678d)
#1 leveldb::(anonymous namespace)::PosixEnv::Schedule(void (*)(void*), void*) env_posix.cc:618 (leveldb:x86_64+0x153ef7)
#2 leveldb::DBImpl::MaybeScheduleCompaction() db_impl.cc:659 (leveldb:x86_64+0x779e9)
#3 leveldb::DB::Open(leveldb::Options const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, leveldb::DB**) db_impl.cc:1522 (leveldb:x86_64+0x9fdeb)
#4 -[FSTLevelDB createDBWithDirectory:error:] <null>:5344976 (SampleApp:x86_64+0x100cbcfd3)
#5 -[FSTLevelDB start:] <null>:5344976 (SampleApp:x86_64+0x100cbb45d)
#6 -[FSTFirestoreClient initializeWithUser:usePersistence:] <null>:5344976 (SampleApp:x86_64+0x100c5f2d3)
#7 __111-[FSTFirestoreClient initWithDatabaseInfo:usePersistence:credentialsProvider:userExecutor:workerDispatchQueue:]_block_invoke <null>:5344976 (SampleApp:x86_64+0x100c5c87a)
#8 -[FSTDispatchQueue dispatchAsync:]::$_1::operator()() const <null>:5344976 (SampleApp:x86_64+0x100bf6a7b)
#9 void std::__1::__invoke_void_return_wrapper<void>::__call<-[FSTDispatchQueue dispatchAsync:]::$_1&>(-[FSTDispatchQueue dispatchAsync:]::$_1&&&) <null>:5344976 (SampleApp:x86_64+0x100bf69cc)
#10 std::__1::__function::__func<-[FSTDispatchQueue dispatchAsync:]::$_1, std::__1::allocator<-[FSTDispatchQueue dispatchAsync:]::$_1>, void ()>::operator()() <null>:5344976 (SampleApp:x86_64+0x100bf5e6e)
#11 std::__1::function<void ()>::operator()() const <null>:5344976 (SampleApp:x86_64+0x100be643b)
#12 firebase::firestore::util::AsyncQueue::ExecuteBlocking(std::__1::function<void ()> const&) <null>:5344976 (SampleApp:x86_64+0x100a67d40)
#13 firebase::firestore::util::AsyncQueue::Wrap(std::__1::function<void ()> const&)::$_0::operator()() const <null>:5344976 (SampleApp:x86_64+0x100a774ac)
#14 void std::__1::__invoke_void_return_wrapper<void>::__call<firebase::firestore::util::AsyncQueue::Wrap(std::__1::function<void ()> const&)::$_0&>(firebase::firestore::util::AsyncQueue::Wrap(std::__1::function<void ()> const&)::$_0&&&) <null>:5344976 (SampleApp:x86_64+0x100a773cc)
#15 std::__1::__function::__func<firebase::firestore::util::AsyncQueue::Wrap(std::__1::function<void ()> const&)::$_0, std::__1::allocator<firebase::firestore::util::AsyncQueue::Wrap(std::__1::function<void ()> const&)::$_0>, void ()>::operator()() <null>:5344976 (SampleApp:x86_64+0x100a7662e)
#16 std::__1::function<void ()>::operator()() const <null>:5344976 (SampleApp:x86_64+0x100be643b)
#17 firebase::firestore::util::internal::DispatchAsync(NSObject<OS_dispatch_queue>*, std::__1::function<void ()>&&)::$_0::operator()(void*) const <null>:5344976 (SampleApp:x86_64+0x100ac1d99)
#18 firebase::firestore::util::internal::DispatchAsync(NSObject<OS_dispatch_queue>*, std::__1::function<void ()>&&)::$_0::__invoke(void*) <null>:5344976 (SampleApp:x86_64+0x100ac1cf8)
#19 __tsan::dispatch_callback_wrap(void*) <null>:5344976 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x62401)
#20 _dispatch_client_callout <null>:5344976 (libdispatch.dylib:x86_64+0x37eb)

SUMMARY: ThreadSanitizer: data race atomic_pointer.h:135 in leveldb::port::AtomicPointer::Acquire_Load() const
==================

标签: xcodefirebasegoogle-cloud-firestore

解决方案


推荐阅读