ruby: fix crashes on musl + never use precompiled native gems on musl

This commit is contained in:
q66 2020-02-21 03:24:42 +01:00
parent 4cc2b6d835
commit 5cc78499fe
4 changed files with 162 additions and 1 deletions

View file

@ -0,0 +1,31 @@
From: Jakub Jirutka <jakub@jirutka.cz>
Date: Fri, 19 May 2017 19:56:00 +0200
Subject: [PATCH] Rubygems: don't install platform-specific gems
Gems with native extensions typically contain just source code that is
built during installation on user's system. However, Rubygems allows to
publish even platform-specific gems with prebuilt binaries for specific
platform. The problem is that Rubygems uses only short platform
identification like x86_64-linux; it does not identify used libc.
And sadly platform-specific gems for linux are built against glibc, so
they may not work on musl libc.
This patch is a workaround for the aforesaid problem. It removes local
platform from Rubygems' supported platforms to force it always pick
a platform-agnostic (source) gem. Users can override it using
`--platform` option.
--- a/lib/rubygems.rb
+++ b/lib/rubygems.rb
@@ -764,7 +764,10 @@
def self.platforms
@platforms ||= []
if @platforms.empty?
- @platforms = [Gem::Platform::RUBY, Gem::Platform.local]
+ # XXX: Patched to avoid installing platform-specific gems with binaries
+ # linked against glibc.
+ @platforms = [Gem::Platform::RUBY]
+ #@platforms = [Gem::Platform::RUBY, Gem::Platform.local]
end
@platforms
end

View file

@ -0,0 +1,74 @@
Source: Adélie Linux
Fixes crashes on some musl platforms.
diff --git a/thread_pthread.c b/thread_pthread.c
index 951885ffa0..cf90321d1d 100644
--- thread_pthread.c
+++ thread_pthread.c
@@ -552,9 +552,6 @@ hpux_attr_getstackaddr(const pthread_attr_t *attr, void **addr)
# define MAINSTACKADDR_AVAILABLE 0
# endif
#endif
-#if MAINSTACKADDR_AVAILABLE && !defined(get_main_stack)
-# define get_main_stack(addr, size) get_stack(addr, size)
-#endif
#ifdef STACKADDR_AVAILABLE
/*
@@ -632,6 +629,55 @@ get_stack(void **addr, size_t *size)
return 0;
#undef CHECK_ERR
}
+
+#if defined(__linux__) && !defined(__GLIBC__) && defined(HAVE_GETRLIMIT)
+
+#ifndef PAGE_SIZE
+#include <unistd.h>
+#define PAGE_SIZE sysconf(_SC_PAGE_SIZE)
+#endif
+
+static int
+get_main_stack(void **addr, size_t *size)
+{
+ size_t start, end, limit, prevend = 0;
+ struct rlimit r;
+ FILE *f;
+ char buf[PATH_MAX+80], s[8];
+ int n;
+ STACK_GROW_DIR_DETECTION;
+
+ f = fopen("/proc/self/maps", "re");
+ if (!f)
+ return -1;
+ n = 0;
+ while (fgets(buf, sizeof buf, f)) {
+ n = sscanf(buf, "%zx-%zx %*s %*s %*s %*s %7s", &start, &end, s);
+ if (n >= 2) {
+ if (n == 3 && strcmp(s, "[stack]") == 0)
+ break;
+ prevend = end;
+ }
+ n = 0;
+ }
+ fclose(f);
+ if (n == 0)
+ return -1;
+
+ limit = 100 << 20; /* 100MB stack limit */
+ if (getrlimit(RLIMIT_STACK, &r)==0 && r.rlim_cur < limit)
+ limit = r.rlim_cur & -PAGE_SIZE;
+ if (limit > end) limit = end;
+ if (prevend < end - limit) prevend = end - limit;
+ if (start > prevend) start = prevend;
+ *addr = IS_STACK_DIR_UPPER() ? (void *)start : (void *)end;
+ *size = end - start;
+ return 0;
+}
+#else
+# define get_main_stack(addr, size) get_stack(addr, size)
+#endif
+
#endif
static struct {

View file

@ -0,0 +1,49 @@
Source: Adélie Linux
The patched test is a recursion function. We have lower stack size,
so we hit SystemStackError sooner than on other platforms.
#361 test_insns.rb:389:in `block in <top (required)>':
# recursive once
def once n
return %r/#{
if n == 0
true
else
once(n-1) # here
end
}/ox
end
x = once(128); x = once(7); x = once(16);
x =~ "true" && $~
#=> "" (expected "true") once
Stderr output is not empty
bootstraptest.tmp.rb:3:in `once': stack level too deep (SystemStackError)
from bootstraptest.tmp.rb:7:in `block in once'
from bootstraptest.tmp.rb:3:in `once'
from bootstraptest.tmp.rb:7:in `block in once'
from bootstraptest.tmp.rb:3:in `once'
from bootstraptest.tmp.rb:7:in `block in once'
from bootstraptest.tmp.rb:3:in `once'
from bootstraptest.tmp.rb:7:in `block in once'
from bootstraptest.tmp.rb:3:in `once'
... 125 levels...
from bootstraptest.tmp.rb:3:in `once'
from bootstraptest.tmp.rb:7:in `block in once'
from bootstraptest.tmp.rb:3:in `once'
from bootstraptest.tmp.rb:11:in `<main>'
Test_insns.rb FAIL 1/187
FAIL 1/1197 tests failed
Make: *** [uncommon.mk:666: yes-btest-ruby] Error 1
--- bootstraptest/test_insns.rb
+++ bootstraptest/test_insns.rb
@@ -248,7 +248,7 @@
end
}/ox
end
- x = once(128); x = once(7); x = once(16);
+ x = once(32); x = once(7); x = once(16);
x =~ "true" && $~
},
[ 'once', <<~'},', ], # {

View file

@ -3,7 +3,7 @@ _ruby_abiver=2.6.0
pkgname=ruby
version=2.6.5
revision=1
revision=2
build_style=gnu-configure
configure_args="--enable-shared --disable-rpath
DOXYGEN=/usr/bin/doxygen DOT=/usr/bin/dot PKG_CONFIG=/usr/bin/pkg-config"
@ -35,6 +35,13 @@ if [ "$CROSS_BUILD" ]; then
hostmakedepends+=" ruby"
fi
post_patch() {
[ "$XBPS_TARGET_LIBC" = "glibc" ] && return 0
echo "Patching out using binary gems for non-glibc..."
patch -sNp1 -i ${FILESDIR}/rubygems-avoid-platform-specific-gems.patch
}
pre_build() {
# Force getaddrinfo detection.
sed -e 's,\(checking_for("wide getaddrinfo") {try_\)run,\1link,' -i ext/socket/extconf.rb