Project

General

Profile

Bug #16455

coroutine ucontext uses deprecated POSIX getcontext/swapcontext/makecontext, absent in musl and uclibc

Added by luizluca (Luiz Angelo Daros de Luca) 8 months ago. Updated 4 months ago.

Status:
Closed
Priority:
Normal
Target version:
ruby -v:
ruby 2.7.0p0 (2019-12-25 revision 647ee6f091)
[ruby-core:96499]
Tags:

Description

Hello,

While building ruby 2.7.0 for mips with musl, it fails:

linking miniruby                                                                                   /home/luizluca/prog-local/openwrt/trunk/staging_dir/toolchain-mips_24kc_gcc-8.3.0_musl/lib/gcc/mips-openwrt-linux-musl/8.3.0/../../../../mips-openwrt-linux-musl/bin/ld: cont.o: in function `coroutine_initialize_main':                                                                                cont.c:(.text+0x36c): undefined reference to `getcontext'                                          /home/luizluca/prog-local/openwrt/trunk/staging_dir/toolchain-mips_24kc_gcc-8.3.0_musl/lib/gcc/mips-openwrt-linux-musl/8.3.0/../../../../mips-openwrt-linux-musl/bin/ld: cont.o: in function `fiber_setcontext':                                                                                         cont.c:(.text+0xde6): undefined reference to `swapcontext'                                         /home/luizluca/prog-local/openwrt/trunk/staging_dir/toolchain-mips_24kc_gcc-8.3.0_musl/lib/gcc/mips-openwrt-linux-musl/8.3.0/../../../../mips-openwrt-linux-musl/bin/ld: cont.o: in function `fiber_switch':                                                                                             cont.c:(.text+0x16b8): undefined reference to `makecontext'                                        collect2: error: ld returned 1 exit status                                                         make[3]: *** [Makefile:271: miniruby] Error 1

It seems that now ruby either uses native ASM code or ucontext for coroutine.
Both are unavailable in my crossbuild. It was building and running with 2.6.x:

configure:25935: checking native coroutine implementation for mips-linux-gnu                       configure:25976: result: no

With 2.7.0:

configure:26536: checking native coroutine implementation for mips-linux-gnu                       configure:26601: result: ucontext

I tried to disable it with --without-coroutine, --with-out-coroutine and --with-coroutine=no, but it is innocuous or try to use a "no" implementation.

It looks like this introduced the change https://github.com/ruby/ruby/commit/7291fef55c90b9ab6b3c22018b16972861b98c9d

And musl might never fix it:
https://wiki.musl-libc.org/open-issues.html

Updated by mame (Yusuke Endoh) 8 months ago

  • Assignee set to ioquatix (Samuel Williams)

Updated by nobu (Nobuyoshi Nakada) 8 months ago

luizluca (Luiz Angelo Daros de Luca) wrote:

I tried to disable it with --without-coroutine, --with-out-coroutine and --with-coroutine=no, but it is innocuous or try to use a "no" implementation.

Does —-with-coroutine=copy work?

Updated by luizluca (Luiz Angelo Daros de Luca) 7 months ago

nobu (Nobuyoshi Nakada) wrote:

luizluca (Luiz Angelo Daros de Luca) wrote:

I tried to disable it with --without-coroutine, --with-out-coroutine and --with-coroutine=no, but it is innocuous or try to use a "no" implementation.

Does —-with-coroutine=copy work?

Yes. And it also affects uclibc.

autoconf should test for getcontext/swapcontext/makecontext at link time as musl do have them declared (but not implemented). uclibc fails even before, while building as it does not even declare them.

For those cases, copy might work.

Updated by luizluca (Luiz Angelo Daros de Luca) 7 months ago

  • Subject changed from coroutine ucontext uses deprecated POSIX getcontext/swapcontext/makecontext, absent in musl to coroutine ucontext uses deprecated POSIX getcontext/swapcontext/makecontext, absent in musl and uclibc

nobu (Nobuyoshi Nakada) wrote:

luizluca (Luiz Angelo Daros de Luca) wrote:

I tried to disable it with --without-coroutine, --with-out-coroutine and --with-coroutine=no, but it is innocuous or try to use a "no" implementation.

Does —-with-coroutine=copy work?

I created a patch to fix the build with musl/uclibc:

--- a/configure.ac
+++ b/configure.ac
@@ -2344,7 +2344,10 @@ AS_CASE([$rb_cv_coroutine], [yes|''], [
             rb_cv_coroutine=copy
         ],
         [*], [
-            rb_cv_coroutine=ucontext
+            AC_CHECK_FUNCS([getcontext swapcontext makecontext],
+                [rb_cv_coroutine=ucontext],
+                [rb_cv_coroutine=copy; break]
+            )
         ]
     )
     AC_MSG_RESULT(${rb_cv_coroutine})

It is ugly as it outputs AC_CHECK_FUNCS tests in the middle of checking coroutine implementations.

Updated by luizluca (Luiz Angelo Daros de Luca) 7 months ago

There is also a missing include for copy to work with musl:

+--- a/coroutine/copy/Context.h
++++ b/coroutine/copy/Context.h
+@@ -13,6 +13,7 @@
+ #include <string.h>
+ #include <stdlib.h>
+ #include <alloca.h>
++#include <sys/types.h>
+ 
+ #define COROUTINE __attribute__((noreturn)) void
+

Updated by ioquatix (Samuel Williams) 7 months ago

Copy implementation is the right one. But what architecture are you compiling for? because copy coroutine is so slow.

Updated by ioquatix (Samuel Williams) 4 months ago

  • Target version set to 2.8
  • Status changed from Open to Closed

Updated by ncopa (Natanael Copa) 4 months ago

This is still an issue for alpine s390x. See #16809

Also available in: Atom PDF