Open dl3sdo opened 1 year ago
Confirmed. The process crashes deep in Qt code which suggests inconsistent QImage
data rather than a straightforward programmatic error. I'm attaching a partial backtrace for illustration. The bug is easy to replicate.
#0 fetchTransformedBilinearARGB32PM_fast_rotate_helper_avx2(unsigned int*, unsigned int*, QTextureData const&, int&, int&, int, int)
(b=0x7fffffff9cb0, end=0x7fffffffab38, image=..., fx=@0x7fffffff7b30: 526803398, fy=@0x7fffffff7b34: 458696704, fdx=654798, fdy=11429)
at painting/qdrawhelper_avx2.cpp:941
#1 0x00007ffff7401294 in fetchTransformedBilinearARGB32PM<(TextureBlendType)4>(uint*, Operator const*, QSpanData const*, int, int, int)
(buffer=0x7fffffff9cb0, data=<optimized out>, y=<optimized out>, x=<optimized out>, length=930) at painting/qdrawhelper.cpp:3107
#2 0x00007ffff741b32f in BlendSrcGeneric::fetch(int, int, int) (len=<optimized out>, y=0, x=0, this=0x7fffffff7c10)
at painting/qdrawhelper.cpp:4764
#3 handleSpans<BlendSrcGeneric>(int, QT_FT_Span_ const*, QSpanData const*, BlendSrcGeneric&)
(count=256, spans=0x7fffffffbeb0, data=<optimized out>, handler=...) at painting/qdrawhelper.cpp:4708
#4 0x00007ffff7418dbd in blend_src_generic(int, QSpan const*, void*) (count=<optimized out>, spans=<optimized out>, userData=<optimized out>)
at painting/qdrawhelper.cpp:4816
#5 0x00007ffff74abcc3 in QSpanBuffer::flushSpans() (this=0x7fffffffbeb0) at painting/qrasterizer.cpp:113
#6 QSpanBuffer::addSpan(int, unsigned int, int, unsigned char)
(x=<optimized out>, len=<optimized out>, y=255, coverage=255 '\377', this=0x7fffffffbeb0) at painting/qrasterizer.cpp:107
#7 QSpanBuffer::addSpan(int, unsigned int, int, unsigned char)
(coverage=255 '\377', y=255, len=<optimized out>, x=<optimized out>, this=0x7fffffffbeb0) at painting/qrasterizer.cpp:91
#8 QRasterizer::rasterizeLine(QPointF const&, QPointF const&, double, bool) (this=<optimized out>, a=..., b=..., width=<optimized out>,
width@entry=0.52554545454545454, squareCap=squareCap@entry=false) at painting/qrasterizer.cpp:1185
#9 0x00007ffff74549b9 in QRasterPaintEngine::drawImage(QRectF const&, QImage const&, QRectF const&, QFlags<Qt::ImageConversionFlag>)
(this=<optimized out>, r=<optimized out>, img=<optimized out>, sr=...) at ../../include/QtCore/../../src/corelib/tools/qscopedpointer.h:116
#10 0x00007ffff745619c in QRasterPaintEngine::drawImage(QRectF const&, QImage const&, QRectF const&, QFlags<Qt::ImageConversionFlag>)
(sr=..., img=..., r=..., this=0x3078ad0) at ../../include/QtCore/../../src/corelib/tools/qrect.h:674
#11 QRasterPaintEngine::drawImage(QPointF const&, QImage const&) (this=0x3078ad0, p=..., img=...) at painting/qpaintengine_raster.cpp:2189
#12 0x000000000100352e in OpenOrienteering::TemplateImage::drawTemplate(QPainter*, QRectF const&, double, bool, double) const
(this=0x2cf22b0, painter=0x7fffffffcb88, opacity=1) at /data/src/oomapper/src/templates/template_image.cpp:363
#13 0x0000000000587fed in OpenOrienteering::Map::drawTemplates(QPainter*, QRectF const&, int, int, OpenOrienteering::MapView const*, bool) const
(this=0x2bda510, painter=0x7fffffffcb88, bounding_box=..., first_template=0, last_template=0, view=0x2cdebe0, on_screen=true)
at /data/src/oomapper/src/core/map.cpp:876
#14 0x0000000000c78a67 in OpenOrienteering::MapWidget::updateTemplateCache(QImage&, QRect&, int, int, bool)
(this=0x2cf2550, cache=..., dirty_rect=..., first_template=0, last_template=0, use_background=true)
at /data/src/oomapper/src/gui/map/map_widget.cpp:1343
#15 0x0000000000c7b911 in OpenOrienteering::MapWidget::updateAllDirtyCaches() (this=0x2cf2550)
at /data/src/oomapper/src/gui/map/map_widget.cpp:1418
#16 0x0000000000c6212e in OpenOrienteering::MapWidget::paintEvent(QPaintEvent*) (this=0x2cf2550, event=0x7fffffffd010)
at /data/src/oomapper/src/gui/map/map_widget.cpp:870
@lpechacek: thank you for the analysis. My first impression was also that this might be an issue of QT. I found this known (and already solved) issue: QTransform rotate big image will crash
I've tested with Qt 6.4.3 (https://github.com/lpechacek/mapper/tree/master-qt6) and the process crashes as well. I'm not going to dig deeper into this issue despite its attractiveness.
My replication procedure with Mapper (slightly different than Matthias'):
1
in the rotation fieldBacktrace with Qt 6.4.3:
#0 0x00007ffff7424364 in fetchTransformedBilinearARGB32PM_fast_rotate_helper<(TextureBlendType)4>(uint*, uint*, QTextureData const&, int&, int&, int, int)
(b=0x7fff6982ae70, end=0x7fff6982bcf8, image=..., fx=@0x7fff69828db4: 593894098, fy=@0x7fff69828db0: 555169819, fdx=<optimized out>, fdy=11429) at /usr/lib64/gcc/x86_64-suse-linux/13/include/emmintrin.h:607
#1 0x00007ffff743054b in fetchTransformedBilinearARGB32PM<(TextureBlendType)4>(uint*, Operator const*, QSpanData const*, int, int, int)
(buffer=0x7fff6982ae70, data=0x3020cc8, y=<optimized out>, x=<optimized out>, length=<optimized out>)
at /usr/src/debug/qtbase-everywhere-src-6.4.3/src/gui/painting/qdrawhelper.cpp:1954
#2 0x00007ffff7436ab7 in BlendSrcGeneric::fetch(int, int, int, bool)
(fetchDest=false, len=<optimized out>, y=<optimized out>, x=0, this=0x7fff69828e50)
at /usr/src/debug/qtbase-everywhere-src-6.4.3/src/gui/painting/qdrawhelper.cpp:4042
#3 handleSpans<BlendSrcGeneric>(int, QT_FT_Span_ const*, QSpanData const*, Operator const&)::{lambda(int, int)#1}::operator()(int, int) const
(__closure=0x7fffffffb0e0, cStart=<optimized out>, cEnd=<optimized out>)
at /usr/src/debug/qtbase-everywhere-src-6.4.3/src/gui/painting/qdrawhelper.cpp:3994
#4 0x00007ffff743dd34 in handleSpans<BlendSrcGeneric>(int, QT_FT_Span_ const*, QSpanData const*, Operator const&)::{lambda()#1}::operator()() const (__closure=0x28d4260) at /usr/src/debug/qtbase-everywhere-src-6.4.3/src/gui/painting/qdrawhelper.cpp:4016
#5 std::__invoke_impl<void, handleSpans<BlendSrcGeneric>(int, QT_FT_Span_ const*, QSpanData const*, Operator const&)::{lambda()#1}&>(std::__invoke_other, handleSpans<BlendSrcGeneric>(int, QT_FT_Span_ const*, QSpanData const*, Operator const&)::{lambda()#1}&) (__f=...)
at /usr/include/c++/13/bits/invoke.h:61
#6 std::__invoke_r<void, handleSpans<BlendSrcGeneric>(int, QT_FT_Span_ const*, QSpanData const*, Operator const&)::{lambda()#1}&>(handleSpans<BlendSrcGeneric>(int, QT_FT_Span_ const*, QSpanData const*, Operator const&)::{lambda()#1}&) (__fn=...) at /usr/include/c++/13/bits/invoke.h:111
#7 std::_Function_handler<void (), handleSpans<BlendSrcGeneric>(int, QT_FT_Span_ const*, QSpanData const*, Operator const&)::{lambda()#1}>::_M_invoke(std::_Any_data const&) (__functor=<optimized out>) at /usr/include/c++/13/bits/std_function.h:290
#8 0x00007ffff4ebad02 in () at /lib64/libQt6Core.so.6
#9 0x00007ffff4eba95f in () at /lib64/libQt6Core.so.6
#10 0x00007ffff3e92f24 in start_thread () at /lib64/libc.so.6
#11 0x00007ffff3f19f50 in clone3 () at /lib64/libc.so.6
Steps to reproduce
Actual behaviour
Mapper crashes.
Expected behaviour
Mapper should at least issue a warning that the rotation of the template cannot be performed (even if the size of the template does not represent a realistic usecase).
Configuration
Mapper Version: 0.95/Current Master (Debug) Operating System: Win7/Ubuntu LargeTemplateCrash.zip