[cfe-dev] segmentation fault when using clang_disposeIndex in a C ruby extension.

cedlemo cedlemo at gmx.com
Fri May 1 02:39:30 PDT 2015


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.
User can set the options flags during the creation of the index like in 
this code:

    # index global options test
    #Clangc::GlobalOptFlags.constants
    #=> [:None, :Threadbackgroundpriorityforindexing,
    :Threadbackgroundpriorityforediting, :Threadbackgroundpriorityforall]

    class TestIndexGlobalOptions < MiniTest::Test
       def setup
         @cindex = Clangc::Index.new(true, true)
       end
       def test_index_set_global_options_None
         flags = Clangc::GlobalOptFlags::None
         @cindex.global_options = flags
         assert_equal flags, @cindex.global_options
       end
       def test_index_set_global_options_editing
         flags = Clangc::GlobalOptFlags::Threadbackgroundpriorityforediting
         @cindex.global_options = flags
         assert_equal flags, @cindex.global_options
       end
    end


This code works, the problem is when the Garbage Collector (GC) of ruby 
try to clean the instances at the very end.
It generates a segmentation fault but just for the instances created 
with the flags Threadbackgroundpriorityforediting.

Each of my Index instance have a structure like this :

    typedef struct Index_t {
         CXIndex data;
    } Index_t;


allocated with :

    #include "class_Index.h"
    #include "stdio.h"

    static void
    c_Index_struct_free(Index_t *s)
    {
       if(s)
       {

         if(s->data)
         {
           printf("SENTINEL index ptr %p\n", s->data);
           clang_disposeIndex(s->data);
         }
         printf("SENTINEL class ptr %p\n", s);
         ruby_xfree(s);
         printf("SENTINEL free end\n");
        }
    }
    static VALUE
    c_Index_struct_alloc( VALUE klass)
    {
       Index_t *i;
       i = (Index_t *) ruby_xmalloc(sizeof(Index_t)); //its an xmalloc
       printf("New class allocated at %p\n", i);
       i->data = NULL;
       /*associate */
       return Data_Wrap_Struct(klass, NULL, c_Index_struct_free,(void *)
    i );
    }


The GC call c_Index_struct_free(Index_t *s) in order to clean all and 
the clang_disposeIndex instruction generate the segfault.

Here is the output (I have added some debugging output in my C code)

    ruby test/Index_tests.rb
    Run options: --seed 10378
    # Running:

    New class allocated at 0x139bfe0
    New class ptr 0x139bfe0 with Index ptr 0x1057b30
    .New class allocated at 0x1350a30
    New class ptr 0x1350a30 with Index ptr 0x13769f0
    .

    Finished in 0.000871s, 2297.2451 runs/s, 2297.2451 assertions/s.

    2 runs, 2 assertions, 0 failures, 0 errors, 0 skips
    SENTINEL index ptr 0x1057b30
    SENTINEL class ptr 0x139bfe0
    SENTINEL free end
    SENTINEL index ptr 0x2013769f0
    test/Index_tests.rb: [BUG] Segmentation fault at 0x0003e800002782
    ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]

    -- Control frame information
    -----------------------------------------------
    c:0001 p:0000 s:0002 E:000f60 TOP    [FINISH]


    -- Machine register context
    ------------------------------------------------
      RIP: 0x00007f175c9cfb9d RBP: 0x0000000000de99f0 RSP:
    0x00007ffc5a05a000
      RAX: 0x0000000000000000 RBX: 0x00000002013769f0 RCX:
    0x000000007fffffe1
      RDX: 0x00007f175fb29970 RDI: 0x00000002013769f0 RSI:
    0x000000000000001f
       R8: 0x00000002013769f0  R9: 0x0000000000000000 R10:
    0x00007f176018e700
      R11: 0x0000000000000000 R12: 0x0000000001040000 R13:
    0x0000000001042648
      R14: 0x000000000103e060 R15: 0x00007ffc5a05a048 EFL:
    0x0000000000010206

    -- C level backtrace information
    -------------------------------------------
    /usr/lib/libruby.so.2.2 [0x7f175fcc2915]
    /usr/lib/libruby.so.2.2 [0x7f175fcc2b4c]
    /usr/lib/libruby.so.2.2 [0x7f175fb9cd4b]
    /usr/lib/libruby.so.2.2 [0x7f175fc5432e]
    /usr/lib/libc.so.6 [0x7f175f7bd540]
    /usr/lib/libclang.so(clang_disposeIndex+0x1d) [0x7f175c9cfb9d]
    /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]
    /usr/lib/libruby.so.2.2 [0x7f175fbb3d21]
    /usr/lib/libruby.so.2.2(rb_gc_call_finalizer_at_exit+0x289)
    [0x7f175fbbd169]
    /usr/lib/libruby.so.2.2(ruby_cleanup+0x3e8) [0x7f175fba3668]
    /usr/lib/libruby.so.2.2(ruby_run_node+0x25) [0x7f175fba38b5]
    ruby [0x4008ab]
    /usr/lib/libc.so.6(__libc_start_main+0xf0) [0x7f175f7aa800]
    ruby(_start+0x29) [0x4008d9]


You can see more informations here 
http://stackoverflow.com/questions/29984265/ruby-extension-for-clang-crash-with-segfault-when-gc-delete-index-object


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20150501/9f81aeb1/attachment.html>


More information about the cfe-dev mailing list