Hi!
When I’m running my JUCE app on Linux with AddressSanitizer, I sporadically get a memory error due to an overlapping memcpy in juce::EdgeTable. I’m using JUCE v7.0.5, but it looks like this hasn’t been resolved in later JUCE versions.
Unfortunately I’m unable to provide steps for reproducing this bug, I can’t find a clear pattern of when this happens. However, I do have a backtrace:
==26402==ERROR: AddressSanitizer: memcpy-param-overlap: memory ranges [0x62a0005f9548,0x62a0005f9640) and [0x62a0005f9454, 0x62a0005f954c) overlap
#0 0x7ffff7848d29 in __interceptor_memcpy (/usr/lib/libasan.so.8+0x48d29)
#1 0x555556660d9e in juce::EdgeTable::intersectWithEdgeTableLine(int, int const*) /home/void/plugdata/Libraries/JUCE/modules/juce_graphics/geometry/juce_EdgeTable.cpp:612
#2 0x555556663445 in juce::EdgeTable::clipLineToMask(int, int, unsigned char const*, int, int) /home/void/plugdata/Libraries/JUCE/modules/juce_graphics/geometry/juce_EdgeTable.cpp:816
#3 0x5555567f892b in juce::RenderingHelpers::EdgeTableFillers::ImageFill<juce::PixelAlpha, juce::PixelAlpha, false>::clipEdgeTableLine(juce::EdgeTable&, int, int, int) /home/void/plugdata/Libraries/JUCE/modules/juce_graphics/native/juce_RenderingHelpers.h:885
#4 0x5555567f892b in void juce::RenderingHelpers::ClipRegions<juce::RenderingHelpers::SoftwareRendererSavedState>::EdgeTableRegion::straightClipImage<juce::PixelAlpha>(juce::Image::BitmapData const&, int, int, juce::PixelAlpha const*) /home/void/plugdata/Libraries/JUCE/modules/juce_graphics/native/juce_RenderingHelpers.h:1804
#5 0x5555567f892b in juce::RenderingHelpers::ClipRegions<juce::RenderingHelpers::SoftwareRendererSavedState>::EdgeTableRegion::clipToImageAlpha(juce::Image const&, juce::AffineTransform const&, juce::Graphics::ResamplingQuality) /home/void/plugdata/Libraries/JUCE/modules/juce_graphics/native/juce_RenderingHelpers.h:1694
#6 0x5555567ae3ae in juce::RenderingHelpers::ClipRegions<juce::RenderingHelpers::SoftwareRendererSavedState>::RectangleListRegion::clipToImageAlpha(juce::Image const&, juce::AffineTransform const&, juce::Graphics::ResamplingQuality) /home/void/plugdata/Libraries/JUCE/modules/juce_graphics/native/juce_RenderingHelpers.h:1844
#7 0x5555567d1c6d in juce::RenderingHelpers::SavedStateBase<juce::RenderingHelpers::SoftwareRendererSavedState>::clipToImageAlpha(juce::Image const&, juce::AffineTransform const&) /home/void/plugdata/Libraries/JUCE/modules/juce_graphics/native/juce_RenderingHelpers.h:2188
#8 0x5555567d1c6d in juce::RenderingHelpers::StackBasedLowLevelGraphicsContext<juce::RenderingHelpers::SoftwareRendererSavedState>::clipToImageAlpha(juce::Image const&, juce::AffineTransform const&) /home/void/plugdata/Libraries/JUCE/modules/juce_graphics/native/juce_RenderingHelpers.h:2712
#9 0x55555669000e in juce::Graphics::drawImageTransformed(juce::Image const&, juce::AffineTransform const&, bool) const /home/void/plugdata/Libraries/JUCE/modules/juce_graphics/contexts/juce_GraphicsContext.cpp:845
#10 0x55555669000e in juce::Graphics::drawImageTransformed(juce::Image const&, juce::AffineTransform const&, bool) const /home/void/plugdata/Libraries/JUCE/modules/juce_graphics/contexts/juce_GraphicsContext.cpp:836
#11 0x55555669040b in juce::Graphics::drawImageAt(juce::Image const&, int, int, bool) const /home/void/plugdata/Libraries/JUCE/modules/juce_graphics/contexts/juce_GraphicsContext.cpp:803
#12 0x555555e52d4a in StackShadow::renderDropShadow(juce::Graphics&, juce::Path const&, juce::Colour, int, juce::Point<int>, int, float) /home/void/plugdata/Source/Utility/StackShadow.h:735
#13 0x555555e632e0 in PlugDataWindow::paint(juce::Graphics&) /home/void/plugdata/Source/Standalone/PlugDataWindow.h:649
I actually have a whole bunch of backtraces from Linux users, all crashing at EdgeTable::intersectWithEdgeTableLine but coming from completely different parts of my code. If I am making a mistake that is causing this crash, I’d be interested to know too, of course.
The crash happens in the memcpy at line 612 in juce::EdgeTable. This issue should be easy to resolve by replacing memcpy with memmove or std::copy_backward, which should both handle overlapping regions correctly.