1
0
mirror of https://git.FreeBSD.org/ports.git synced 2024-12-23 04:23:08 +00:00

- 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>
This commit is contained in:
Stanislav Sedov 2009-06-19 12:42:45 +00:00
parent 3be2edf560
commit 263664e7b5
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=236301
4 changed files with 184 additions and 20 deletions

View File

@ -170,7 +170,7 @@ RUBY?= ${LOCALBASE}/bin/${RUBY_NAME}
# Ruby 1.8
#
RUBY_RELVERSION= 1.8.7
RUBY_PORTREVISION= 2
RUBY_PORTREVISION= 3
RUBY_PORTEPOCH= 1
RUBY_PATCHLEVEL= 160

View File

@ -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
#

View File

@ -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=""}
;;
*)

View File

@ -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;