ImageProcessing-ElectronicPublications / scantailor-experimental

Scan Tailor Experimental is an interactive post-processing tool for scanned pages.
https://github.com/Tulon/scantailor/tree/experimental
GNU General Public License v3.0
30 stars 0 forks source link

Crash after clicking dewarp button #17

Closed mara004 closed 6 months ago

mara004 commented 7 months ago

On my sample, STEX always crashes when clicking the dewarp button ("distortion type -> curved lines") The same happened with my installs of the original Tulon STEX, and with ST Deviant.

Head of backtrace:

#0  0x00000000005f1bf7 in XSpline::linearCombinationFor(spfit::FittableSpline::LinearCoefficient*, int, double) const ()
#1  0x00000000005f21bf in XSpline::pointAtImpl(int, double) const ()
#2  0x00000000005f2c95 in XSpline::maybeAddMoreSamples(VirtualFunction3<void, QPointF, double, spfit::FittableSpline::SampleFlags>&, double, double, double, double, double, QPointF const&, double, QPointF const&) const ()

XSpline::maybeAddMoreSamples was then repeated countless times below.

mara004 commented 7 months ago

https://github.com/ImageProcessing-ElectronicPublications/scantailor-experimental/issues/10 sounds related

plzombie commented 7 months ago

@mara004 Can you attach some example (.zip with project)?

mara004 commented 7 months ago

@mara004 Can you attach some example (.zip with project)?

Here you go: stex-z_bug_017.zip

plzombie commented 7 months ago

So, on windows it performed fine. Need to debug under linux

zvezdochiot commented 7 months ago

@plzombie say:

Need to debug under linux

Попробую.

So, on linux it performed fine. (Geometric Distorsion: Curves) :ok: STEX 0.2023.11.29

  1. stex-4
  2. ...
  3. stex-6
plzombie commented 7 months ago

@mara004 can you describe distro/stex version/build flags?

mara004 commented 7 months ago

Incidentally I was just about to do so 😅 I'm on Fedora 37 and built today from latest git main 0a01ed7. Without OpenCL, because I didn't manage to set it up.

zvezdochiot commented 7 months ago

Hi @mara004 .

ldd /usr/bin/scantailor-experimental

or

ldd ./scantailor-experimental
mara004 commented 7 months ago
linux-vdso.so.1 (0x00007ffe7ad8c000)
libtiff.so.5 => /lib64/libtiff.so.5 (0x00007f4910fb1000)
libpng16.so.16 => /lib64/libpng16.so.16 (0x00007f4910f77000)
libz.so.1 => /lib64/libz.so.1 (0x00007f4910f5d000)
libjpeg.so.62 => /lib64/libjpeg.so.62 (0x00007f4910eda000)
libOpenGL.so.0 => /lib64/libOpenGL.so.0 (0x00007f4910eaf000)
libGLX.so.0 => /lib64/libGLX.so.0 (0x00007f4910e7b000)
libQt5OpenGL.so.5 => /lib64/libQt5OpenGL.so.5 (0x00007f4910e1a000)
libQt5Xml.so.5 => /lib64/libQt5Xml.so.5 (0x00007f4910dd2000)
libQt5Widgets.so.5 => /lib64/libQt5Widgets.so.5 (0x00007f4910600000)
libQt5Gui.so.5 => /lib64/libQt5Gui.so.5 (0x00007f490fe00000)
libQt5Core.so.5 => /lib64/libQt5Core.so.5 (0x00007f490f800000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f490f400000)
libm.so.6 => /lib64/libm.so.6 (0x00007f4910520000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f4910db0000)
libc.so.6 => /lib64/libc.so.6 (0x00007f490f223000)
libwebp.so.7 => /lib64/libwebp.so.7 (0x00007f4910d41000)
libzstd.so.1 => /lib64/libzstd.so.1 (0x00007f4910467000)
libjbig.so.2.1 => /lib64/libjbig.so.2.1 (0x00007f4910d31000)
libGLdispatch.so.0 => /lib64/libGLdispatch.so.0 (0x00007f490f747000)
libX11.so.6 => /lib64/libX11.so.6 (0x00007f490f0dc000)
libXext.so.6 => /lib64/libXext.so.6 (0x00007f4910d1c000)
libGL.so.1 => /lib64/libGL.so.1 (0x00007f490fd79000)
libharfbuzz.so.0 => /lib64/libharfbuzz.so.0 (0x00007f490f65b000)
libsystemd.so.0 => /lib64/libsystemd.so.0 (0x00007f490efff000)
libdouble-conversion.so.3 => /lib64/libdouble-conversion.so.3 (0x00007f4910452000)
libicui18n.so.71 => /lib64/libicui18n.so.71 (0x00007f490ec00000)
libicuuc.so.71 => /lib64/libicuuc.so.71 (0x00007f490ea03000)
libpcre2-16.so.0 => /lib64/libpcre2-16.so.0 (0x00007f490ef71000)
libglib-2.0.so.0 => /lib64/libglib-2.0.so.0 (0x00007f490e8c2000)
/lib64/ld-linux-x86-64.so.2 (0x00007f4911062000)
libsharpyuv.so.0 => /lib64/libsharpyuv.so.0 (0x00007f4910d10000)
libxcb.so.1 => /lib64/libxcb.so.1 (0x00007f490ef46000)
libfreetype.so.6 => /lib64/libfreetype.so.6 (0x00007f490e7f4000)
libgraphite2.so.3 => /lib64/libgraphite2.so.3 (0x00007f490f639000)
libcap.so.2 => /lib64/libcap.so.2 (0x00007f4910446000)
liblzma.so.5 => /lib64/liblzma.so.5 (0x00007f490e7c0000)
liblz4.so.1 => /lib64/liblz4.so.1 (0x00007f490e79d000)
libicudata.so.71 => /lib64/libicudata.so.71 (0x00007f490ca00000)
libpcre2-8.so.0 => /lib64/libpcre2-8.so.0 (0x00007f490c963000)
libXau.so.6 => /lib64/libXau.so.6 (0x00007f491043e000)
libbz2.so.1 => /lib64/libbz2.so.1 (0x00007f490ef33000)
libbrotlidec.so.1 => /lib64/libbrotlidec.so.1 (0x00007f490fd6c000)
libbrotlicommon.so.1 => /lib64/libbrotlicommon.so.1 (0x00007f490e77a000)
mara004 commented 7 months ago

I also specified -DOpenGL_GL_PREFERENCE=GLVND as I had needed that last time to build Tulon's STEX.

zvezdochiot commented 7 months ago
diff: deb rpm
- libOpenGL.so.0

:warning: I can't debug calls to a library that I don't use.

mara004 commented 7 months ago

I've recompiled in legacy OpenGL mode (i.e. without the above flag), which makes libOpenGL.so.0 disappear from the ldd output. Let me see...

mara004 commented 7 months ago

Same crash. The way I understand the backtrace the latest call also does not seem to be in libOpenGL, but in ST itself.

zvezdochiot commented 7 months ago

@mara004 .

:warning: I can't repeat this. And without this I can’t debug.

plzombie commented 7 months ago

@mara004 I'm installing Fedora 37. Will try to debug tomorrow

mara004 commented 7 months ago

⚠️ I can't repeat this. And without this I can’t debug.

@zvezdochiot Sorry, I'm confused. Did not https://github.com/ImageProcessing-ElectronicPublications/scantailor-experimental/issues/17#issuecomment-1841477904 answer this ... ?

zvezdochiot commented 7 months ago

@mara004 say:

Sorry, I'm confused.

No confusion. It’s just that this situation cannot be reproduced on my build of the deb package and on my system.

plzombie commented 7 months ago

Just tested. Target "-D CMAKE_BUILD_TYPE=Debug"" works file. "Release" and "RelWithDebInfo" crashes

@zvezdochiot how to enable qDebug? It's not working at all for me

P.S. Gnome 40 is the worst DE ever

zvezdochiot commented 7 months ago

@plzombie say:

how to enable qDebug?

#include <QDebug>
...
qDebug() << "Бла-бла-бла..." << var1 << var2 << var3 << ... ;

После чего запускаешь STEX из CMD (или из shell) и читаешь "надписи" в консоле.

mara004 commented 7 months ago

P.S. Gnome 40 is the worst DE ever

