Crash with optimized build: Assertion `CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count)' failed.
I'm getting a core dump when opening panorama images taken with my Samsung S9. Apparently some Samsung phones produce invalid jpgs in panorama mode, but after doing some analysis I don't think this should actually cause a crash in gthumb. So far it rather seems to be an issue related to the error handling.
The error I'm getting on the console:
gthumb: cairo-surface.c:930: cairo_surface_reference: Assertion `CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count)' failed.
and it crashes at:
#0 0x00007ffff69abce5 in raise () at /usr/lib/libc.so.6 #1 0x00007ffff6995857 in abort () at /usr/lib/libc.so.6 #2 0x00007ffff6995727 in _nl_load_domain.cold () at /usr/lib/libc.so.6 #3 0x00007ffff69a4426 in () at /usr/lib/libc.so.6 #4 0x00007ffff7162391 in () at /usr/lib/libcairo.so.2 #5 0x00005555555dece3 in gth_image_set_cairo_surface (image=image@entry=0x555556c861e0, value=value@entry=0x7fffcc002bc0) at ../gthumb/gth-image.c:213 #6 0x00007fffef57d0eb in _cairo_image_surface_create_from_jpeg (istream=<optimized out>, file_data=<optimized out>, requested_size=690, original_width_p=0x7fffdae8 0bbc, original_height_p=0x7fffdae80bc0, loaded_original_p=0x7fffdae80bc4, user_data=0x0, cancellable=0x555556cde960, error=0x7fffdae80bd0) at ../extensions/cairo_io /cairo-image-surface-jpeg.c:601 #7 0x00005555555e2005 in load_image_thread (task=0x555556bb5040, source_object=<optimized out>, task_data=<optimized out>, cancellable=0x555556cde960) at ../gthumb /gth-image-loader.c:241 #8 0x00007ffff7c23d81 in () at /usr/lib/libgio-2.0.so.0 #9 0x00007ffff7d5e487 in () at /usr/lib/libglib-2.0.so.0 #10 0x00007ffff7d645b1 in () at /usr/lib/libglib-2.0.so.0 #11 0x00007ffff6b3f46f in start_thread () at /usr/lib/libpthread.so.0 #12 0x00007ffff6a6f3d3 in clone () at /usr/lib/libc.so.6
I first experienced this crash with the package provided by manjaro/arch which is compiled with -O2. When first trying to reproduce this crash with my own build the picture showed just fine, so it took me a while to figure out this is actually related to the optimization level (-O1 also produces the crash).
Let me try to give some more details on what I saw while debugging and what I'm suspecting. Feel free to ignore everything after this if my assumptions are wrong due to not really knowing the code base. So far it looks to me like one important NULL assignment is optimized away in cairo-image-surface-jpeg.c:903 :
surface = NULL; /* ignore other jpeg errors */
A little later the call to
jpeg_finish_decompress seems to produce an error due to the malformed jpeg file, which causes the error handler to jump back to
surface was not set to NULL and the only remaining ref_count is kept by the GthImage the cairo assert eventually fails when entering
gth_image_set_cairo_surface the second time.
So I'm not very familiar with goto and compiler optimizations, but is it possible the NULL assignment to surface is optimized away because the compiler thinks the variable is not used anymore? A quick (and ugly) fix that fits to this assumption is to just add another access to surface after the if in line 609:
g_print ("surface: %d\n", surface);
With this the pictures show fine to me even with -O2.
I'm happy to provide more information if something is missing.