For reference, this is the crash I get with latest Nim compiler with wrong cast:
$ nim c --gc:arc drawingarea.nim
Hint: used config file '/home/salewski/Nim/config/nim.cfg' [Conf]
Hint: used config file '/home/salewski/Nim/config/config.nims' [Conf]
..............................................................................................
CC: ../../home/salewski/.nimble/pkgs/gintro-#v0.9.2/gintro/cairo.nim
Hint: [Link]
Hint: gc: arc; opt: none (DEBUG BUILD, `-d:release` generates faster code)
202079 lines; 3.845s; 353.93MiB peakmem; proj: /tmp/hhh/drawingarea.nim;
out: /tmp/hhh/drawingarea [SuccessX]
salewski@nuc /tmp/hhh $ ./drawing
salewski@nuc /tmp/hhh $ ./drawingarea
appStartup
Traceback (most recent call last)
/tmp/hhh/drawingarea.nim(339) drawingarea
/tmp/hhh/drawingarea.nim(337) test
/tmp/hhh/drawingarea.nim(306) newDisplay
/home/salewski/.nimble/pkgs/gintro-#v0.9.2/gintro/gio.nim(31014) run
/home/salewski/Nim/lib/core/macros.nim(546)
connect_for_signal_cdecl_configure_event2
/tmp/hhh/drawingarea.nim(151) dareaConfigureCallback
/home/salewski/.nimble/pkgs/gintro-#v0.9.2/gintro/cairoimpl.nim(180) destroy
/home/salewski/.nimble/pkgs/gintro-#v0.9.2/gintro/cairoimpl.nim(149) gcuref
/home/salewski/Nim/lib/system/arc.nim(211) GC_unref
/home/salewski/Nim/lib/system/arc.nim(171) nimDestroyAndDispose
SIGSEGV: Illegal storage access. (Attempt to read from nil?)
Segmentation fault (core dumped)
Run
That is for
proc gcuref(o: pointer) {.cdecl.} =
GC_unref(cast[RootRef](o))
proc gcurefsurface(o: pointer) {.cdecl.} =
GC_unref(cast[Surface](o))
Run
proc newContext*(target: Surface): Context =
fnew(result, gBoxedFreeCairoContext)
GC_ref(target)
result.impl = cairo_create(target.impl)
discard cairo_surface_set_user_data(target.impl, NUDK,
cast[pointer](target), gcuref)
#discard cairo_set_user_data(result.impl, NUDK, cast[pointer](target),
gcurefsurface)
Run
With the correct cast all works.
The good news is that for the main gintro modules there is no problem, as all
GC_unref() is used for GObject data type, so all casts are fine. For the cairo
binding I could provide a own gcuref proc for each type, so that all casts are
correct. Some more work, some more code. But I wonder why it worked for so many
years. And I think it can work, as I can make my own GC_ref/GC_unref for
RootRefs just by adding the refs to a a seq[RootRef]?