(FWIW you could have used one of the spins. I'm on KDE Plasma - disliking Gnome 3/40 too.)

mara004 commented 7 months ago

@plzombie I can reproduce your findings. The debug build doesn't crash on this step and actually finishes to compute a pretty reasonable mesh, although it takes very long.

As an aside, AFAICS it's not currently possible to disable the initial auto-calculation. An option to bypass it and use manual mesh in the first place would be nice.

mara004 commented 7 months ago

However, I have reached a second, constantly reproducible crash at the output stage now (same project). Head of backtrace attached: stex-z_bug_017_2.bt.txt

plzombie commented 7 months ago

About second bug. It seems like CachingFactory is trying to create itself in an infinite loop (another object is created in constructor). I'm not a C++ guy so I can't help with this. Maybe we should check differences between GCC 12.3.1 (Fedora 37) and 12.2.0 (Debian 12). Also reproduced on version 0.2017.04.10 изображение

plzombie commented 6 months ago

@zvezdochiot Попытался ещё потыкать. qDebug у меня отказывается работать в любом виде, так что только в отладчике сидел. Удалось воспроизвести в Debian 12 вылет на вкладке Вывод. В том же самом месте, что и в Fedora 37. Ещё посмотрел что в STA, думал, может там уже что-то фиксили похожее, но там вообще нет класса CachingFactory.

zvezdochiot commented 6 months ago

@plzombie .

foundation/CMakeLists.txt:16:    CachingFactory.h
foundation/CachingFactory.h:32: * @note Multiple copies of CachingFactory share the same cache.
foundation/CachingFactory.h:36:class CachingFactory
foundation/CachingFactory.h:50:    explicit CachingFactory(F&& factory)
foundation/CachingFactory.h:85: * @brief Wraps a factory functor into a CachingFactory.
foundation/CachingFactory.h:88:CachingFactory<T> cachingFactory(F&& factory)
foundation/CachingFactory.h:90:    return CachingFactory<T>(std::forward<F>(factory));
LoadFileTask.cpp:20:#include "CachingFactory.h"
LoadFileTask.cpp:104:            CachingFactory<GrayImage> gray_image_factory([image]()
filters/fix_orientation/Task.cpp:97:    CachingFactory<imageproc::GrayImage> const& gray_orig_image_factory,
filters/fix_orientation/Task.h:24:#include "CachingFactory.h"
filters/fix_orientation/Task.h:67:        CachingFactory<imageproc::GrayImage> const& gray_orig_image_factory,
filters/deskew/Task.cpp:214:    CachingFactory<imageproc::GrayImage> const& gray_orig_image_factory,
filters/deskew/Task.cpp:274:    CachingFactory<imageproc::GrayImage> const& gray_orig_image_factory,
filters/deskew/Task.cpp:304:    CachingFactory<imageproc::GrayImage> const& gray_orig_image_factory,
filters/deskew/Task.cpp:388:    CachingFactory<imageproc::GrayImage> const& gray_orig_image_factory,
filters/deskew/Task.cpp:495:    CachingFactory<imageproc::GrayImage> const& gray_orig_image_factory,
filters/deskew/Task.h:26:#include "CachingFactory.h"
filters/deskew/Task.h:71:        CachingFactory<imageproc::GrayImage> const& gray_orig_image_factory,
filters/deskew/Task.h:84:        CachingFactory<imageproc::GrayImage> const& gray_orig_image_factory,
filters/deskew/Task.h:91:        CachingFactory<imageproc::GrayImage> const& gray_orig_image_factory,
filters/deskew/Task.h:98:        CachingFactory<imageproc::GrayImage> const& gray_orig_image_factory,
filters/deskew/Task.h:105:        CachingFactory<imageproc::GrayImage> const& gray_orig_image_factory,
filters/select_content/Task.cpp:102:    CachingFactory<imageproc::GrayImage> const& gray_orig_image_factory,
filters/select_content/Task.h:25:#include "CachingFactory.h"
filters/select_content/Task.h:68:        CachingFactory<imageproc::GrayImage> const& gray_orig_image_factory,
filters/page_layout/Task.cpp:101:    CachingFactory<imageproc::GrayImage> const& gray_orig_image_factory,
filters/page_layout/Task.h:26:#include "CachingFactory.h"
filters/page_layout/Task.h:68:        CachingFactory<imageproc::GrayImage> const& gray_orig_image_factory,
filters/page_split/Task.cpp:129:    CachingFactory<imageproc::GrayImage> const& gray_orig_image_factory,
filters/page_split/Task.h:27:#include "CachingFactory.h"
filters/page_split/Task.h:74:        CachingFactory<imageproc::GrayImage> const& gray_orig_image_factory,
filters/output/Task.cpp:61:#include "CachingFactory.h"
filters/output/Task.cpp:91:              CachingFactory<QImage> const& cached_transformed_orig_image,
filters/output/Task.cpp:92:              CachingFactory<QImage> const& cached_downscaled_transformed_orig_image,
filters/output/Task.cpp:116:    CachingFactory<QImage> m_cachedTransformedOrigImage;
filters/output/Task.cpp:117:    CachingFactory<QImage> m_cachedDownscaledTransformedOrigImage;
filters/output/Task.cpp:154:    CachingFactory<imageproc::GrayImage> const& gray_orig_image_factory,
filters/output/Task.cpp:173:    CachingFactory<imageproc::GrayImage> const& gray_orig_image_factory,
filters/output/Task.cpp:520:    CachingFactory<QImage> const& cached_transformed_orig_image,
filters/output/Task.cpp:521:    CachingFactory<QImage> const& cached_downscaled_transformed_orig_image,
filters/output/OnDemandPictureZoneEditor.h:25:#include "CachingFactory.h"
filters/output/OnDemandPictureZoneEditor.h:51:        CachingFactory<QImage> const& cached_transformed_orig_image,
filters/output/OnDemandPictureZoneEditor.h:52:        CachingFactory<QImage> const& cached_downscaled_transformed_orig_image,
filters/output/OnDemandPictureZoneEditor.h:68:    CachingFactory<QImage> m_cachedTransformedOrigImage;
filters/output/OnDemandPictureZoneEditor.h:69:    CachingFactory<QImage> m_cachedDownscaledTransformedOrigImage;
filters/output/Task.h:28:#include "CachingFactory.h"
filters/output/Task.h:70:        CachingFactory<imageproc::GrayImage> const& gray_orig_image_factory,
filters/output/Task.h:80:        CachingFactory<imageproc::GrayImage> const& gray_orig_image_factory,
filters/output/OutputGenerator.cpp:274:    CachingFactory<imageproc::GrayImage> const& gray_orig_image_factory,
filters/output/OutputGenerator.h:37:#include "CachingFactory.h"
filters/output/OutputGenerator.h:101:        CachingFactory<imageproc::GrayImage> const& gray_orig_image_factory,
filters/output/OnDemandPictureZoneEditor.cpp:43:        CachingFactory<QImage> const& cached_transformed_orig_image,
filters/output/OnDemandPictureZoneEditor.cpp:44:        CachingFactory<QImage> const& cached_downscaled_transformed_orig_image);
filters/output/OnDemandPictureZoneEditor.cpp:49:    CachingFactory<QImage> m_cachedTransformedOrigImage;
filters/output/OnDemandPictureZoneEditor.cpp:50:    CachingFactory<QImage> m_cachedDownscaledTransformedOrigImage;
filters/output/OnDemandPictureZoneEditor.cpp:69:    CachingFactory<QImage> const& cached_transformed_orig_image,
filters/output/OnDemandPictureZoneEditor.cpp:70:    CachingFactory<QImage> const& cached_downscaled_transformed_orig_image,
filters/output/OnDemandPictureZoneEditor.cpp:138:    CachingFactory<QImage> const& cached_transformed_orig_image,
filters/output/OnDemandPictureZoneEditor.cpp:139:    CachingFactory<QImage> const& cached_downscaled_transformed_orig_image)

