Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

EM::epoll causes undefined symbol: rb_enable_interrupt, Ruby 1.9.4 #248

Closed
gmallard opened this Issue · 17 comments
@gmallard

Running:

ruby 1.9.4dev (2011-08-27 trunk 33096) [x86_64-linux]

With:

eventmachine (0.12.10)

And using:

EventMachine::epoll

Causes:

EM.run running echo server on 9091
ruby: symbol lookup error: /opt/r194_20110827/lib/ruby/gems/1.9.1/gems/eventmachine-0.12.10/lib/rubyeventmachine.so:     undefined symbol: rb_enable_interrupt

It looks to me like Ruby SVN Revision 32510 on trunk (1.9.4) has totally removed this function (and others).

If I comment the call to Eventmachine::epoll, this problem disappears.

@michaelklishin

Isn't it a bit early to be using Ruby 1.9.4? 1.9.3 is not out yet.

@gmallard

Probably. Just seeing what works and what does not.

The 1.9.3 branch was created on July 10.

@tmm1
Owner

Is there an alternative for this missing function. We can add a check/macro to extconf to fix the lookup error, but it will likely break ctrl+c again.

@gmallard

I misread the SVN commit message, it is a bit misleading.

Calls to these functions were removed from thread_pthread.c.

The actual functions remain in signal.c. However, it looks like 'static' was added to the function definitions. Here is a clip from the diff for that commit:

-void
+static void
 rb_disable_interrupt(void)
 {
 #if USE_TRAP_MASK
     sigset_t mask;
     sigfillset(&mask);
-    sigdelset(&mask, SIGVTALRM);
-    sigdelset(&mask, SIGSEGV);
     pthread_sigmask(SIG_SETMASK, &mask, NULL);
 #endif
 }

-void
+static void
 rb_enable_interrupt(void)
 {
 #if USE_TRAP_MASK
@@ -872,19 +866,10 @@ trap_ensure(struct trap_arg *arg)
 {
     /* enable interrupt */
     pthread_sigmask(SIG_SETMASK, &arg->mask, NULL);
-    trap_last_mask = arg->mask;
     return 0;
 }
 #endif

That has me totally confused.

The EM .so appears to be correctly linked against the Ruby .so.

And the Ruby .so appears to have those functions defined.

I do not know enough about dynamic linkage in C to understand what I am looking at.

I did clone the EM gen, and installed from the HEAD of master. Same problem, though.

If you need me to look at something else, please let me know.

@gmallard

Just checking in.

I guess I did speak about 1.9.4 too early.

On 2011-10-19 a patch went in to TRUNK that did:

-#define RUBY_VERSION "1.9.4"
+#define RUBY_VERSION "2.0.0"

so much for 1.9.4.

This EM behavior remains.

@glebm

Yep

@SamSaffron

This is still broken against 2.0 head it seems

@ghost

confirming, it is still broken

/usr/home/ruby/versions/2.0.0/bin/ruby: symbol lookup error: 
/home/slivu/gem/2.0.0/gems/eventmachine-1.0.0/lib/rubyeventmachine.so: 
undefined symbol: rb_enable_interrupt
@soffes

Still broken on Ruby 2.0.0-rc1

@balexand

I'm also getting this on 2.0.0-rc1

@ancheremukhin

On Ruby 2.0.0-rc2 is broken too.

@msievers

I think the problem is

ext/em.h (Lines 29-36)

...
#elif defined(HAVE_RB_THREAD_CHECK_INTS)
extern "C" {
void rb_enable_interrupt(void);
void rb_disable_interrupt(void);
}

#define TRAP_BEG rb_enable_interrupt()
#define TRAP_END do { rb_disable_interrupt(); rb_thread_check_ints(); } while(0)

#else
...

rb_enable_interrupt() and rb_disable_interrupt() are static functions in Ruby 2 signal.c since ruby/ruby@74b339e

Static C functions are only visible to other functions in the same file, so they can't be called anymore in Ruby 2. They can be called in 1.9.3, because there, these functions are non-static.

Removing the #elif block fixes this (tested with Thin 1.5 and Rails 4 beta).

Cheers

@Nyoho

it seems to be still broken on 2.0.0-p0.

@phoet

jip, fails on heroku too :sweat:

2013-02-25T18:40:52+00:00 app[web.1]: ruby: symbol lookup error: /app/vendor/bundle/ruby/2.0.0/gems/eventmachine-1.0.0/lib/rubyeventmachine.so: undefined symbol: rb_enable_interrupt
@joallard

Should those (rb_enable_interrupt, rb_disable_interrupt) even be called in the first place?

Related issue #389 was filed in ruby-trunk bug 7474, to which kozaki replied :

There are two problems:

1)

rb_disable_interrupt()
..
rb_enable_interrupt()

is expand to

sigfillset(&mask);
pthread_sigmask(SIG_SETMASK, &mask, NULL);

...

sigemptyset(&mask);
pthread_sigmask(SIG_SETMASK, &mask, NULL);

See? rb_enable_interrupt() ignore old sigmask and set signal mask to
empty.

2) thread unsafe

pthread_sigmask() only change current thread sigmask. then other
thread still be able to be interrupted by signal. then, this api only
work single thread context. MRI only use this api when process
creation time.

So, I have a question. Why do event machine need
rb_disable_interrupt()? If I understand correctly, event machine
don't have single thread guarantee.

@tmm1 tmm1 closed this in 3992b90
@tmm1
Owner

The disable/enable_interrupt was added in 945eb1c, after many reports of not being able to "ctrl+c" out of an running EM loop.

The test suite passes for me on 2.0.0-p0 with 3992b90. I've just pushed out a 1.0.1 gem with that fix.

@phoet

thx for fixing this, is running on heroku now!

@allomov allomov referenced this issue in cloudfoundry-incubator/admin-ui
Closed

Update to 2.1.x ruby #114

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.