The implementation of ListContainer::EraseAndInvalidateAllPointers uses std::copy<char> (which I believe is effectively the same as memcpy) to move the contents after the erased element into the empty space created by the removal. RenderPassDrawQuads contain FilterOperations which contains an std::vector, so memcpy-ing a RenderPassDrawQuad means memcpy-ing a vector which I don't think is guaranteed to be safe.
I've run into a case where iterating over the resulting vector crashes on Windows debug (this caused http://crrev.com/2423483003 to get reverted). More specifically, LayerTreeHostImpl::RemoveRenderPasses removes a RenderPassDrawQuad from a quad_list, causing the next RPDQ in the list to get memcpy'd into the space previously occupied by the removed quad (this happens in ListContainerHelper::CharAllocator::Erase). After that, attempting to copy this RPDQ's filters will crash inside std::vector's copy constructor, while it's iterating over the vector (but only on Windows debug).
Discussing with weiliangc@, we concluded that changing RPDQ to have a unique_ptr<FilterOperations> rather than an actual FilterOperations might be the best fix (assuming that it's safe to memcpy a unique_ptr).
The crash being Windows-debug-only seems a bit surprising. jbroman's theory is that the implementation of std::vector there might have a debug-only check that involves a pointer from the vector's heap-allocated storage back into the vector instance.
Comment 1 by danakj@chromium.org
, Nov 11 2016