window show and hide leads to invalid memory access
Hi, I am experiencing wrong memory access inside libdecor.
I am showing and hiding my window. For hide operation, I am calling libdecor_frame_unref() and to show it again, I call libdecor_decorate(). I see wrong memory access in libdecor_frame_gtk_new(), in wl_list_insert().
Steps to reproduce (using libdecor's demo example):
- take latest libdecor sources
- modify demo.c by appending following lines in main (new text is in bold):
context = libdecor_new(wl_display, &libdecor_iface); window->frame = libdecor_decorate(context, window->wl_surface, &libdecor_frame_iface, window); fprintf(stderr, "Hiding...\n"); libdecor_frame_unref(window->frame); fprintf(stderr, "Showing again...\n"); window->frame = libdecor_decorate(context, window->wl_surface, &libdecor_frame_iface, window); fprintf(stderr, "Showing done.\n"); libdecor_frame_set_app_id(window->frame, "libdecor-demo"); libdecor_frame_set_title(window->frame, "libdecor demo"); libdecor_frame_map(window->frame);
- run libdecor-demo example in valgrind:
valgrind /usr/local/bin/libdecor-demo
- following output reveals the problem that might lead to crash in various applications and various use cases (I made bold important information and put comment there):
$ valgrind /usr/local/bin/libdecor-demo ==6100== Memcheck, a memory error detector ==6100== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==6100== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info ==6100== Command: /usr/local/bin/libdecor-demo ==6100== (process:6100): Gtk-WARNING **: 12:58:11.981: Locale not supported by C library. Using the fallback 'C' locale. Hiding... Showing again... ==6100== Invalid write of size 8 ==6100== at 0x4888027: wl_list_insert (in /usr/lib/x86_64-linux-gnu/libwayland-client.so.0.20.0) ==6100== by 0x60FBC4F: libdecor_frame_gtk_new (libdecor-gtk.c:461) ==6100== by 0x60FBF0E: libdecor_plugin_gtk_frame_new (libdecor-gtk.c:538) ==6100== by 0x4878B73: libdecor_decorate (libdecor.c:559) ==6100== by 0x10FE9E: main (demo.c:1310) <- the second call to libdecor_decorate() ==6100== Address 0x7b087e0 is 352 bytes inside a block of size 368 free'd ==6100== at 0x484B27F: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==6100== by 0x4878D7F: libdecor_frame_unref (libdecor.c:627) ==6100== by 0x10FE4D: main (demo.c:1308) <- the call to libdecor_frame_unref() ==6100== Block was alloc'd at ==6100== at 0x484DA83: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==6100== by 0x60FB2FD: zalloc (utils.h:45) ==6100== by 0x60FBBFE: libdecor_frame_gtk_new (libdecor-gtk.c:452) ==6100== by 0x60FBF0E: libdecor_plugin_gtk_frame_new (libdecor-gtk.c:538) ==6100== by 0x4878B73: libdecor_decorate (libdecor.c:559) ==6100== by 0x10FE13: main (demo.c:1304) <- the first call to libdecor_decorate() ==6100== Showing done. ==6100== Invalid read of size 8 ==6100== at 0x60FC5EA: redraw_scale (libdecor-gtk.c:735) ==6100== by 0x6100728: output_done (libdecor-gtk.c:2608) ==6100== by 0x4B62E2D: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.8.1.0) ==6100== by 0x4B5F492: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.8.1.0) ==6100== by 0x4887ACF: ??? (in /usr/lib/x86_64-linux-gnu/libwayland-client.so.0.20.0) ==6100== by 0x4888242: ??? (in /usr/lib/x86_64-linux-gnu/libwayland-client.so.0.20.0) ==6100== by 0x488843B: wl_display_dispatch_queue_pending (in /usr/lib/x86_64-linux-gnu/libwayland-client.so.0.20.0) ==6100== by 0x60FBE8F: libdecor_plugin_gtk_dispatch (libdecor-gtk.c:516) ==6100== by 0x487A972: libdecor_dispatch (libdecor.c:1641) ==6100== by 0x10FFCB: main (demo.c:1321) ==6100== Address 0x7b086f0 is 112 bytes inside a block of size 368 free'd ==6100== at 0x484B27F: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==6100== by 0x4878D7F: libdecor_frame_unref (libdecor.c:627) ==6100== by 0x10FE4D: main (demo.c:1308) ==6100== Block was alloc'd at ==6100== at 0x484DA83: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==6100== by 0x60FB2FD: zalloc (utils.h:45) ==6100== by 0x60FBBFE: libdecor_frame_gtk_new (libdecor-gtk.c:452) ==6100== by 0x60FBF0E: libdecor_plugin_gtk_frame_new (libdecor-gtk.c:538) ==6100== by 0x4878B73: libdecor_decorate (libdecor.c:559) ==6100== by 0x10FE13: main (demo.c:1304) ==6100== ==6100== Invalid read of size 8 ==6100== at 0x610074D: output_done (libdecor-gtk.c:2605) ==6100== by 0x4B62E2D: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.8.1.0) ==6100== by 0x4B5F492: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.8.1.0) ==6100== by 0x4887ACF: ??? (in /usr/lib/x86_64-linux-gnu/libwayland-client.so.0.20.0) ==6100== by 0x4888242: ??? (in /usr/lib/x86_64-linux-gnu/libwayland-client.so.0.20.0) ==6100== by 0x488843B: wl_display_dispatch_queue_pending (in /usr/lib/x86_64-linux-gnu/libwayland-client.so.0.20.0) ==6100== by 0x60FBE8F: libdecor_plugin_gtk_dispatch (libdecor-gtk.c:516) ==6100== by 0x487A972: libdecor_dispatch (libdecor.c:1641) ==6100== by 0x10FFCB: main (demo.c:1321) ==6100== Address 0x7b087e8 is 360 bytes inside a block of size 368 free'd ==6100== at 0x484B27F: free (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==6100== by 0x4878D7F: libdecor_frame_unref (libdecor.c:627) ==6100== by 0x10FE4D: main (demo.c:1308) ==6100== Block was alloc'd at ==6100== at 0x484DA83: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==6100== by 0x60FB2FD: zalloc (utils.h:45) ==6100== by 0x60FBBFE: libdecor_frame_gtk_new (libdecor-gtk.c:452) ==6100== by 0x60FBF0E: libdecor_plugin_gtk_frame_new (libdecor-gtk.c:538) ==6100== by 0x4878B73: libdecor_decorate (libdecor.c:559) ==6100== by 0x10FE13: main (demo.c:1304) ==6100== ==6100== ==6100== HEAP SUMMARY: ==6100== in use at exit: 1,786,338 bytes in 17,220 blocks ==6100== total heap usage: 199,090 allocs, 181,870 frees, 35,011,694 bytes allocated ==6100== ==6100== LEAK SUMMARY: ==6100== definitely lost: 392 bytes in 1 blocks ==6100== indirectly lost: 65,800 bytes in 2 blocks ==6100== possibly lost: 1,056 bytes in 5 blocks ==6100== still reachable: 1,643,522 bytes in 16,522 blocks ==6100== suppressed: 0 bytes in 0 blocks ==6100== Rerun with --leak-check=full to see details of leaked memory ==6100== ==6100== For lists of detected and suppressed errors, rerun with: -s ==6100== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)