KhronosGroup / KhronosGroup/Vulkan-ValidationLayers
GPU-AV: Data race between image layout validation and image destruction
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 1k
- Forks
- 505
- Avg merge
- 11h 25m
- Merged PRs (30d)
- 229
Description
Environment:
- OS: Linux (and most likely Windows)
- GPU and driver version: AMD RX 6900 XT (
Mesa 24.0.9-0ubuntu0.2) - SDK or header version if building from repo: bbb0d4963dd8d279d7b6ee5009cce8fb5218217c (current
main) - Options enabled (synchronization, best practices, etc.): GPU-AV
Describe the Issue
Initially reported here: https://github.com/KhronosGroup/Vulkan-ValidationLayers/issues/4646#issuecomment-1988557333.
There is a data race, reported by TSAN, between when an image layout is validated, and when the image is destroyed.
The image is destroyed immediately after observing that the command buffer has completed execution via vkGetSemaphoreCounterValue (possibly in another thread). Perhaps vkGetSemaphoreCounterValue returns values for no-yet-validated submissions?
I'm pretty sure this issue also manifests itself as a validation error on Windows (and then device lost after a few errors):
Validation Error: [ VUID-vkDestroyBuffer-buffer-00922 ] | MessageID = 0xe4549c11 | vkDestroyBuffer(): can't be called on VkBuffer 0xa36341000000d00b[] that is currently in use by VkCommandBuffer 0x2491bde9070[].
The Vulkan spec states: All submitted commands that refer to buffer, either directly or via a VkBufferView, must have completed execution (https://www.khronos.org/registry/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkDestroyBuffer-buffer-00922)
Here's the full TSAN output:
WARNING: ThreadSanitizer: data race (pid=26285)
Write of size 8 at 0x725000957dc8 by main thread:
#0 std::enable_if<__and_<std::__not_<std::__is_tuple_like<vvl::Image*>>, std::is_move_constructible<vvl::Image*>, std::is_move_assignable<vvl::Image*>>::value, void>::type std::swap<vvl::Image*>(vvl::Image*&, vvl::Image*&) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/move.h:199:11 (libVkLayer_khronos_validation.so+0x11959e5) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#1 std::__shared_ptr<vvl::Image, (__gnu_cxx::_Lock_policy)2>::swap(std::__shared_ptr<vvl::Image, (__gnu_cxx::_Lock_policy)2>&) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/shared_ptr_base.h:1686:2 (libVkLayer_khronos_validation.so+0x1195939) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#2 std::__shared_ptr<vvl::Image, (__gnu_cxx::_Lock_policy)2>::operator=(std::__shared_ptr<vvl::Image, (__gnu_cxx::_Lock_policy)2>&&) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/shared_ptr_base.h:1620:31 (libVkLayer_khronos_validation.so+0x11958da) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#3 std::shared_ptr<vvl::Image>::operator=(std::shared_ptr<vvl::Image>&&) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/shared_ptr.h:440:27 (libVkLayer_khronos_validation.so+0x118c5b9) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#4 vvl::ImageView::Destroy() VVL/layers/state_tracker/image_state.cpp:464:21 (libVkLayer_khronos_validation.so+0x1186e96) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#5 gpuav::ImageView::Destroy() VVL/layers/gpu/resources/gpuav_subclasses.cpp:70:21 (libVkLayer_khronos_validation.so+0x107a449) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#6 void ValidationStateTracker::Destroy<vvl::ImageView, state_object::Traits<vvl::ImageView>>(state_object::Traits<vvl::ImageView>::HandleType) VVL/layers/./state_tracker/state_tracker.h:299:27 (libVkLayer_khronos_validation.so+0x129b0a6) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#7 ValidationStateTracker::PreCallRecordDestroyImageView(VkDevice_T*, VkImageView_T*, VkAllocationCallbacks const*, RecordObject const&) VVL/layers/state_tracker/state_tracker.cpp:514:5 (libVkLayer_khronos_validation.so+0x12651d9) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#8 vulkan_layer_chassis::DestroyImageView(VkDevice_T*, VkImageView_T*, VkAllocationCallbacks const*) VVL/layers/vulkan/generated/chassis.cpp:3265:24 (libVkLayer_khronos_validation.so+0xa7a490) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
Previous read of size 8 at 0x725000957dc8 by thread T18 (mutexes: write M0):
#0 std::__shared_ptr<vvl::Image, (__gnu_cxx::_Lock_policy)2>::operator bool() const /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/shared_ptr_base.h:1670:16 (libVkLayer_khronos_validation.so+0x43f229) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#1 gpuav::Validator::VerifyImageLayout(vvl::CommandBuffer const&, vvl::ImageView const&, VkImageLayout, Location const&, char const*, bool*) const VVL/layers/gpu/descriptor_validation/gpuav_image_layout.cpp:331:10 (libVkLayer_khronos_validation.so+0xfd14e3) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#2 vvl::DescriptorValidator::ValidateDescriptor(std::pair<unsigned int, std::vector<DescriptorRequirement, std::allocator<DescriptorRequirement>>> const&, unsigned int, VkDescriptorType, vvl::ImageDescriptor const&) const VVL/layers/drawdispatch/descriptor_validator.cpp:437:19 (libVkLayer_khronos_validation.so+0x9812ac) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#3 bool vvl::DescriptorValidator::ValidateDescriptors<vvl::DescriptorBindingImpl<vvl::ImageDescriptor>>(std::pair<unsigned int, std::vector<DescriptorRequirement, std::allocator<DescriptorRequirement>>> const&, vvl::DescriptorBindingImpl<vvl::ImageDescriptor> const&, std::vector<unsigned int, std::allocator<unsigned int>> const&) VVL/layers/drawdispatch/descriptor_validator.cpp:135:17 (libVkLayer_khronos_validation.so+0x9952d2) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#4 vvl::DescriptorValidator::ValidateBinding(std::pair<unsigned int, std::vector<DescriptorRequirement, std::allocator<DescriptorRequirement>>> const&, std::vector<unsigned int, std::allocator<unsigned int>> const&) VVL/layers/drawdispatch/descriptor_validator.cpp:168:21 (libVkLayer_khronos_validation.so+0x97e927) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#5 gpuav::CommandBuffer::ValidateBindlessDescriptorSets(Location const&) VVL/layers/gpu/descriptor_validation/gpuav_descriptor_validation.cpp:196:25 (libVkLayer_khronos_validation.so+0xfbcdf4) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#6 gpuav::CommandBuffer::PostProcess(VkQueue_T*, Location const&) VVL/layers/gpu/resources/gpuav_subclasses.cpp:516:25 (libVkLayer_khronos_validation.so+0x107d67b) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#7 gpuav::Queue::Retire(vvl::QueueSubmission&) VVL/layers/gpu/resources/gpuav_subclasses.cpp:664:25 (libVkLayer_khronos_validation.so+0x107ed9d) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#8 vvl::Queue::ThreadFunc() VVL/layers/state_tracker/queue_state.cpp:226:9 (libVkLayer_khronos_validation.so+0x11f35c4) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#9 void std::__invoke_impl<void, void (vvl::Queue::*)(), vvl::Queue*>(std::__invoke_memfun_deref, void (vvl::Queue::*&&)(), vvl::Queue*&&) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/invoke.h:74:14 (libVkLayer_khronos_validation.so+0x11f8215) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#10 std::__invoke_result<void (vvl::Queue::*)(), vvl::Queue*>::type std::__invoke<void (vvl::Queue::*)(), vvl::Queue*>(void (vvl::Queue::*&&)(), vvl::Queue*&&) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/invoke.h:96:14 (libVkLayer_khronos_validation.so+0x11f80c5) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#11 void std::thread::_Invoker<std::tuple<void (vvl::Queue::*)(), vvl::Queue*>>::_M_invoke<0ul, 1ul>(std::_Index_tuple<0ul, 1ul>) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_thread.h:292:13 (libVkLayer_khronos_validation.so+0x11f8062) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#12 std::thread::_Invoker<std::tuple<void (vvl::Queue::*)(), vvl::Queue*>>::operator()() /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_thread.h:299:11 (libVkLayer_khronos_validation.so+0x11f7ff5) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#13 std::thread::_State_impl<std::thread::_Invoker<std::tuple<void (vvl::Queue::*)(), vvl::Queue*>>>::_M_run() /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_thread.h:244:13 (libVkLayer_khronos_validation.so+0x11f7d89) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#14 <null> <null> (libstdc++.so.6+0xed0e3) (BuildId: 757266bafff1752c4f6fbd29014465e90e4ff6c7)
Location is heap block of size 496 at 0x725000957c00 allocated by thread T1:
#0 malloc <null> (libclang_rt.tsan-x86_64.so+0x66324) (BuildId: 83a3c8d2530f3f7484f54738b3cc92e3ba2a603f)
#1 operator new(unsigned long) <null> (libstdc++.so.6+0xbf8eb) (BuildId: 757266bafff1752c4f6fbd29014465e90e4ff6c7)
#2 std::allocator_traits<std::allocator<std::_Sp_counted_ptr_inplace<gpuav::ImageView, std::allocator<void>, (__gnu_cxx::_Lock_policy)2>>>::allocate(std::allocator<std::_Sp_counted_ptr_inplace<gpuav::ImageView, std::allocator<void>, (__gnu_cxx::_Lock_policy)2>>&, unsigned long) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/alloc_traits.h:482:20 (libVkLayer_khronos_validation.so+0xfecc41) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#3 std::__allocated_ptr<std::allocator<std::_Sp_counted_ptr_inplace<gpuav::ImageView, std::allocator<void>, (__gnu_cxx::_Lock_policy)2>>> std::__allocate_guarded<std::allocator<std::_Sp_counted_ptr_inplace<gpuav::ImageView, std::allocator<void>, (__gnu_cxx::_Lock_policy)2>>>(std::allocator<std::_Sp_counted_ptr_inplace<gpuav::ImageView, std::allocator<void>, (__gnu_cxx::_Lock_policy)2>>&) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/allocated_ptr.h:98:21 (libVkLayer_khronos_validation.so+0xfecc41)
#4 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count<gpuav::ImageView, std::allocator<void>, std::shared_ptr<vvl::Image> const&, VkImageView_T*&, VkImageViewCreateInfo const*&, unsigned long&, VkFilterCubicImageViewImageFormatPropertiesEXT const&, gpuav::DescriptorHeap&>(gpuav::ImageView*&, std::_Sp_alloc_shared_tag<std::allocator<void>>, std::shared_ptr<vvl::Image> const&, VkImageView_T*&, VkImageViewCreateInfo const*&, unsigned long&, VkFilterCubicImageViewImageFormatPropertiesEXT const&, gpuav::DescriptorHeap&) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/shared_ptr_base.h:969:19 (libVkLayer_khronos_validation.so+0xfeca07) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#5 std::__shared_ptr<gpuav::ImageView, (__gnu_cxx::_Lock_policy)2>::__shared_ptr<std::allocator<void>, std::shared_ptr<vvl::Image> const&, VkImageView_T*&, VkImageViewCreateInfo const*&, unsigned long&, VkFilterCubicImageViewImageFormatPropertiesEXT const&, gpuav::DescriptorHeap&>(std::_Sp_alloc_shared_tag<std::allocator<void>>, std::shared_ptr<vvl::Image> const&, VkImageView_T*&, VkImageViewCreateInfo const*&, unsigned long&, VkFilterCubicImageViewImageFormatPropertiesEXT const&, gpuav::DescriptorHeap&) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/shared_ptr_base.h:1712:14 (libVkLayer_khronos_validation.so+0xfec90d) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#6 std::shared_ptr<gpuav::ImageView>::shared_ptr<std::allocator<void>, std::shared_ptr<vvl::Image> const&, VkImageView_T*&, VkImageViewCreateInfo const*&, unsigned long&, VkFilterCubicImageViewImageFormatPropertiesEXT const&, gpuav::DescriptorHeap&>(std::_Sp_alloc_shared_tag<std::allocator<void>>, std::shared_ptr<vvl::Image> const&, VkImageView_T*&, VkImageViewCreateInfo const*&, unsigned long&, VkFilterCubicImageViewImageFormatPropertiesEXT const&, gpuav::DescriptorHeap&) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/shared_ptr.h:464:4 (libVkLayer_khronos_validation.so+0xfec81c) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#7 std::shared_ptr<std::enable_if<!is_array<gpuav::ImageView>::value, gpuav::ImageView>::type> std::make_shared<gpuav::ImageView, std::shared_ptr<vvl::Image> const&, VkImageView_T*&, VkImageViewCreateInfo const*&, unsigned long&, VkFilterCubicImageViewImageFormatPropertiesEXT const&, gpuav::DescriptorHeap&>(std::shared_ptr<vvl::Image> const&, VkImageView_T*&, VkImageViewCreateInfo const*&, unsigned long&, VkFilterCubicImageViewImageFormatPropertiesEXT const&, gpuav::DescriptorHeap&) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/shared_ptr.h:1009:14 (libVkLayer_khronos_validation.so+0xfe8066) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#8 gpuav::Validator::CreateImageViewState(std::shared_ptr<vvl::Image> const&, VkImageView_T*, VkImageViewCreateInfo const*, unsigned long, VkFilterCubicImageViewImageFormatPropertiesEXT const&) VVL/layers/gpu/core/gpuav_setup.cpp:49:12 (libVkLayer_khronos_validation.so+0xfe2d05) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#9 ValidationStateTracker::PostCallRecordCreateImageView(VkDevice_T*, VkImageViewCreateInfo const*, VkAllocationCallbacks const*, VkImageView_T**, RecordObject const&) VVL/layers/state_tracker/state_tracker.cpp:484:9 (libVkLayer_khronos_validation.so+0x1264b67) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#10 vulkan_layer_chassis::CreateImageView(VkDevice_T*, VkImageViewCreateInfo const*, VkAllocationCallbacks const*, VkImageView_T**) VVL/layers/vulkan/generated/chassis.cpp:3240:24 (libVkLayer_khronos_validation.so+0xa7a01c) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
Mutex M0 (0x7284001dfb38) created at:
#0 pthread_rwlock_wrlock <null> (libclang_rt.tsan-x86_64.so+0x6b4c2) (BuildId: 83a3c8d2530f3f7484f54738b3cc92e3ba2a603f)
#1 std::__glibcxx_rwlock_wrlock(pthread_rwlock_t*) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/shared_mutex:83:3 (libVkLayer_khronos_validation.so+0x3e948f) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#2 std::__shared_mutex_pthread::lock() /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/shared_mutex:196:19 (libVkLayer_khronos_validation.so+0x415255) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#3 std::shared_mutex::lock() /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/shared_mutex:423:27 (libVkLayer_khronos_validation.so+0x415205) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#4 std::unique_lock<std::shared_mutex>::lock() /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/unique_lock.h:141:17 (libVkLayer_khronos_validation.so+0x4151a7) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#5 std::unique_lock<std::shared_mutex>::unique_lock(std::shared_mutex&) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/unique_lock.h:71:2 (libVkLayer_khronos_validation.so+0x3ea63e) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#6 vvl::CommandBuffer::WriteLock() VVL/layers/./state_tracker/cmd_buffer_state.h:542:41 (libVkLayer_khronos_validation.so+0x4323cc) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#7 LockedSharedPtr<vvl::CommandBuffer, std::unique_lock<std::shared_mutex>> ValidationStateTracker::GetWrite<vvl::CommandBuffer, state_object::Traits<vvl::CommandBuffer>, LockedSharedPtr<vvl::CommandBuffer, std::unique_lock<std::shared_mutex>>>(state_object::Traits<vvl::CommandBuffer>::HandleType) VVL/layers/./state_tracker/state_tracker.h:379:31 (libVkLayer_khronos_validation.so+0x5a0cb2) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#8 ValidationStateTracker::PreCallRecordBeginCommandBuffer(VkCommandBuffer_T*, VkCommandBufferBeginInfo const*, RecordObject const&) VVL/layers/state_tracker/state_tracker.cpp:2267:21 (libVkLayer_khronos_validation.so+0x1275db4) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#9 vulkan_layer_chassis::BeginCommandBuffer(VkCommandBuffer_T*, VkCommandBufferBeginInfo const*) VVL/layers/vulkan/generated/chassis.cpp:1267:24 (libVkLayer_khronos_validation.so+0xa66d0b) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
Thread T18 (tid=26323, running) created by main thread at:
#0 pthread_create <null> (libclang_rt.tsan-x86_64.so+0x67ee5) (BuildId: 83a3c8d2530f3f7484f54738b3cc92e3ba2a603f)
#1 std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State>>, void (*)()) <null> (libstdc++.so.6+0xed1b8) (BuildId: 757266bafff1752c4f6fbd29014465e90e4ff6c7)
#2 std::__detail::_MakeUniq<std::thread>::__single_object std::make_unique<std::thread, void (vvl::Queue::*)(), vvl::Queue*>(void (vvl::Queue::*&&)(), vvl::Queue*&&) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/unique_ptr.h:1070:34 (libVkLayer_khronos_validation.so+0x11f59b9) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#3 vvl::Queue::PreSubmit(std::vector<vvl::QueueSubmission, std::allocator<vvl::QueueSubmission>>&&) VVL/layers/state_tracker/queue_state.cpp:90:27 (libVkLayer_khronos_validation.so+0x11f3493) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#4 gpuav::Queue::PreSubmit(std::vector<vvl::QueueSubmission, std::allocator<vvl::QueueSubmission>>&&) VVL/layers/gpu/resources/gpuav_subclasses.cpp:633:24 (libVkLayer_khronos_validation.so+0x107e950) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#5 ValidationStateTracker::PreCallRecordQueueSubmit2(VkQueue_T*, unsigned int, VkSubmitInfo2 const*, VkFence_T*, RecordObject const&) VVL/layers/state_tracker/state_tracker.cpp:1298:48 (libVkLayer_khronos_validation.so+0x126ce84) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
#6 vulkan_layer_chassis::QueueSubmit2(VkQueue_T*, unsigned int, VkSubmitInfo2 const*, VkFence_T*) VVL/layers/vulkan/generated/chassis.cpp:7914:24 (libVkLayer_khronos_validation.so+0xaa8bb4) (BuildId: 116bb3f83830d9d8e894cbf9f3dec2294bac2744)
Core and sync. validation (including QueueSubmit) don't report any errors.
Expected behavior
No data races
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with gpuav::Validator::VerifyImageLayout in VVL/layers/gpu/descriptor_validation/gpuav_image_layout.cpp and follow its call path through gpuav::CommandBuffer::PostProcess and vvl::Queue::Retire. Compare that path with gpuav::ImageView::Destroy in VVL/layers/gpu/resources/gpuav_subclasses.cpp and vvl::ImageView::Destroy in VVL/layers/state_tracker/image_state.cpp. Done means the TSAN race and the reported validation errors no longer occur during image destruction.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- testing-qa
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100