gaaclarke 96b0bf0ce3 Speculative fix for memory issues related to retrying image decompression (flutter/engine#55704)
b/371512414

This issue had no reproduction but the stacktrace was provided.  The theory of this fix is that the `ImageResult` type is capturing something that doesn't handle being copied and deallocated twice so instead of copying it, we std::move it into a shared_ptr so that it will only be deallocated once.

Also, I just avoid using a `std::move` when overflowing.  The idea here is maybe sometimes deleting the std::move'd item isn't kosher.  We know from the stacktrace that it has something to do with overflowing because that would be the only case where something is being deleted.

I've added 2 integration tests that exercises the code where the crash appears to be happening.  This is good coverage to have but neither of them reproduced the issue, even with MallocScribble enabled.  That's the best we can do without a reproduction.

```
Thread 7  (id: 0x0000a103)crashed
0x000000010a48ae8c(Flutter -function.h)std::_fl::allocator<impeller::ContextMTL::PendingTasks>::destroy[abi:v15000](impeller::ContextMTL::PendingTasks*)
0x000000010a48b9fc(Flutter -allocator_traits.h:309)impeller::ContextMTL::StoreTaskForGPU(std::_fl::function<void ()> const&, std::_fl::function<void ()> const&)
0x000000010a48b9fc(Flutter -allocator_traits.h:309)impeller::ContextMTL::StoreTaskForGPU(std::_fl::function<void ()> const&, std::_fl::function<void ()> const&)
0x000000010a4d49e4(Flutter -image_decoder_impeller.cc:422)std::_fl::__function::__func<flutter::ImageDecoderImpeller::UploadTextureToPrivate(std::_fl::function<void (sk_sp<flutter::DlImage>, std::_fl::basic_string<char, std::_fl::char_traits<char>, std::_fl::allocator<char>>)>, std::_fl::shared_ptr<impeller::Context> const&, std::_fl::shared_ptr<impeller::DeviceBuffer> const&, SkImageInfo const&, std::_fl::shared_ptr<SkBitmap> const&, std::_fl::optional<SkImageInfo> const&, std::_fl::shared_ptr<fml::SyncSwitch> const&)::$_1, std::_fl::allocator<flutter::ImageDecoderImpeller::UploadTextureToPrivate(std::_fl::function<void (sk_sp<flutter::DlImage>, std::_fl::basic_string<char, std::_fl::char_traits<char>, std::_fl::allocator<char>>)>, std::_fl::shared_ptr<impeller::Context> const&, std::_fl::shared_ptr<impeller::DeviceBuffer> const&, SkImageInfo const&, std::_fl::shared_ptr<SkBitmap> const&, std::_fl::optional<SkImageInfo> const&, std::_fl::shared_ptr<fml::SyncSwitch> const&)::$_1>, void ()>::operator()()
0x000000010a06c234(Flutter -function.h:512)fml::SyncSwitch::Execute(fml::SyncSwitch::Handlers const&) const
0x000000010a4d42f8(Flutter -image_decoder_impeller.cc:408)flutter::ImageDecoderImpeller::UploadTextureToPrivate(std::_fl::function<void (sk_sp<flutter::DlImage>, std::_fl::basic_string<char, std::_fl::char_traits<char>, std::_fl::allocator<char>>)>, std::_fl::shared_ptr<impeller::Context> const&, std::_fl::shared_ptr<impeller::DeviceBuffer> const&, SkImageInfo const&, std::_fl::shared_ptr<SkBitmap> const&, std::_fl::optional<SkImageInfo> const&, std::_fl::shared_ptr<fml::SyncSwitch> const&)
0x000000010a4d3838(Flutter -image_decoder_impeller.cc:538)std::_fl::__function::__func<flutter::ImageDecoderImpeller::Decode(fml::RefPtr<flutter::ImageDescriptor>, unsigned int, unsigned int, std::_fl::function<void (sk_sp<flutter::DlImage>, std::_fl::basic_string<char, std::_fl::char_traits<char>, std::_fl::allocator<char>>)> const&)::$_1, std::_fl::allocator<flutter::ImageDecoderImpeller::Decode(fml::RefPtr<flutter::ImageDescriptor>, unsigned int, unsigned int, std::_fl::function<void (sk_sp<flutter::DlImage>, std::_fl::basic_string<char, std::_fl::char_traits<char>, std::_fl::allocator<char>>)> const&)::$_1>, void ()>::operator()()
0x000000010a06dd1c(Flutter -function.h:512)fml::ConcurrentMessageLoopDarwin::ExecuteTask(std::_fl::function<void ()> const&)
0x000000010a06737c(Flutter -concurrent_message_loop.cc:101)void* std::_fl::__thread_proxy[abi:v15000]<std::_fl::tuple<std::_fl::unique_ptr<std::_fl::__thread_struct, std::_fl::default_delete<std::_fl::__thread_struct>>, fml::ConcurrentMessageLoop::ConcurrentMessageLoop(unsigned long)::$_0>>(void*)
0x000000021d4ff378(libsystem_pthread.dylib + 0x00006378)_pthread_start
```

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
2024-10-07 20:46:16 +00:00
..

ui_unittest Fixtures

The files in this directory are used by the ui_unittests binary.

The ui_test.dart file is either JIT or AOT compiled depending on the runtime mode of the test binary. Other files in this folder are used by tests to verify functionality.

See //lib/ui/BUILD.gn and //testing/testing.gni for the build rules and GN template definitions that determine which files get included and compiled here.