:question: А что вообще делает этот "кеш"? И нельзя ли (коли от такой) как-нибудь без него обойтись (вырезать то бишь)?

PS: В scantailor-deviant никакого такого кэша тоже нет, но там деварпинг от scantailor-experimental спокойно себе работает (а в начальном сообщении написано, что ST Deviant тоже падает).

PS: :question: А нельзя ли какой-нибудь флаг припаяить, чтобы GCC вёл себя как 12.2.0?

noobie-iv commented 6 months ago

Скорее, надо в книжках поискать реализацию шаблонного кеширования. Там, небось, в разных стандартах плюсов надо разную реализацию сделать. А сама фабрика, судя по длине кода, вообще готовая идиома, утянутая у какого-нибудь Мейерса из очередного "супер С++", надо только найти, из какой конкретно книжки. Тот же STD тормозит, как и STU/STA, не хотелось бы явного лидера по скорости тормозить до их уровня.

Если такую фабрику отдельным тестовым проектом "в один класс" сделать - тоже вылетать будет? Под вынью-то все работает, а ставить Фёдора и разбираться, что там где лежит, для меня перебор.

Кто знает учебник по шаблонам? Не для чайников, типа "вот шаблон min/max, вот шаблон "массив, теперь вы знаете кунг-фу". А с внятными объяснениями и примерами, для чего это все надо. Нашел лекции Константина Владимирова, https://sourceforge.net/projects/cpp-lects-rus/, но они что-то сильно затеоретизированы, для быстрого старта не годятся. А книгу Вандевурда под тыщщу страниц мне пять лет читать придется.

plzombie commented 6 months ago

@noobie-iv Оно теперь и под дебианом вылетает, скоро везде будет вылетать. Возможно и под виндой теперь тоже вылетает с последней версией компилятора (я 2019 собираю до сих пор). Там надо смотреть теорию по std::function и std::forward

zvezdochiot commented 6 months ago

@plzombie say:

скоро везде будет вылетать.

Так может надобно:

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

применить? Али ещё какой?

noobie-iv commented 6 months ago

Я собираю в VS2022, у меня вылетов нет. Стандарт языка 14, ниже выставить нельзя, можно только повысить до 17/20. Интересу ради пересобрал на 17 - вылетов тоже нет.

017

plzombie commented 6 months ago

@noobie-iv А на стадии Вывод что? Вторая ошибка (которую я воспроизвёл в дебиане 12) появляется именно на стадии 6

noobie-iv commented 6 months ago

@plzombie Вывод здорового компилятора:

017-2

zvezdochiot commented 6 months ago

@noobie-iv . А чего версия STEX == 0.2023.11.21? С 0.2023.12.25 что то не так? Мне же важно. Да и не только мне.

@plzombie . Попробуй в Федоре в CMakeLists.txt вправить:

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True)
noobie-iv commented 6 months ago

Последние изменения не подтянул. Но и с ними в Багдаде все стабильно:

017-3

zvezdochiot commented 6 months ago

@noobie-iv . Тогда вопрос тот же: Почему Deviant тоже падает в Федоре, ежели никакого кэша в нём - днём с огнём...?

plzombie commented 6 months ago

@noobie-iv . Тогда вопрос тот же: Почему Deviant тоже падает в Федоре, ежели никакого кэша в нём - днём с огнём...?

Он падает на деварпинге. А на кэше падает на стадии Вывод

zvezdochiot commented 6 months ago

@plzombie . Так с деварпом что не так? Может стоит его отследить на Deviant-е? Как минимум один иструмент с рабочим и удобным деварпом в строю останется? А уж траблы с кэшем оставить на длительное и нудное чтение мануалов STD?

