Project

General

Profile

Actions

Bug #16455

closed

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

Added by luizluca (Luiz Angelo Daros de Luca) over 4 years ago. Updated 2 days ago.

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

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


Files

aarch64_be.patch (480 Bytes) aarch64_be.patch puchuu (Andrew Aladjev), 10/01/2020 10:19 PM

Updated by mame (Yusuke Endoh) over 4 years ago

  • Assignee set to ioquatix (Samuel Williams)

Updated by nobu (Nobuyoshi Nakada) over 4 years 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) about 4 years 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) about 4 years 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) about 4 years 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) about 4 years 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) almost 4 years ago

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

Updated by ncopa (Natanael Copa) almost 4 years ago

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

Updated by puchuu (Andrew Aladjev) over 3 years ago

ioquatix (Samuel Williams) wrote in #note-7:

It is fixed: https://github.com/ruby/ruby/pull/2995

Hello, you have provided good fix but it is related to armv7 only.
For example: aarch64-gentoo-linux-musl and aarch64_be-gentoo-linux-musl are valid CHOSTS, but first one works fine, second one fails.
First one is using "rb_cv_coroutine=arm64", second one is using default "rb_cv_coroutine=ucontext".
Same thing will be true for s390x, other arches: it will try to use default broken (for musl) "rb_cv_coroutine=ucontext".

@luizluca (Luiz Angelo Daros de Luca) have provided right fix - it works perfect. https://github.com/ruby/ruby/pull/3567

Updated by ioquatix (Samuel Williams) over 3 years ago

Understood. The PR looks acceptable and the right fix.

My advice is to avoid the copy coroutine implementation if at all possible, so we should try to detect as many native implementation paths as possible.

Actions #11

Updated by hsbt (Hiroshi SHIBATA) over 3 years ago

  • Target version changed from 36 to 3.0

Updated by puchuu (Andrew Aladjev) over 3 years ago

I've checked that current "aarch64" coroutine works fine for "aarch64_be" (at least for qemu). So I am going to propose to update "aarch64" wildcard.

Updated by luizluca (Luiz Angelo Daros de Luca) about 3 years ago

I still the get same issue with 3.0.0.

Ruby cannot blindly try to use ucontext without checking for getcontext swapcontext makecontext presence.
https://github.com/ruby/ruby/pull/3567 does work. It only needs to be refreshed, removing the #include.

Actions #14

Updated by hsbt (Hiroshi SHIBATA) 2 days ago

  • Tags changed from patch, fiber to patch, fiber, musl
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0