yglukhov / nimx

GUI library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Valgrind issues

kb2ma opened this issue · comments

I have found significant memory issues when running Valgrind on a minimal nimx application. Details below, and I'd appreciate any insights. Am I missing something?

Environment

  • nimx add6b39
  • nim v1.2.6
  • Ubuntu 20.04

Application

nimx_mem.nim

import nimx / [ segmented_control, window ]

proc startApplication() =
  let wnd = newWindow(newRect(40, 40, 800, 600))
  wnd.title = "Mem Test"
*[
  let sc = SegmentedControl.new(newRect(10, 10, 160, 22))
  sc.segments = @["Client", "Server"]
  sc.autoresizingMask = { afFlexibleWidth, afFlexibleMaxY }
  wnd.addSubview(sc)
]*
runApplication:
  startApplication()

Build and Run

   $ nim c --threads:on nimx_mem.nim
   $ valgrind --leak-check=yes --show-leak-kinds=definite ./nimx_mem

After the app starts, I just close it without interacting with it.

Results, without SegmentedControl

==28923== HEAP SUMMARY:
==28923==     in use at exit: 2,957,743 bytes in 9,923 blocks
==28923==   total heap usage: 31,065 allocs, 21,142 frees, 8,874,866 bytes allocated
==28923== 
==28923== 32 bytes in 1 blocks are definitely lost in loss record 543 of 2,706
==28923==    at 0x483B7F3: malloc (vg_replace_malloc.c:309)
==28923==    by 0x544A3CF: XextAddDisplay (in /usr/lib/x86_64-linux-gnu/libXext.so.6.4.0)
==28923==    by 0x77A8674: ???
==28923==    by 0x77AB06C: ???
==28923==    by 0x779ACE1: ???
==28923==    by 0x7796653: ???
==28923==    by 0x7797098: ???
==28923==    by 0x513823A: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.10.0)
==28923==    by 0x5138507: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.10.0)
==28923==    by 0x510A739: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.10.0)
==28923==    by 0x510C977: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.10.0)
==28923==    by 0x510D112: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.10.0)
==28923== 
==28923== 32 bytes in 1 blocks are definitely lost in loss record 544 of 2,706
==28923==    at 0x483B7F3: malloc (vg_replace_malloc.c:309)
==28923==    by 0x544A3CF: XextAddDisplay (in /usr/lib/x86_64-linux-gnu/libXext.so.6.4.0)
==28923==    by 0x77AC714: ???
==28923==    by 0x77AC5DA: ???
==28923==    by 0x779ACEE: ???
==28923==    by 0x7796653: ???
==28923==    by 0x7797098: ???
==28923==    by 0x513823A: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.10.0)
==28923==    by 0x5138507: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.10.0)
==28923==    by 0x510A739: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.10.0)
==28923==    by 0x510C977: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.10.0)
==28923==    by 0x510D112: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.10.0)
==28923== 
==28923== LEAK SUMMARY:
==28923==    definitely lost: 64 bytes in 2 blocks
==28923==    indirectly lost: 0 bytes in 0 blocks
==28923==      possibly lost: 1,906,599 bytes in 6,480 blocks
==28923==    still reachable: 1,051,080 bytes in 3,441 blocks
==28923==         suppressed: 0 bytes in 0 blocks
==28923== Reachable blocks (those to which a pointer was found) are not shown.
==28923== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==28923== 
==28923== For lists of detected and suppressed errors, rerun with: -s
==28923== ERROR SUMMARY: 2387 errors from 1269 contexts (suppressed: 2 from 2)

Results, with SegmentedControl

Removed the comments from the code. This run shows significantly more problems with only the addition of the segmented control.

