diff options
author | stas <stas@FreeBSD.org> | 2009-06-19 20:42:45 +0800 |
---|---|---|
committer | stas <stas@FreeBSD.org> | 2009-06-19 20:42:45 +0800 |
commit | 8abc2f4e8aa2d4475b91f48e9b09fd4758ff91de (patch) | |
tree | bd7e955ed22b957261fbea3e879a92fb61a48a3c /lang | |
parent | 26301273e3bf570440a2442318b67364c2f847f3 (diff) | |
download | freebsd-ports-gnome-8abc2f4e8aa2d4475b91f48e9b09fd4758ff91de.tar.gz freebsd-ports-gnome-8abc2f4e8aa2d4475b91f48e9b09fd4758ff91de.tar.zst freebsd-ports-gnome-8abc2f4e8aa2d4475b91f48e9b09fd4758ff91de.zip |
- Fix stack overflow detection algorithm. It has not worked before as
we were linking the ruby binary against pthreads, and the default
stack size detection method with getrlimit didn't returned right
values in this case. Now, if threads enabled, it also tries to
determine the stack size via pthreads calls and use this value if
it is smaller than what getrlimit returned. Furthermore, the stack
overflow detection routine now works proactively, generating
exception if there're probability the stack will be exhausted by
the time of the next check (ruby performs checks only in each 256th
call of rb_call0). [1]
- Build pthreads-enabled ruby by default. I have not received any
bug reports for this for years, and this verison will work correctly
with threaded libraries. Also, do not link agains pthreads in non-pthread
case (this breaks stack size detection algorithm), and eliminate the
option to disable pthreads (so only power users who know what they're
doing can disable them).
- Build RDoc by default so it is available in the package.
- Bump portrevision.
PR: ports/132158
Reported by: Eugene Pimenov <libc@libc.st>
Diffstat (limited to 'lang')
-rw-r--r-- | lang/ruby18/Makefile | 26 | ||||
-rw-r--r-- | lang/ruby18/files/patch-configure.in | 35 | ||||
-rw-r--r-- | lang/ruby18/files/patch-gc.c | 141 |
3 files changed, 183 insertions, 19 deletions
diff --git a/lang/ruby18/Makefile b/lang/ruby18/Makefile index 21de40cf43b3..ee7e77cc1728 100644 --- a/lang/ruby18/Makefile +++ b/lang/ruby18/Makefile @@ -24,6 +24,9 @@ CONFIGURE_ARGS= ${RUBY_CONFIGURE_ARGS} \ --enable-shared --with-openssl-include=${OPENSSLINC} USE_OPENSSL= yes USE_LDCONFIG= yes +USE_AUTOTOOLS= aclocal:110 autoconf:262 +ACLOCAL_ARGS= -I ${LOCALBASE}/share/aclocal +AUTOMAKE_ARGS= --add-missing WRKSRC= ${WRKDIR}/${PORTNAME}-${RUBY_DISTVERSION} @@ -34,10 +37,9 @@ RUBY_NO_BUILD_DEPENDS= yes RUBY_NO_RUN_DEPENDS= yes _RUBY_SYSLIBDIR= ${PREFIX}/lib -OPTIONS= PTHREADS "Enable pthreads support (may break some apps)" off \ - ONIGURUMA "Build with oniguruma regular expressions lib" off \ +OPTIONS= ONIGURUMA "Build with oniguruma regular expressions lib" off \ IPV6 "Enable IPv6 support" on \ - RDOC "Build and install Rdoc indexes" off \ + RDOC "Build and install Rdoc indexes" on \ DEBUG "Compile-in debug info" off .include <bsd.port.pre.mk> @@ -53,14 +55,12 @@ _SUF1= _${PORTREVISION} .endif PKGNAMESUFFIX= #empty -CFLAGS+= ${PTHREAD_CFLAGS} # Keep this, else ruby will fail to load -LDFLAGS+= ${PTHREAD_LIBS} # libraries dependent op libpthread. -.if defined(WITH_PTHREADS) -CONFIGURE_ARGS+=--enable-pthread -PKGNAMESUFFIX:= ${PKGNAMESUFFIX}+pthreads -.else +.if defined(WITHOUT_PTHREADS) CONFIGURE_ARGS+=--disable-pthread +PKGNAMESUFFIX:= ${PKGNAMESUFFIX}+nopthreads +.else +CONFIGURE_ARGS+=--enable-pthread .endif .if defined(WITH_ONIGURUMA) @@ -81,7 +81,7 @@ STRIP= # none # # Disable doc generation if requested or docs disabled at all # -.if defined(WITH_RDOC) && !defined(NOPORTDOCS) +.if !defined(WITHOUT_RDOC) && !defined(NOPORTDOCS) CONFIGURE_ARGS+= --enable-install-doc .else CONFIGURE_ARGS+= --disable-install-doc @@ -130,12 +130,6 @@ post-extract: ${MV} ${WRKSRC}/ext/dl/h2rb ${WRKSRC}/bin/ post-patch: -.if ${ARCH} == "sparc64" || ${ARCH} == "alpha" - ${REINPLACE_CMD} -e 's|-lc"|"|g' ${WRKSRC}/configure -.endif - ${REINPLACE_CMD} -e 's|-l$$pthread_lib|${PTHREAD_LIBS}|g' \ - ${WRKSRC}/configure - # # Remove modules we don't want # diff --git a/lang/ruby18/files/patch-configure.in b/lang/ruby18/files/patch-configure.in new file mode 100644 index 000000000000..35837db64974 --- /dev/null +++ b/lang/ruby18/files/patch-configure.in @@ -0,0 +1,35 @@ +--- configure.in.orig 2009-01-19 12:25:38.000000000 +0300 ++++ configure.in 2009-06-19 15:35:22.000000000 +0400 +@@ -1020,7 +1020,7 @@ + case $pthread_lib in + c) + ;; +- c_r) ++ c_r | pthread) + MAINLIBS="-pthread $MAINLIBS" + ;; + *) +@@ -1037,6 +1037,14 @@ + AC_DEFINE(HAVE_NANOSLEEP) + fi + fi ++ AC_MSG_CHECKING([for pthread_np.h]) ++ AC_TRY_COMPILE([ ++ #include <pthread.h> ++ #include <pthread_np.h>], ++ [(void)0;], ++ AC_MSG_RESULT(yes) ++ AC_DEFINE(HAVE_PTHREAD_NP_H), ++ AC_MSG_RESULT(no)) + fi + if test x"$ac_cv_header_ucontext_h" = xyes; then + if test x"$rb_with_pthread" = xyes; then +@@ -1441,7 +1449,7 @@ + SOLIBS= + + case "$target_os" in +- cygwin*|mingw*|beos*|openstep*|nextstep*|rhapsody*|darwin*|os2-emx*) ++ cygwin*|mingw*|beos*|openstep*|nextstep*|rhapsody*|darwin*|os2-emx*|freebsd*) + : ${DLDLIBS=""} + ;; + *) diff --git a/lang/ruby18/files/patch-gc.c b/lang/ruby18/files/patch-gc.c index 8d285937cdbf..873c96c76908 100644 --- a/lang/ruby18/files/patch-gc.c +++ b/lang/ruby18/files/patch-gc.c @@ -1,6 +1,141 @@ ---- gc.c.orig 2009-06-18 14:18:33.000000000 +0400 -+++ gc.c 2009-06-18 14:18:45.000000000 +0400 -@@ -1980,7 +1980,7 @@ +--- gc.c.orig 2009-03-27 13:25:23.000000000 +0300 ++++ gc.c 2009-06-19 16:26:54.000000000 +0400 +@@ -30,6 +30,10 @@ + #include <sys/resource.h> + #endif + ++#if defined(HAVE_PTHREAD_NP_H) ++#include <pthread_np.h> ++#endif ++ + #if defined _WIN32 || defined __CYGWIN__ + #include <windows.h> + #endif +@@ -75,6 +79,7 @@ + static void run_final(); + static VALUE nomem_error; + static void garbage_collect(); ++static void set_stack_limit(); + + int ruby_gc_stress = 0; + +@@ -534,9 +539,14 @@ + + #define GC_WATER_MARK 512 + +-#define CHECK_STACK(ret) do {\ ++#define CHECK_STACK(ret, prev) do {\ + SET_STACK_END;\ +- (ret) = (STACK_LENGTH > STACK_LEVEL_MAX + GC_WATER_MARK);\ ++ ssize_t avail = STACK_LEVEL_MAX + GC_WATER_MARK - STACK_LENGTH;\ ++ if (avail <= 0 || (prev != -1 && (signed)(STACK_LENGTH - prev) > avail))\ ++ (ret) = 1;\ ++ else\ ++ (ret) = 0;\ ++ (prev) = STACK_LENGTH;\ + } while (0) + + size_t +@@ -552,8 +562,9 @@ + ruby_stack_check() + { + int ret; ++ static size_t prev = -1; + +- CHECK_STACK(ret); ++ CHECK_STACK(ret, prev); + return ret; + } + +@@ -1599,18 +1610,50 @@ + } + rb_gc_stack_start = addr; + #endif ++ set_stack_limit(); ++} ++ ++static void set_stack_limit() ++{ ++ size_t stacksize = 0; ++ + #ifdef HAVE_GETRLIMIT + { + struct rlimit rlim; + +- if (getrlimit(RLIMIT_STACK, &rlim) == 0) { +- unsigned int space = rlim.rlim_cur/5; ++ if (getrlimit(RLIMIT_STACK, &rlim) == 0) ++ stacksize = rlim.rlim_cur; ++ } ++#elif defined _WIN32 ++ { ++ MEMORY_BASIC_INFORMATION mi; ++ ++ if (VirtualQuery(&mi, &mi, sizeof(mi))) { ++ stacksize = (char *)mi.BaseAddress - (char *)mi.AllocationBase; ++ } ++ } ++#endif ++#if defined(_THREAD_SAFE) && defined(HAVE_PTHREAD_NP_H) ++ { ++ pthread_attr_t attr; ++ size_t size; + +- if (space > 1024*1024) space = 1024*1024; +- STACK_LEVEL_MAX = (rlim.rlim_cur - space) / sizeof(VALUE); ++ pthread_attr_init(&attr); ++ if (pthread_attr_get_np(pthread_self(), &attr) == 0) { ++ pthread_attr_getstacksize(&attr, &size); ++ if (stacksize == 0 || size < stacksize) ++ stacksize = size; + } ++ pthread_attr_destroy(&attr); + } + #endif ++ if (stacksize) { ++ unsigned int space = stacksize / 5; ++ ++ if (space > 1024*1024) ++ space = 1024*1024; ++ STACK_LEVEL_MAX = (stacksize - space) / sizeof(VALUE); ++ } + } + + void ruby_init_stack(VALUE *addr +@@ -1631,31 +1674,7 @@ + rb_gc_register_stack_start = (VALUE*)bsp; + } + #endif +-#ifdef HAVE_GETRLIMIT +- { +- struct rlimit rlim; +- +- if (getrlimit(RLIMIT_STACK, &rlim) == 0) { +- unsigned int space = rlim.rlim_cur/5; +- +- if (space > 1024*1024) space = 1024*1024; +- STACK_LEVEL_MAX = (rlim.rlim_cur - space) / sizeof(VALUE); +- } +- } +-#elif defined _WIN32 +- { +- MEMORY_BASIC_INFORMATION mi; +- DWORD size; +- DWORD space; +- +- if (VirtualQuery(&mi, &mi, sizeof(mi))) { +- size = (char *)mi.BaseAddress - (char *)mi.AllocationBase; +- space = size / 5; +- if (space > 1024*1024) space = 1024*1024; +- STACK_LEVEL_MAX = (size - space) / sizeof(VALUE); +- } +- } +-#endif ++ set_stack_limit(); + } + + /* +@@ -1980,7 +1999,7 @@ chain_finalized_object(st_data_t key, st_data_t val, st_data_t arg) { RVALUE *p = (RVALUE *)key, **final_list = (RVALUE **)arg; |