noobie-iv commented 6 months ago

std::function и std::forward

Насколько я в курсе, std::function - это плюсовая шаблонная обертка над указателем на функцию (заодно она и объекты-функторы обработает, и новомодные лямбды). Где в чистых сях писали:

void foo(){} // функция
typedef void (*function)(); // тип указателя на функцию
function f = &foo; // указатель на функцию
f();  // вызов функции через указатель

там в плюсах пользуют

std::function<void()> f  = &foo;  // указатель на функцию
f();   // вызов функции через указатель

А у std::forward - внутри вроде как просто приведение типа. Когда в шаблонную функцию передается правая ссылка && (которая обеспечивает оптимизацию, вызывая вместо копирования перемещение), она превращается в обычную левую & ссылку без волшебных свойств. А forward это волшебство восстанавливает по требованию. Пишут, что forward специально придумали для пробрасывания правых ссылок с оптимизацией внутрь шаблонов, чтобы перенос продолжал срабатывать и внутри. То есть никаких чудес, кроме static_cast, она не делает, и никаких дополнительных объектов не создает; наоборот, убирает лишние копирования.

Получается, внутри конструктора CachingFactory создается реальный объект вызовом make_shared, а дальше он перемещается (а не копируется, благодаря forward) внутрь SharedState, и там сохраняется в указателе factory.

Может, разные верси компилятора эти шаблоны по-разному понимают?

plzombie commented 6 months ago

@zvezdochiot вот std::forward там вызывается в конструкторе CacheFactory и в итоге создаётся новый объект CacheFactory, который создаёт новый объект, который создаёт новый объект и так до бесконечности, пока память не закончится

Конкретно, где-то при создании объекта std::function вызывается конструктор CacheFactory и так по кругу

Может, разные верси компилятора эти шаблоны по-разному понимают?

Видимо, да

zvezdochiot commented 6 months ago

@plzombie . Так почему в моей и твоих сборках ничего не заканчивается? И ежели у вас винда как то умеет справляться с исчерпанием стека, то у меня в devuan - ни разу (я целый fix добавлял по этому поводу). Что то не так со стандартами STD. Еще раз предлагаю внести указание на 14-ый. И оттестировать с указанием. Оттестировать смогёшь только ты, мне не на чем, плодить всякие виртуалки - у меня места нет совсем (всё книгами и сканами завалено).

plzombie commented 6 months ago

@plzombie . Так почему в моей и твоих сборках ничего не заканчивается? И ежели у вас винда как то умеет справляться с исчерпанием стека, то у меня в devuan - ни разу (я целый fix добавлял по этому поводу). Что то не так со стандартами STD. Еще раз предлагаю внести указание на 14-ый. И оттестировать с указанием. Оттестировать смогёшь только ты, мне не на чем, плодить всякие виртуалки - у меня места нет совсем (всё книгами и сканами завалено).

Протестировал, тот же результат. А не заканчивается, потому что что-то поломали конкретно в Fedora 37+ и Debian 12

zvezdochiot commented 6 months ago

@plzombie . Тогда стоит смотреть в сторону Deviant. "Починить" в нём деварп. А дальше посмотрим.

PS: И ещё: ежели с помощью alien сконвертировать мой deb в rpm, он будет работать в Федоре? Или же всё глобальней и хуже?

PS2: Дело не в Федоре или Дебиане, а конкретно в GCC. Именно в нём что то "сотворили".

PS3: Скорее всего понадобится libstdc++6-{rel}-dbg.deb или libstdc++6-{rel}-dbg.rpm для выяснения "причин".

PS4: На https://cmake.org предлагают такую конструкцию для линковки:

set_property(TARGET tgt PROPERTY CXX_STANDARD 14)
noobie-iv commented 6 months ago

Вот примитивный тест этого кеша:

#include <iostream>
#include <functional>
#include <mutex>
#include <optional>

//------------------------------------------------------------

template<typename T>
class CachingFactory
{
private:
    struct SharedState
    {
        std::mutex mutex;
        std::function<T()> factory;
        std::optional<T> cached;

        template<typename F>
        SharedState(F&& factory) : factory(std::forward<F>(factory)) {}
    };
public:
    template<typename F>
    explicit CachingFactory(F&& factory)
        : m_ptrState(std::make_shared<SharedState>(std::forward<F>(factory))) {}

    T operator()() const
    {
        SharedState& s = *m_ptrState;
        std::lock_guard<std::mutex> const lock(s.mutex);

        if (!s.cached)
        {
            s.cached = s.factory();
        }

        return *s.cached;
    }

    bool isCached() const
    {
        SharedState& s = *m_ptrState;
        std::lock_guard<std::mutex> const lock(s.mutex);
        return s.cached.is_initialized();
    }

    void clearCache()
    {
        SharedState& s = *m_ptrState;
        std::lock_guard<std::mutex> const lock(s.mutex);
        s.cached.reset();
    }
private:
    std::shared_ptr<SharedState> m_ptrState;
};

