From: "U.Nakamura" Date: 2010-07-16T12:57:36+09:00 Subject: [ruby-core:31307] Re: [Bug #3523][Assigned] win32 exception c0000029 on exit using fibers Hello, > http://redmine.ruby-lang.org/issues/show/3523 Interim report: There is a patch for ruby_1_9_2, to save and restore SEH frame. After this patch is applied, Bill's 0xC0000029 error vanishes! ... But another error 0xC0000374 occurs. This error means heap corruption. I cannot confirm yet whether this error is due to ruby or EventMachine. Index: cont.c =================================================================== --- cont.c (revision 28653) +++ cont.c (working copy) @@ -39,6 +39,9 @@ typedef struct rb_context_struct { VALUE *machine_register_stack_src; int machine_register_stack_size; #endif +#if _WIN32 && (defined(_M_IX86) || defined(__i386__)) + VALUE win32_exception_list; +#endif rb_thread_t saved_thread; rb_jmpbuf_t jmpbuf; size_t machine_stack_size; @@ -224,6 +227,44 @@ fiber_memsize(const void *ptr) return 0; } +#if _WIN32 && (defined(_M_IX86) || defined(__i386__)) +static inline VALUE +win32_get_exception_list(void) +{ + VALUE p; +# if defined _MSC_VER +# ifdef _M_IX86 +# if _MSC_VER >= 1310 + /* warning: unsafe assignment to fs:0 ... this is ok */ +# pragma warning(disable: 4733) +# endif + __asm mov eax, fs:[0]; + __asm mov p, eax; +# endif +# elif defined __GNUC__ +# ifdef __i386__ + __asm__("movl %%fs:0,%0" : "=r"(p)); +# endif +# endif + return p; +} + +static inline void +win32_set_exception_list(VALUE p) +{ +# if defined _MSC_VER +# ifdef _M_IX86 + __asm mov eax, p; + __asm mov fs:[0], eax; +# endif +# elif defined __GNUC__ +# ifdef __i386__ + __asm__("movl %0,%%fs:0" :: "r"(p)); +# endif +# endif +} +#endif + static void cont_save_machine_stack(rb_thread_t *th, rb_context_t *cont) { @@ -267,6 +308,9 @@ cont_save_machine_stack(rb_thread_t *th, MEMCPY(cont->machine_register_stack, cont->machine_register_stack_src, VALUE, size); #endif +#if _WIN32 && (defined(_M_IX86) || defined(__i386__)) + cont->win32_exception_list = win32_get_exception_list(); +#endif sth->machine_stack_start = sth->machine_stack_end = 0; #ifdef __ia64 @@ -403,6 +447,9 @@ cont_restore_1(rb_context_t *cont) } #endif if (cont->machine_stack_src) { +#if _WIN32 && (defined(_M_IX86) || defined(__i386__)) + win32_set_exception_list(cont->win32_exception_list); +#endif FLUSH_REGISTER_WINDOWS; MEMCPY(cont->machine_stack_src, cont->machine_stack, VALUE, cont->machine_stack_size); Regards, -- U.Nakamura