Bug #1239


build fails for OpenBSD: [BUG] register_sigaltstack. error

Added by kernigh (George Koehler) almost 14 years ago. Updated over 11 years ago.

Target version:
ruby -v:
ruby 1.9.1p0 (2009-01-30 revision 21907) [powerpc-openbsd4.5]


I have a computer with OpenBSD and I tried Ruby 1.9.1. So I obtained the source code, configured with "../configure --prefix=$HOME/prefix" and did "make". The build failed with an error. My computer has a PowerPC processor and the operating system is OpenBSD 4.5-beta.

Here I use "make -dl" to show the miniruby command causing the error:

 $ make -dl
 ./miniruby -I./lib -I.ext/common -I./- -r./ext/purelib.rb  ./mkconfig.rb -timestamp=./.rbconfig.time  -install_name=ruby  -so_name=ruby rbconfig.rb
 [BUG] register_sigaltstack. error
 ruby 1.9.1p0 (2009-01-30 revision 21907) [powerpc-openbsd4.5]
 -- control frame ----------
 c:0001 p:---- s:0002 b:0002 l:000001 d:000001 TOP
 Segmentation fault (core dumped)
 *** Error code 139
 Stop in /home/kernigh/park/ruby-wrong/ruby-1.9.1-p0 (line 691 of Makefile).

The same error happens if I do "./miniruby" with no arguments.

I looked in the Ruby source code. I found that "register_sigaltstack. error" happens if the call to sigaltstack() fails. So I searched for why sigaltstack() fails. I found the answer in the source code of the OpenBSD pthreads library.

OpenBSD does not have kernel threads. The OpenBSD pthreads library implements threads in userspace. (OpenBSD is the only operating system, that I know, where pthreads are not kernel threads. They say that Ruby 1.9 uses kernel threads, but this is not true for OpenBSD!) The OpenBSD pthreads library does override multiple libc functions, including sigaltstack().

Here is the comment in OpenBSD src/lib/libpthread/uthread/uthread_sigaltstack.c

  * IEEE Std 1003.1-2001 says:
  * "Use of this function by library threads that are not bound to
  * kernel-scheduled entities results in undefined behavior."
  * There exists code (e.g. alpha setjmp) that uses this function
  * to get information about the current stack.
  * The "undefined behaviour" in this implementation is thus:
  * o if ss is *not* null return -1 with errno set to EINVAL
  * o if oss is *not* null fill it in with information about the
  *   current stack and return 0.
  * This lets things like alpha setjmp work in threaded applications.
 sigaltstack(const struct sigaltstack *ss, struct sigaltstack *oss)
 	struct pthread *curthread = _get_curthread();
 	int ret = 0;
 	if (ss != NULL) {
 		errno = EINVAL;
 		ret = -1;
 	} else ...

So the OpenBSD pthreads library does not allow a separate signal stack. Whenever you give a signal stack to sigaltstack(), it always returns EINVAL.

So I changed my copy of ruby-1.9.1-p0/signal.c to ignore this error.

 --- signal.c.orig	Wed Jan 28 04:22:07 2009
 +++ signal.c	Mon Mar  2 14:11:01 2009
 @@ -444,8 +444,13 @@
      newSS.ss_size = ALT_STACK_SIZE;
      newSS.ss_flags = 0;
 -    if (sigaltstack(&newSS, &oldSS) < 0) 
 -	rb_bug("register_sigaltstack. error\n");
 +    if (sigaltstack(&newSS, &oldSS) < 0) {
 +	if (errno == EINVAL) {
 +	    /* ignore error, always happens with OpenBSD pthreads */
 +	}
 +	else
 +	    rb_bug("register_sigaltstack. error\n");
 +    }

I left in the call to sigaltstack(), in case OpenBSD ever fixes their broken sigaltstack() function, but I ignored the EINVAL error. (Other ways might be to put an #ifdef OpenBSD somewhere, or to #undef HAVE_SIGALTSTACK with OpenBSD.)

After I made this change to signal.c, I did "make", "make test" and "make install". Ruby seems to work correctly. All tests pass except one test in test_objectspace.rb, that seems to do an infinite loop, so I had to Control-C that test.

 #703 test_objectspace.rb:13:in `':   [ruby-dev:31911]
 FAIL 1/928 tests failed

I agree when ruby-1.9.1-p0/README claims that ruby is "Highly Portable". Except for one call to sigaltstack(), everything in Ruby 1.9.1 seems to work with OpenBSD. Though the Ruby manual pages do have a few tiny formatting mistakes, but I will not worry about that until later. I wonder if someone will fix how Ruby uses sigaltstack().

Actions #1

Updated by akr (Akira Tanaka) almost 14 years ago

  • Assignee set to yugui (Yuki Sonoda)

trunk (1.9.2dev) is already fixed.
Thank you for the report.

Actions #2

Updated by vipaca (Chad Dollins) almost 14 years ago

please change status to resolved or duped if there is an associated fix for this issue

Actions #3

Updated by nobu (Nobuyoshi Nakada) almost 14 years ago

  • Status changed from Open to Assigned
  • Assignee deleted (yugui (Yuki Sonoda))



Actions #4

Updated by nobu (Nobuyoshi Nakada) almost 14 years ago

  • Category set to core
  • Assignee set to yugui (Yuki Sonoda)
  • Target version set to 1.9.1



Actions #5

Updated by yugui (Yuki Sonoda) over 13 years ago

  • Status changed from Assigned to Closed




Also available in: Atom PDF