template<typename T, typename F>
CachingFactory<T> cachingFactory(F&& factory)
{
    return CachingFactory<T>(std::forward<F>(factory));
}

//------------------------------------------------------------

int f()
{
    std::cout << "Fuction f() call" << std::endl;
    return 1;
}

int main()
{
    CachingFactory<int> cf(f);

    std::cout << cf() << std::endl;
    std::cout << cf() << std::endl;
}

Код кеша скопипащен (только буст поправлен на std). Есть фукция f(), которая при вызове выводит сообщение о том, что ее, собственно, вызвали. Эта функция запихана в кеш, и пару раз вызвана через него. Под вынью выдача такая:

Fuction f() call
1
1

На два вызова через кеш реальный вызов функции только один. А результатов два, второй взят из кеша. Такое запустится под линем, или тоже вылетит?

plzombie commented 6 months ago

Этот код у меня в Fedora 37 нормально отработал. Надо тестировать с QImage

Резюмирую. В Alt Linux Workstation 10 (gcc 10.3.1), Debian 11 (10.2.1) и Винде работает нормально. В Debian 12 (gcc 12.2) падает на этапе Вывод. В Fedora 37 (gcc 12.3.1) падает ещё и на деварпинге и определение полезной области кривое

zvezdochiot commented 6 months ago

@plzombie . Кстати, а что там с версиями Qt? Прям таблицей:

OS Qt version GCC verion
Devuan chimaera 5.15.2 10.2.1
Debian 11 ??? 10.2.1
Debian 12 ??? 12.2
Fedora 37 ??? 12.3.1
Alt Linux Workstation 10 ??? 10.3.1

PS: Сейчас собираюсь переходить с chimaera на daedalus. Так что смогу принимать участие в тестировании этого "бага".

noobie-iv commented 6 months ago

Версия теста кеша с QImage. Не вылетает ни под вынь, ни под дебиан 12.2.0.

В кешированной версии рисует зеленые квадраты. Если для проверки перекомментировать строки в некешированную версию, второй квадрат станет красным.

Cache NoCache

Cache.zip

Дело в чем-то другом.

zvezdochiot commented 6 months ago

Здесь что то про спотыкание на ровном месте из-за потоков.

PS: SEGFAULT в Devuan daedalus (aka Debian 12.0) подтверждаю. При этом сборка Debian 11 в ней же без проблем пашет.

PS2: :information_source: https://github.com/Tulon/scantailor/commit/3631ce3afdae119630591edd03b26104771edf7e#diff-fd258663a763846177dddc93aec8c2c7639f32c26bb4b23a930bdd001c8bcfa2


GDB


На всех этапах до "Output" все вызовы CacheFactory имеют вид:

Thread 5 "Thread (pooled)" hit Breakpoint 1.5, CachingFactory<imageproc::GrayImage>::CachingFactory<LoadFileTask::operator()()::<lambda()> >(struct {...} &&) (this=0x7fffd72cacb0, factory=...)
    at /media/buf/zvezdochiot/dists/git/github.com/ORGS/ORG.IPEP/GUI/scantailor-all/scantailor-experimental-w/src/foundation/CachingFactory.h:51
51              : m_ptrState(std::make_shared<SharedState>(std::forward<F>(factory))) {}
(gdb) n
LoadFileTask::operator() (this=0x555556999050) at /media/buf/zvezdochiot/dists/git/github.com/ORGS/ORG.IPEP/GUI/scantailor-all/scantailor-experimental-w/src/LoadFileTask.cpp:104
104                 CachingFactory<GrayImage> gray_image_factory([image]()
(gdb) n
111                        );
(gdb) n
110                            *this, m_ptrAccelOps, image, gray_image_factory, transform
(gdb) n
[Thread 0x7fffccd286c0 (LWP 441) exited]
[Thread 0x7fffcd5296c0 (LWP 440) exited]
[Thread 0x7fffcdd2a6c0 (LWP 439) exited]
[Thread 0x7fffce52b6c0 (LWP 438) exited]
[Thread 0x7fffd48696c0 (LWP 437) exited]
[Thread 0x7fffb3fff6c0 (LWP 442) exited]
111                        );
(gdb) n
112             }
(gdb) n
118     }
(gdb) n

на этапе же "Output" всё меняется:

Thread 5 "Thread (pooled)" hit Breakpoint 1.5, CachingFactory<imageproc::GrayImage>::CachingFactory<LoadFileTask::operator()()::<lambda()> >(struct {...} &&) (this=0x7fffd72cacb0, factory=...)
    at /media/buf/zvezdochiot/dists/git/github.com/ORGS/ORG.IPEP/GUI/scantailor-all/scantailor-experimental-w/src/foundation/CachingFactory.h:51
