Ruby 1.9 - embedding inside a pthread

Discussion in 'Ruby' started by Suraj Kurapati, Mar 3, 2008.

  1. Hello,

    I'm having trouble embedding Ruby 1.9 inside a pthread because calling
    ruby_sysinit() is segfaulting. I created a small example to reproduce
    the problem and illustrate my humble goal. (The reason for this weird
    way of embedding Ruby is: I need to embed Ruby inside a Verilog HDL
    simulator and this is the best way I could accomplish it!).

    There are three files in this example:

    $ ls
    extconf.rb hello.rb main.c

    First, we have a simple Ruby script:

    $ cat hello.rb
    puts "Hello World!"

    Second, we have a Makefile generator:

    $ cat extconf.rb
    require 'mkmf'

    have_library('pthread', 'pthread_create')

    have_library('ruby', 'ruby_init') ||
    have_library('ruby-static', 'ruby_init')

    create_makefile('main')

    Finally, we have a C program:

    $ cat main.c
    #include <stdio.h>
    #include <pthread.h>
    #include <ruby.h>

    RUBY_GLOBAL_SETUP

    pthread_t gRubyThread;
    pthread_mutex_t gCProgLock;

    void* gRubyThread_body(void* dummy)
    {
    int argc = 0;
    char* argv[1];

    printf("Ruby thread is calling ruby_sysinit()\n");
    ruby_sysinit(&argc, &argv);

    {
    printf("Ruby thread is calling RUBY_INIT_STACK()\n");
    RUBY_INIT_STACK;

    printf("Ruby thread is calling ruby_init()\n");
    ruby_init();

    char* file = "hello.rb"; // the file to run

    printf("Ruby interpreter is loading file: %s\n", file);
    void* node = rb_load_file(file);

    printf("Ruby thread is starting interpreter\n");
    ruby_run_node(node);
    }

    printf("Ruby thread is done, waking up C program...\n");
    pthread_mutex_unlock(&gCProgLock);
    return NULL;
    }

    int main(int argc, char** argv)
    {
    pthread_mutex_init(&gCProgLock, NULL);
    pthread_mutex_lock(&gCProgLock);

    printf("C program is putting Ruby thread in control...\n");

    pthread_create(&gRubyThread, NULL, gRubyThread_body, NULL);
    pthread_mutex_lock(&gCProgLock); // C program blocks here

    printf("C program got control back from Ruby thread,
    exiting...\n");
    return 0;
    }

    This C program is very simple: it creates a new pthread and locks
    itself. (At this point, only the pthread in running.) The pthread then
    proceeds to embed a Ruby 1.9 interpreter inside itself and have the
    interpreter run the "hello.rb" file. Once this is complete, the pthread
    unlocks the main C program and dies. Finally, the main C program exits.

    Now let's try running this example.

    Here's the version of Ruby 1.9 I am using (the official release):

    $ ruby -v
    ruby 1.9.0 (2007-12-25 revision 14709) [i686-linux]

    Generate the makefile:

    $ ruby extconf.rb
    checking for pthread_create() in -lpthread... yes
    checking for ruby_init() in -lruby... no
    checking for ruby_init() in -lruby-static... yes
    creating Makefile

    Build the C extension:

    $ make
    gcc -I. -I/home/sun/app/ruby19/include/ruby-1.9.0/i686-linux
    -I/home/sun/app/ruby19/include/ruby-1.9.0 -I. -D_FILE_OFFSET_BITS=64
    -fPIC -g -O2 -o main.o -c main.c
    main.c: In function ‘gRubyThread_body’:
    main.c:16: warning: passing argument 2 of ‘ruby_sysinit’ from
    incompatible pointer type
    gcc -shared -o main.so main.o -L. -L/home/sun/app/ruby19/lib
    -Wl,-R/home/sun/app/ruby19/lib -L. -rdynamic -Wl,-export-dynamic
    -lruby-static -lpthread -lpthread -lrt -ldl -lcrypt -lm -lc

    Copy and paste the last gcc command (from the output above) and remove
    the "-shared" option, and then run the new command:

    $ gcc -o main.so main.o -L. -L/home/sun/app/ruby19/lib
    -Wl,-R/home/sun/app/ruby19/lib -L. -rdynamic -Wl,-export-dynamic
    -lruby-static -lpthread -lpthread -lrt -ldl -lcrypt -lm -lc

    Now run the C program:

    $ ./main.so
    C program is putting Ruby thread in control...
    Ruby thread is calling ruby_sysinit()
    Segmentation fault (core dumped)

    As you can see, ruby_sysinit() core dumped on us. Why?

    Thanks for your consideration.
    --
    Posted via http://www.ruby-forum.com/.
    Suraj Kurapati, Mar 3, 2008
    #1
    1. Advertising

  2. Suraj Kurapati wrote:
    > I'm having trouble embedding Ruby 1.9 inside a pthread because calling
    > ruby_sysinit() is segfaulting. I created a small example to reproduce
    > the problem and illustrate my humble goal. (The reason for this weird
    > way of embedding Ruby is: I need to embed Ruby inside a Verilog HDL
    > simulator and this is the best way I could accomplish it!).


    I should clarify that although the main.c in this example has argc and
    argv, when I deploy my C extension as a .so file, there is no main()
    method as far as my code is concerned. The Verilog simulator owns the
    main() method and my C extension has *no* way of accessing the argc and
    argv passed to that main() method.

    For this reason, I did not pass the argc and argv from main() to the
    body of the gRubyThread (because that is the real-life scenario of this
    simple example). And since ruby_sysinit() requires an argc and argv, I
    am forced to fabricate them inside the body of gRubyThread.
    --
    Posted via http://www.ruby-forum.com/.
    Suraj Kurapati, Mar 3, 2008
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. R Mar
    Replies:
    0
    Views:
    392
    R Mar
    Jan 3, 2004
  2. Avin
    Replies:
    2
    Views:
    15,570
    Jerald Fijerald
    May 8, 2004
  3. Alexey Verkhovsky
    Replies:
    2
    Views:
    181
    Austin Ziegler
    Jul 30, 2004
  4. Joe Van Dyk

    embedding ruby + pthread

    Joe Van Dyk, Jan 9, 2006, in forum: Ruby
    Replies:
    1
    Views:
    87
  5. Denis Berezhnoy

    Ruby and --enable-pthread

    Denis Berezhnoy, Jul 27, 2009, in forum: Ruby
    Replies:
    0
    Views:
    149
    Denis Berezhnoy
    Jul 27, 2009
Loading...

Share This Page