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]?

Reply via email to