<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    I am trying to create a litte ruby extension for the c interface of
    clang for fun. I have an Index class that create a CXIndex when the
    class is initialized.<br>
    User can set the options flags during the creation of the index like
    in this code:<br>
    <br>
    <blockquote># index global options test<br>
      #Clangc::GlobalOptFlags.constants<br>
      #=> [:None, :Threadbackgroundpriorityforindexing,
      :Threadbackgroundpriorityforediting,
      :Threadbackgroundpriorityforall]<br>
      <br>
      class TestIndexGlobalOptions < MiniTest::Test<br>
        def setup<br>
          @cindex = Clangc::Index.new(true, true)<br>
        end<br>
        def test_index_set_global_options_None<br>
          flags = Clangc::GlobalOptFlags::None<br>
          @cindex.global_options = flags<br>
          assert_equal flags, @cindex.global_options<br>
        end<br>
        def test_index_set_global_options_editing<br>
          flags = 
      Clangc::GlobalOptFlags::Threadbackgroundpriorityforediting<br>
          @cindex.global_options = flags<br>
          assert_equal flags, @cindex.global_options<br>
        end<br>
      end<br>
    </blockquote>
    <br>
    This code works, the problem is when the Garbage Collector (GC) of
    ruby try to clean the instances at the very end.<br>
    It generates a segmentation fault but just for the instances created
    with the flags Threadbackgroundpriorityforediting.<br>
    <br>
    Each of my Index instance have a structure like this :<br>
    <br>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <blockquote>typedef struct Index_t {<br>
          CXIndex data; <br>
      } Index_t;<br>
    </blockquote>
    <br>
    allocated with :<br>
    <br>
    <blockquote>#include "class_Index.h"<br>
      #include "stdio.h"<br>
      <br>
      static void<br>
      c_Index_struct_free(Index_t *s)<br>
      {<br>
        if(s)<br>
        {<br>
      <br>
          if(s->data)<br>
          {<br>
            printf("SENTINEL index ptr %p\n", s->data);<br>
            clang_disposeIndex(s->data); <br>
          }<br>
          printf("SENTINEL class ptr %p\n", s);<br>
          ruby_xfree(s);<br>
          printf("SENTINEL free end\n");<br>
         }<br>
      }  <br>
      static VALUE<br>
      c_Index_struct_alloc( VALUE klass)<br>
      {<br>
        Index_t *i;<br>
        i = (Index_t *) ruby_xmalloc(sizeof(Index_t)); //its an xmalloc<br>
        printf("New class allocated at %p\n", i);<br>
        i->data = NULL;<br>
        /*associate */<br>
        return Data_Wrap_Struct(klass, NULL, c_Index_struct_free,(void
      *) i );<br>
      }<br>
    </blockquote>
    <br>
    The GC call c_Index_struct_free(Index_t *s) in order to clean all
    and the clang_disposeIndex instruction generate the segfault.<br>
    <br>
    Here is the output (I have added some debugging output in my C code)<br>
    <br>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <blockquote>ruby test/Index_tests.rb<br>
      Run options: --seed 10378<br>
      # Running:<br>
      <br>
      New class allocated at 0x139bfe0<br>
      New class ptr 0x139bfe0 with Index ptr 0x1057b30<br>
      .New class allocated at 0x1350a30<br>
      New class ptr 0x1350a30 with Index ptr 0x13769f0<br>
      .<br>
      <br>
      Finished in 0.000871s, 2297.2451 runs/s, 2297.2451 assertions/s.<br>
      <br>
      2 runs, 2 assertions, 0 failures, 0 errors, 0 skips<br>
      SENTINEL index ptr 0x1057b30<br>
      SENTINEL class ptr 0x139bfe0<br>
      SENTINEL free end<br>
      SENTINEL index ptr 0x2013769f0<br>
      test/Index_tests.rb: [BUG] Segmentation fault at 0x0003e800002782<br>
      ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]<br>
      <br>
      -- Control frame information
      -----------------------------------------------<br>
      c:0001 p:0000 s:0002 E:000f60 TOP    [FINISH]<br>
      <br>
      <br>
      -- Machine register context
      ------------------------------------------------<br>
       RIP: 0x00007f175c9cfb9d RBP: 0x0000000000de99f0 RSP:
      0x00007ffc5a05a000<br>
       RAX: 0x0000000000000000 RBX: 0x00000002013769f0 RCX:
      0x000000007fffffe1<br>
       RDX: 0x00007f175fb29970 RDI: 0x00000002013769f0 RSI:
      0x000000000000001f<br>
        R8: 0x00000002013769f0  R9: 0x0000000000000000 R10:
      0x00007f176018e700<br>
       R11: 0x0000000000000000 R12: 0x0000000001040000 R13:
      0x0000000001042648<br>
       R14: 0x000000000103e060 R15: 0x00007ffc5a05a048 EFL:
      0x0000000000010206<br>
      <br>
      -- C level backtrace information
      -------------------------------------------<br>
      /usr/lib/libruby.so.2.2 [0x7f175fcc2915]<br>
      /usr/lib/libruby.so.2.2 [0x7f175fcc2b4c]<br>
      /usr/lib/libruby.so.2.2 [0x7f175fb9cd4b]<br>
      /usr/lib/libruby.so.2.2 [0x7f175fc5432e]<br>
      /usr/lib/libc.so.6 [0x7f175f7bd540]<br>
      /usr/lib/libclang.so(clang_disposeIndex+0x1d) [0x7f175c9cfb9d]<br>
      /home/cedlemo/.gem/ruby/2.2.0/extensions/x86_64-linux/2.2.0/clangc-0.0.1/clangc/clangc.so(c_Index_struct_free+0x2c)
      [0x7f175d79ff7c]<br>
      /usr/lib/libruby.so.2.2 [0x7f175fbb3d21]<br>
      /usr/lib/libruby.so.2.2(rb_gc_call_finalizer_at_exit+0x289)
      [0x7f175fbbd169]<br>
      /usr/lib/libruby.so.2.2(ruby_cleanup+0x3e8) [0x7f175fba3668]<br>
      /usr/lib/libruby.so.2.2(ruby_run_node+0x25) [0x7f175fba38b5]<br>
      ruby [0x4008ab]<br>
      /usr/lib/libc.so.6(__libc_start_main+0xf0) [0x7f175f7aa800]<br>
      ruby(_start+0x29) [0x4008d9]<br>
    </blockquote>
    <br>
    You can see more informations here
<a class="moz-txt-link-freetext" href="http://stackoverflow.com/questions/29984265/ruby-extension-for-clang-crash-with-segfault-when-gc-delete-index-object">http://stackoverflow.com/questions/29984265/ruby-extension-for-clang-crash-with-segfault-when-gc-delete-index-object</a><br>
    <br>
    <br>
  </body>
</html>