Skip to content

Memory leak in connect() template #118

@demotomohiro

Description

@demotomohiro

Following code expands connect() template using expandMacros.

import gintro/[dummygtk, gio, gobject, glib]
import macros

var gMainLoop = newMainLoop(nil, false)

proc cbChanged(self: FileMonitor; file: GFile; otherFile: GFile = nil; eventType: FileMonitorEvent, x: int) =
  echo "File changed", x
  gMainLoop.quit

proc main =
  "foo.txt".writeFile("")
  var
    f = newGFileForPath("foo.txt")
    fmon = f.monitorFile({})

  var x = 123
  expandMacros:
    fmon.connect("changed", cbChanged, x)
  "foo.txt".writeFile("a")
  gMainLoop.run

main()

and this is expanded code:

proc connect_for_signal_cdecl_changed1(self: ptr FileMonitor00;
                                       file: ptr GFile00;
                                       otherFile: ptr GFile00;
                                       eventType: FileMonitorEvent;
                                       user_data: pointer) {.cdecl.} =
  let h: pointer = g_object_get_qdata(self, Quark)
  var file1: GFile
  if isNil(file1):
    new file1
    GC_ref(file1)
    file1.ignoreFinalizer = true
  file1.impl = file
  var otherFile1: GFile
  if isNil(otherFile1):
    new otherFile1
    GC_ref(otherFile1)
    otherFile1.ignoreFinalizer = true
  otherFile1.impl = otherFile
  cbChanged(cast[gio.FileMonitor](h), file1, otherFile1, eventType,
            cast[ptr int](user_data)[])

proc connect_for_signal_changed1(self: gio.FileMonitor; p: proc (
    self: gio.FileMonitor; file: GFile; otherFile: GFile = nil;
    eventType: FileMonitorEvent; arg: int); a: int): culong {.discardable.} =
  result =
    var ar: ref int
    new(ar)
    ar[] = a
    GC_ref(ar)
    scChanged(self, connect_for_signal_cdecl_changed1, cast[pointer](ar), {})

connect_for_signal_changed1(fmon, cbChanged, x)

This code creates ref objects and calls GC_ref to them.
Unless GC_unref is called to them in cbChanged (callback procedure), there is no way to access these ref object and they are leaked.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions