GNOME Bugzilla – Bug 787089
win32: GtkWindow of type GTK_WINDOW_POPUP/GDK_WINDOW_TEMP leaks memory proportional to its size
Last modified: 2017-12-03 03:17:33 UTC
Created attachment 358864 [details] test case The attached test case shows that opening and destroying GtkWindows of type GTK_WINDOW_POPUP (but not _TOPLEVEL) leaks memory. Moreover, by increasing the size of the window, the amount of memory leaked increases proportionally, indicating the leak may be of a graphics surface or similar. I've only just noticed this and have only been able to test it on Windows so far. Once I have access to a Linux machine, I'll confirm whether it's Windows-specific and post the results of running it under valgrind.
Created attachment 358882 [details] test case I left TOPLEVEL in, from testing to show that prevented the leak. When run on Linux, valgrind seems perfectly happy with this, so it seems indeed to be caused by something in the Windows backend only. valgrind ./a.out ==28608== Memcheck, a memory error detector ==28608== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==28608== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info ==28608== Command: ./a.out ==28608== ^Z^C==28608== ==28608== Process terminating with default action of signal 2 (SIGINT) ==28608== at 0x73EC66D: ??? (syscall-template.S:84) ==28608== by 0x6E27118: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.5306.0) ==28608== by 0x6E274B1: g_main_loop_run (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.5306.0) ==28608== by 0x68BA905: ??? (in /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0.5306.0) ==28608== by 0x6E4E624: ??? (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.5306.0) ==28608== by 0x70F7493: start_thread (pthread_create.c:333) ==28608== by 0x73F5ABE: clone (clone.S:97) ==28608== ==28608== HEAP SUMMARY: ==28608== in use at exit: 1,592,462 bytes in 17,053 blocks ==28608== total heap usage: 357,813 allocs, 340,760 frees, 24,900,604 bytes allocated ==28608== ==28608== LEAK SUMMARY: ==28608== definitely lost: 0 bytes in 0 blocks ==28608== indirectly lost: 0 bytes in 0 blocks ==28608== possibly lost: 4,416 bytes in 52 blocks ==28608== still reachable: 1,499,342 bytes in 16,285 blocks ==28608== of which reachable via heuristic: ==28608== length64 : 5,168 bytes in 86 blocks ==28608== newarray : 2,096 bytes in 51 blocks ==28608== suppressed: 0 bytes in 0 blocks ==28608== Rerun with --leak-check=full to see details of leaked memory ==28608== ==28608== For counts of detected and suppressed errors, rerun with: -v ==28608== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
From LRN on irc: dboles LRN: Hi, do you have any guesses where to look to fix this? https://bugzilla.gnome.org/show_bug.cgi?id=787089 bugbot Bug 787089: Backend: Win32, normal, gtk-win32-maint, NEW , win32: GtkWindow of type GTK_WINDOW_POPUP/GDK_WINDOW_TEMP leaks memory proportional to its size LRN dboles, i gave it some thought. What happens if you run with GDK_WIN32_LAYERED=0 ? (running with GTK_CSD=0 probably shouldn't affect popup windows, but you might want to check that too) dboles LRN: thanks, I'll give those a shot once I can reboot into Windows LRN anyway, if the leak is proportionate to the window size, the thing leaking is most likely a surface. If i were you, i'd either hack up GDK to keep track of all surfaces it uses, or hack up cairo for the same purpose. hacking GDK is probably easier - there aren't that many places where it allocates surfaces and you'll be able to trivially store the source code location where that happens (if you hack that into cairo, you'd also need a backtrace library, otherwise you won't be able to find where the leaking surface is allocated) dboles sounds good, thanks!
finally able to test this: (In reply to Daniel Boles from comment #2) > LRN dboles, i gave it some thought. What happens if you run with > GDK_WIN32_LAYERED=0 ? Yes, indeed, this appears to stabilise the memory consumption! > (running with GTK_CSD=0 probably shouldn't affect popup windows, but you > might want to check that too) This has no effect; the runaway RAM consumption continues. > LRN anyway, if the leak is proportionate to the window size, the thing > leaking is most likely a surface. If i were you, i'd either hack up GDK to > keep track of all surfaces it uses, or hack up cairo for the same purpose. > hacking GDK is probably easier If the effect of GDK_WIN32_LAYERED doesn't immediately suggest anything useful to you, then I can dive further into this. I had hoped that Application Verifier or Dr Memory would report something useful, to save me the work, but no dice so far!
( ping ^ )
Created attachment 359083 [details] [review] DEBUG: track W32 GDK backend surfaces creation and destruction Seriously? It's as simple as this. As i have said, there aren't many surfaces in W32 GDK backend, and they are very easy to track.
Created attachment 359084 [details] [review] GDK W32: Plug a resource leak And this patch plugs the leak that i've found.
(In reply to LRN from comment #5) > Seriously? It's as simple as this. > As i have said, there aren't many surfaces in W32 GDK backend, and they are > very easy to track. Yeah, I'm sure it's insultingly simple to you. However, it's the first time I'm looking at any of the win32-specific code, having never done anything with that backend before, and I also have irregular ability to boot into Windows... so you'll have to bear with my level of ignorance for the first while! Thanks for the effort and patches; once I'm on *another* Windows machine where I might stand a chance of building GTK+, I can test them for you.
Created attachment 364838 [details] [review] GDK W32: Plug a resource leak v2 v2: * Remove debug code from the commit
Attachment 364838 [details] pushed as 6d0b0cb - GDK W32: Plug a resource leak Since there's been no activity in this bug, and since the patch seems rather straightforward, i've elected to push and fix this unilaterally.