51              : m_ptrState(std::make_shared<SharedState>(std::forward<F>(factory))) {}
(gdb) n
[Thread 0x7fffabfff6c0 (LWP 26707) exited]
[Thread 0x7fffccd286c0 (LWP 26706) exited]
[Thread 0x7fffcd5296c0 (LWP 26705) exited]
[Thread 0x7fffcdd2a6c0 (LWP 26704) exited]
[Thread 0x7fffce52b6c0 (LWP 26703) exited]
[Thread 0x7fffd48696c0 (LWP 26702) exited]
LoadFileTask::operator() (this=0x5555565574a0) at /media/buf/zvezdochiot/dists/git/github.com/ORGS/ORG.IPEP/GUI/scantailor-all/scantailor-experimental-w/src/LoadFileTask.cpp:104
104                 CachingFactory<GrayImage> gray_image_factory([image]()
(gdb) n
111                        );
(gdb) n
110                            *this, m_ptrAccelOps, image, gray_image_factory, transform
(gdb) n
111                        );
(gdb) n

Thread 5 "Thread (pooled)" hit Breakpoint 1.1, CachingFactory<QImage>::CachingFactory<output::Task::processScaled(const TaskStatus&, const std::shared_ptr<AcceleratableOperations>&, const QImage&, const CachingFactory<imageproc::GrayImage>&, const std::shared_ptr<const imageproc::AbstractImageTransform>&, const QRectF&, const QRectF&)::<lambda()>&>(struct {...} &) (this=0x7fffd72c8e10, factory=...) at /media/buf/zvezdochiot/dists/git/github.com/ORGS/ORG.IPEP/GUI/scantailor-all/scantailor-experimental-w/src/foundation/CachingFactory.h:51                    
51              : m_ptrState(std::make_shared<SharedState>(std::forward<F>(factory))) {}
(gdb) n
cachingFactory<QImage, output::Task::processScaled(const TaskStatus&, const std::shared_ptr<AcceleratableOperations>&, const QImage&, const CachingFactory<imageproc::GrayImage>&, const std::shared_ptr<const imageproc::AbstractImageTransform>&, const QRectF&, const QRectF&)::<lambda()>&>(struct {...} &) (factory=...) at /media/buf/zvezdochiot/dists/git/github.com/ORGS/ORG.IPEP/GUI/scantailor-all/scantailor-experimental-w/src/foundation/CachingFactory.h:91                                                                                                        
91      }
(gdb) n
output::Task::processScaled (this=0x5555564d3e00, status=..., accel_ops=std::shared_ptr<AcceleratableOperations> (use count 5, weak count 0) = {...}, orig_image=..., gray_orig_image_factory=..., 
    orig_image_transform=std::shared_ptr<const imageproc::AbstractImageTransform> (use count 5, weak count 0) = {...}, content_rect=..., outer_rect=...)
    at /media/buf/zvezdochiot/dists/git/github.com/ORGS/ORG.IPEP/GUI/scantailor-all/scantailor-experimental-w/src/filters/output/Task.cpp:446
446         };
(gdb) n

Thread 5 "Thread (pooled)" hit Breakpoint 1.4, CachingFactory<QImage>::CachingFactory<CachingFactory<QImage>&> (this=0x7fffd72c8df0, factory=...)
    at /media/buf/zvezdochiot/dists/git/github.com/ORGS/ORG.IPEP/GUI/scantailor-all/scantailor-experimental-w/src/foundation/CachingFactory.h:51
51              : m_ptrState(std::make_shared<SharedState>(std::forward<F>(factory))) {}
(gdb) n

Thread 5 "Thread (pooled)" hit Breakpoint 1.4, CachingFactory<QImage>::CachingFactory<CachingFactory<QImage>&> (this=0x7fffd1e45080, factory=...)
    at /media/buf/zvezdochiot/dists/git/github.com/ORGS/ORG.IPEP/GUI/scantailor-all/scantailor-experimental-w/src/foundation/CachingFactory.h:51
51              : m_ptrState(std::make_shared<SharedState>(std::forward<F>(factory))) {}
(gdb) n

Thread 5 "Thread (pooled)" hit Breakpoint 1.4, CachingFactory<QImage>::CachingFactory<CachingFactory<QImage>&> (this=0x7fffd00043e0, factory=...)
    at /media/buf/zvezdochiot/dists/git/github.com/ORGS/ORG.IPEP/GUI/scantailor-all/scantailor-experimental-w/src/foundation/CachingFactory.h:51
51              : m_ptrState(std::make_shared<SharedState>(std::forward<F>(factory))) {}
(gdb) n

Thread 5 "Thread (pooled)" hit Breakpoint 1.4, CachingFactory<QImage>::CachingFactory<CachingFactory<QImage>&> (this=0x7fffd0005e50, factory=...)
    at /media/buf/zvezdochiot/dists/git/github.com/ORGS/ORG.IPEP/GUI/scantailor-all/scantailor-experimental-w/src/foundation/CachingFactory.h:51
51              : m_ptrState(std::make_shared<SharedState>(std::forward<F>(factory))) {}
(gdb) n

Thread 5 "Thread (pooled)" hit Breakpoint 1.4, CachingFactory<QImage>::CachingFactory<CachingFactory<QImage>&> (this=0x7fffd00098e0, factory=...)
    at /media/buf/zvezdochiot/dists/git/github.com/ORGS/ORG.IPEP/GUI/scantailor-all/scantailor-experimental-w/src/foundation/CachingFactory.h:51
