Hi,

At Fri, 12 Dec 2003 03:08:58 +0900,
ts wrote:
> N> I tried it against the latest Ruby CVS, and it still crashes. It seemed 
> N> to take (subjectively) longer to crash, though. Interestingly, 2 out of 
> N> 3 runs gave me this instead of a segfault:
> 
>  Well, look where it crash.
> 
>  With the previous version normally you have a crash in
>    * rb_thread_restore_content()
>    * and localjump_destination()
> 
>  normally with the new patch (if I'm right), you have just a crash in
>    * localjump_destination()

Then, it'd be simple.


Index: eval.c =================================================================== RCS file: /cvs/ruby/src/ruby/eval.c,v retrieving revision 1.602 diff -u -2 -p -r1.602 eval.c --- eval.c 11 Dec 2003 21:06:14 -0000 1.602 +++ eval.c 11 Dec 2003 21:09:34 -0000 @@ -30,5 +30,11 @@ #include <stdio.h> -#include <setjmp.h> +#if defined(__ia64__) || defined(HAVE_NATIVETHREAD) +# include <ucontext.h> +# define USE_CONTEXT +#else +# include <setjmp.h> +#endif + #include "st.h" #include "dln.h" @@ -83,4 +89,26 @@ char *strrchr _((const char*,const char) #endif +#ifdef USE_CONTEXT +typedef struct { + ucontext_t context; + volatile int status; +} rb_jmpbuf_t[1]; + +#undef longjmp +#undef setjmp +NORETURN(static void rb_jump_context(rb_jmpbuf_t, int)); +static inline void +rb_jump_context(env, val) + rb_jmpbuf_t env; + int val; +{ + env->status = val; + setcontext(&env->context); + abort(); /* ensure noreturn */ +} +#define longjmp(env, val) rb_jump_context(env, val) +#define setjmp(j) ((j)->status = 0, getcontext(&(j)->context), (j)->status) +#else +typedef jmp_buf rb_jmpbuf_t; #ifndef setjmp #ifdef HAVE__SETJMP @@ -89,4 +117,5 @@ char *strrchr _((const char*,const char) #endif #endif +#endif #include <sys/types.h> @@ -848,5 +877,5 @@ static struct iter *ruby_iter; struct tag { - jmp_buf buf; + rb_jmpbuf_t buf; struct FRAME *frame; struct iter *iter; @@ -7859,5 +7888,4 @@ Init_Proc() #ifdef __ia64__ -#include <ucontext.h> #if defined(__FreeBSD__) /* @@ -7964,10 +7992,5 @@ enum thread_status { struct thread { struct thread *next, *prev; -#ifdef __ia64__ - ucontext_t context; - int context_status; -#else - jmp_buf context; -#endif + rb_jmpbuf_t context; #ifdef SAVE_WIN32_EXCEPTION_LIST DWORD win32_exception_list; @@ -8351,5 +8374,5 @@ rb_thread_save_context(th) FLUSH_REGISTER_WINDOWS; MEMCPY(th->stk_ptr, th->stk_pos, VALUE, th->stk_len); -#ifdef __ia64__ +#ifdef USE_CONTEXT { ucontext_t ctx; @@ -8357,4 +8380,5 @@ rb_thread_save_context(th) getcontext(&ctx); +#ifdef __ia64__ bot = (VALUE*)__libc_ia64_register_backing_store_base; #if defined(__FreeBSD__) @@ -8366,4 +8390,5 @@ rb_thread_save_context(th) REALLOC_N(th->bstr_ptr, VALUE, th->bstr_len); MEMCPY(th->bstr_ptr, (VALUE*)__libc_ia64_register_backing_store_base, VALUE, th->bstr_len); +#endif } #endif @@ -8435,14 +8460,7 @@ rb_thread_switch(n) } -#ifdef __ia64__ -# define THREAD_SAVE_CONTEXT(th) \ - (rb_thread_save_context(th),\ - th->context_status = 0,\ - rb_thread_switch((FLUSH_REGISTER_WINDOWS, getcontext(&th->context),(th)->context_status))) -#else -# define THREAD_SAVE_CONTEXT(th) \ +#define THREAD_SAVE_CONTEXT(th) \ (rb_thread_save_context(th),\ rb_thread_switch((FLUSH_REGISTER_WINDOWS, setjmp((th)->context)))) -#endif NORETURN(static void rb_thread_restore_context _((rb_thread_t,int))); @@ -8522,10 +8540,5 @@ rb_thread_restore_context(th, exit) tmp->last_match = tval; -#ifdef __ia64__ - tmp->context_status = ex; - setcontext(&tmp->context); -#else longjmp(tmp->context, ex); -#endif }
-- Nobu Nakada