==28975== HEAP SUMMARY:
==28975==     in use at exit: 3,557,358 bytes in 18,866 blocks
==28975==   total heap usage: 88,284 allocs, 69,418 frees, 22,490,084 bytes allocated
==28975== 
==28975== 32 bytes in 1 blocks are definitely lost in loss record 632 of 3,207
==28975==    at 0x483B7F3: malloc (vg_replace_malloc.c:309)
==28975==    by 0x544A3CF: XextAddDisplay (in /usr/lib/x86_64-linux-gnu/libXext.so.6.4.0)
==28975==    by 0x77A8674: ???
==28975==    by 0x77AB06C: ???
==28975==    by 0x779ACE1: ???
==28975==    by 0x7796653: ???
==28975==    by 0x7797098: ???
==28975==    by 0x513823A: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.10.0)
==28975==    by 0x5138507: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.10.0)
==28975==    by 0x510A739: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.10.0)
==28975==    by 0x510C977: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.10.0)
==28975==    by 0x510D112: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.10.0)
==28975== 
==28975== 32 bytes in 1 blocks are definitely lost in loss record 633 of 3,207
==28975==    at 0x483B7F3: malloc (vg_replace_malloc.c:309)
==28975==    by 0x544A3CF: XextAddDisplay (in /usr/lib/x86_64-linux-gnu/libXext.so.6.4.0)
==28975==    by 0x77AC714: ???
==28975==    by 0x77AC5DA: ???
==28975==    by 0x779ACEE: ???
==28975==    by 0x7796653: ???
==28975==    by 0x7797098: ???
==28975==    by 0x513823A: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.10.0)
==28975==    by 0x5138507: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.10.0)
==28975==    by 0x510A739: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.10.0)
==28975==    by 0x510C977: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.10.0)
==28975==    by 0x510D112: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.10.0)
==28975== 
==28975== 8,807 (6,656 direct, 2,151 indirect) bytes in 26 blocks are definitely lost in loss record 3,167 of 3,207
==28975==    at 0x483B7F3: malloc (vg_replace_malloc.c:309)
==28975==    by 0x105202F4: ??? (in /usr/lib/x86_64-linux-gnu/libfontconfig.so.1.12.0)
==28975==    by 0x105209B8: ??? (in /usr/lib/x86_64-linux-gnu/libfontconfig.so.1.12.0)
==28975==    by 0x10521FDC: ??? (in /usr/lib/x86_64-linux-gnu/libfontconfig.so.1.12.0)
==28975==    by 0x1052906C: ??? (in /usr/lib/x86_64-linux-gnu/libfontconfig.so.1.12.0)
==28975==    by 0x784F9D9: ??? (in /lib/x86_64-linux-gnu/libexpat.so.1.6.11)
==28975==    by 0x78506AF: ??? (in /lib/x86_64-linux-gnu/libexpat.so.1.6.11)
==28975==    by 0x784DB82: ??? (in /lib/x86_64-linux-gnu/libexpat.so.1.6.11)
==28975==    by 0x784F04D: ??? (in /lib/x86_64-linux-gnu/libexpat.so.1.6.11)
==28975==    by 0x7852DBF: XML_ParseBuffer (in /lib/x86_64-linux-gnu/libexpat.so.1.6.11)
==28975==    by 0x10526F42: ??? (in /usr/lib/x86_64-linux-gnu/libfontconfig.so.1.12.0)
==28975==    by 0x1052737B: ??? (in /usr/lib/x86_64-linux-gnu/libfontconfig.so.1.12.0)
==28975== 
==28975== LEAK SUMMARY:
==28975==    definitely lost: 6,720 bytes in 28 blocks
==28975==    indirectly lost: 2,151 bytes in 101 blocks
==28975==      possibly lost: 2,262,479 bytes in 7,977 blocks
==28975==    still reachable: 1,286,008 bytes in 10,760 blocks
==28975==         suppressed: 0 bytes in 0 blocks
==28975== Reachable blocks (those to which a pointer was found) are not shown.
==28975== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==28975== 
==28975== Use --track-origins=yes to see where uninitialised values come from
==28975== For lists of detected and suppressed errors, rerun with: -s
==28975== ERROR SUMMARY: 56147 errors from 2060 contexts (suppressed: 2 from 2)

Sorry, I'm not a heavy valgrind user, can't make a good use of its output. It seems however that the leaks are coming from SDL, X, and fontconfig (which is loaded lazily when fonts are rendered. In your case SegmentedControl triggered it). I would assume those are one-shot globals and nothing to worry about. Unless you can prove that the leaks are growing over runtime.

OK, thanks. I am not a Valgrind expert either. I am just digging in to a project with nimx, and will monitor memory use over time.

In my project, I use a SegmentedControl to switch the current view. I'd like to confirm that the approach in main.nim shown below is the idiomatic way to do it, and that I can expect GC to clean up any resources for the replaced view.

    let nv = View(newObjectOfClass(allSamples[firstSelectedRow].className))
    nv.init(currentView.frame)
    nv.resizingMask = "wh"
    splitView.replaceSubview(currentView, nv)
    currentView = nv

I'd like to confirm that the approach...

Regarding the GC there's nothing to worry about. However I would suggest using the new layout syntax rather than procedural view creation. Samples:
https://github.com/yglukhov/nimx/blob/master/test/sample14_layout.nim
https://github.com/yglukhov/nimx/blob/version-2/test/main.nim

Docs: https://github.com/yglukhov/nimx/blob/version-2/doc/layout-dsl.md

Thanks for the links. I'm just starting to think about layouts.

I'll close for now and monitor memory use.