51              : m_ptrState(std::make_shared<SharedState>(std::forward<F>(factory))) {}
(gdb) n

Thread 5 "Thread (pooled)" hit Breakpoint 1.4, CachingFactory<QImage>::CachingFactory<CachingFactory<QImage>&> (this=0x7fffd000a7b0, factory=...)
    at /media/buf/zvezdochiot/dists/git/github.com/ORGS/ORG.IPEP/GUI/scantailor-all/scantailor-experimental-w/src/foundation/CachingFactory.h:51
51              : m_ptrState(std::make_shared<SharedState>(std::forward<F>(factory))) {}
(gdb) n

Thread 5 "Thread (pooled)" hit Breakpoint 1.4, CachingFactory<QImage>::CachingFactory<CachingFactory<QImage>&> (this=0x7fffd0008da0, factory=...)
    at /media/buf/zvezdochiot/dists/git/github.com/ORGS/ORG.IPEP/GUI/scantailor-all/scantailor-experimental-w/src/foundation/CachingFactory.h:51
51              : m_ptrState(std::make_shared<SharedState>(std::forward<F>(factory))) {}
(gdb) n

Thread 5 "Thread (pooled)" hit Breakpoint 1.4, CachingFactory<QImage>::CachingFactory<CachingFactory<QImage>&> (this=0x7fffd00025e0, factory=...)
    at /media/buf/zvezdochiot/dists/git/github.com/ORGS/ORG.IPEP/GUI/scantailor-all/scantailor-experimental-w/src/foundation/CachingFactory.h:51
51              : m_ptrState(std::make_shared<SharedState>(std::forward<F>(factory))) {}
(gdb) n

Thread 5 "Thread (pooled)" hit Breakpoint 1.4, CachingFactory<QImage>::CachingFactory<CachingFactory<QImage>&> (this=0x7fffd1d72870, factory=...)
    at /media/buf/zvezdochiot/dists/git/github.com/ORGS/ORG.IPEP/GUI/scantailor-all/scantailor-experimental-w/src/foundation/CachingFactory.h:51
51              : m_ptrState(std::make_shared<SharedState>(std::forward<F>(factory))) {}
(gdb) n

Thread 5 "Thread (pooled)" hit Breakpoint 1.4, CachingFactory<QImage>::CachingFactory<CachingFactory<QImage>&> (this=0x7fffd0007720, factory=...)
    at /media/buf/zvezdochiot/dists/git/github.com/ORGS/ORG.IPEP/GUI/scantailor-all/scantailor-experimental-w/src/foundation/CachingFactory.h:51
51              : m_ptrState(std::make_shared<SharedState>(std::forward<F>(factory))) {}
...
zvezdochiot commented 6 months ago

@plzombie , @noobie-iv

Короче, фигня эта происходит ни где-нибудь, а вот здесь:

Thread 14 "Thread (pooled)" hit Breakpoint 1, output::Task::processScaled (this=0x555556aac210, status=..., accel_ops=std::shared_ptr<AcceleratableOperations> (use count 5, weak count 0) = {...}, orig_image=..., gray_orig_image_factory=..., 
    orig_image_transform=std::shared_ptr<const imageproc::AbstractImageTransform> (use count 4, weak count 0) = {...}, content_rect=..., outer_rect=...)
    at /media/buf/zvezdochiot/dists/git/github.com/ORGS/ORG.IPEP/GUI/scantailor-all/scantailor-experimental-w/src/filters/output/Task.cpp:441
441         auto cached_transform_orig_image = cachingFactory<QImage>(transform_orig_image);
(gdb) n
446         };
(gdb) n

Thread 14 "Thread (pooled)" received signal SIGSEGV, Segmentation fault.
0x00007ffff66b7804 in __GI___libc_malloc (bytes=128) at ./malloc/malloc.c:3323
3323    ./malloc/malloc.c: Нет такого файла или каталога.
noobie-iv commented 6 months ago

@zvezdochiot @plzombie

Надо затестить вариант исправления CachingFactory. Похоже, лишние копирования получались при захвате фабрики лямбдой по значению. Поправил на захват по ссылке. На виртуалке под Debian 12.2.0 вроде перестал вылетать, и под Win/VS2022 тоже контачит.

https://github.com/ImageProcessing-ElectronicPublications/scantailor-experimental/tree/fix_caching_factory

zvezdochiot commented 6 months ago

@noobie-iv , "вы - гений, доктор...", в который раз поражаешь. Devuan Daedalus (aka Debian 12), gcc 12.2.0 - всё пашет! Дождусь ответа @plzombie и тут же смержу.

А теперь...

@mara004 . does your system crash with the fix from @noobie-iv : https://github.com/ImageProcessing-ElectronicPublications/scantailor-experimental/tree/fix_caching_factory ?

plzombie commented 6 months ago

OMG. Lambdas... closures... caches of caches...