[#23657] [Bug #1550] String#lstrip! raises RuntimeError on Frozen String Despite Making No Changes — Run Paint Run Run <redmine@...>

Bug #1550: String#lstrip! raises RuntimeError on Frozen String Despite Making No Changes

13 messages 2009/06/01

[#23729] [Bug #1583] Time + String no Longer Raises TypeError? — Run Paint Run Run <redmine@...>

Bug #1583: Time + String no Longer Raises TypeError?

14 messages 2009/06/05

[#23770] [Bug #1595] rake unusable on windows install — Robert Gonzalez <redmine@...>

Bug #1595: rake unusable on windows install

10 messages 2009/06/09

[#23869] [Bug #1640] [PATCH] Documentation for the Rational Class — Run Paint Run Run <redmine@...>

Bug #1640: [PATCH] Documentation for the Rational Class

12 messages 2009/06/16

[#23903] [Bug #1648] Rational#div Raises NoMethodError for Invalid Argument — Run Paint Run Run <redmine@...>

Bug #1648: Rational#div Raises NoMethodError for Invalid Argument

9 messages 2009/06/17

[#23977] [ANN] meeting log of RubyDeveloperKaigi20090622 — "Yugui (Yuki Sonoda)" <yugui@...>

Hi,

41 messages 2009/06/23
[#23979] Re: [ANN] meeting log of RubyDeveloperKaigi20090622 — Run Paint Run Run <runrun@...> 2009/06/23

Thanks for the update. :-)

[#24173] Re: [ANN] meeting log of RubyDeveloperKaigi20090622 — "NARUSE, Yui" <naruse@...> 2009/07/07

Sorry for late response,

[#24174] Re: [ANN] meeting log of RubyDeveloperKaigi20090622 — Luis Lavena <luislavena@...> 2009/07/07

On Tue, Jul 7, 2009 at 12:12 AM, NARUSE, Yui<naruse@airemix.jp> wrote:

[#24242] Re: [ANN] meeting log of RubyDeveloperKaigi20090622 — Charles Oliver Nutter <headius@...> 2009/07/09

On Mon, Jul 6, 2009 at 10:18 PM, Luis Lavena<luislavena@gmail.com> wrote:

[#24010] [Bug #1685] Some windows unicode path issues remain — B Kelly <redmine@...>

Bug #1685: Some windows unicode path issues remain

26 messages 2009/06/24
[#29189] [Bug #1685] Some windows unicode path issues remain — Yuki Sonoda <redmine@...> 2010/04/01

Issue #1685 has been updated by Yuki Sonoda.

[#29200] Re: [Bug #1685] Some windows unicode path issues remain — Bill Kelly <billk@...> 2010/04/01

Yuki Sonoda wrote:

[#29892] Re: [Bug #1685] Some windows unicode path issues remain — Bill Kelly <billk@...> 2010/04/29

Hi,

[#24058] [Bug #1696] http downloads are unuseably slow — Steven Hartland <redmine@...>

Bug #1696: http downloads are unuseably slow

19 messages 2009/06/27

[#24063] [Feature #1697] Object#<=> — Marc-Andre Lafortune <redmine@...>

Feature #1697: Object#<=>

15 messages 2009/06/28

[ruby-core:23933] Stack size detection algorithm

From: Stanislav Sedov <stas@...>
Date: 2009-06-19 13:06:27 UTC
List: ruby-core #23933
Hi!

When debugging the stack overflow bug in ruby 1.8.7 on FreeBSD, I notices t=
hat
its stack detection algoritm doesn't work properly in pthreads case,
as it still uses the value returned by getrlimit as the stack maximum
size.  However, this value would not work on FreeBSD and probably other
OSes, as in pthreads case the main thread's stack size is much lower than
the stack size limit for the whole process.

I attached the patch that adds an additional check for stack size in pthread
case via pthread_attr_getstacksize if pthreads is enabled.  If the value
returned by pthread functions is lower than stack size limit, this value
will be used instead.  I also moved these checks into the separate function
to eliminate code duplication.

The other modification I made adds proactive check for stack size available.
Currently, ruby reserves up to 1/5 of available stack size for safeguard
purposes, and performs stack limit checks only each 256th call of rb_call0.
When the available stack size is too small, 1/5 of it may not be enough for
next 256 calls to rb_call0 to complete for ruby to detect overflow.  The
code I added measures how much of stack size was consumed since the previous
check and if the stack size available is lower than this value the exception
will be generated.

I attached patched to configure.in and gc.c to the mail.

--=20
Stanislav Sedov
ST4096-RIPE

Attachments (2)

patch-configure.in (523 Bytes, text/plain)
--- configure.in.orig	2009-01-19 12:25:38.000000000 +0300
+++ configure.in	2009-06-19 15:35:22.000000000 +0400
@@ -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
patch-gc.c (3.04 KB, text/x-csrc)
--- 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();
 }
 
 /*

In This Thread

Prev Next