From: Ivan Maidanski Date: Fri, 20 Jul 2012 20:36:34 +0000 (+0400) Subject: Fix stop_info.stack_ptr assignment in GC_suspend_all for OpenBSD X-Git-Tag: gc7_2d~1^2~6 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e196288adb5f9579218746377f1237399f4789f9;p=gc Fix stop_info.stack_ptr assignment in GC_suspend_all for OpenBSD (commit '7ff92dc' from master branch) * os_dep.c (GC_get_stack_base): Abort if pthread_stackseg_np fails (if GC_OPENBSD_THREADS). * pthread_stop_world.c (GC_suspend_all): Get correct stack_ptr by calling pthread_stackseg_np (subtracting ss_size from ss_sp) instead of retrieving it from OpenBSD pthread implementation-dependent context (if GC_OPENBSD_THREADS); remove comment. --- diff --git a/os_dep.c b/os_dep.c index 333421d4..d9d8fdae 100644 --- a/os_dep.c +++ b/os_dep.c @@ -1304,7 +1304,8 @@ GC_INNER word GC_page_size = 0; GC_API int GC_CALL GC_get_stack_base(struct GC_stack_base *sb) { stack_t stack; - pthread_stackseg_np(pthread_self(), &stack); + if (pthread_stackseg_np(pthread_self(), &stack)) + ABORT("pthread_stackseg_np(self) failed"); sb->mem_base = stack.ss_sp; return GC_SUCCESS; } diff --git a/pthread_stop_world.c b/pthread_stop_world.c index 811cfb5a..20f54f97 100644 --- a/pthread_stop_world.c +++ b/pthread_stop_world.c @@ -446,15 +446,14 @@ STATIC int GC_suspend_all(void) # endif # ifdef GC_OPENBSD_THREADS - if (pthread_suspend_np(p -> id) != 0) - ABORT("pthread_suspend_np failed"); - /* This will only work for userland pthreads. It will */ - /* fail badly on rthreads. Perhaps we should consider */ - /* a pthread_sp_np() function that returns the stack */ - /* pointer for a suspended thread and implement in both */ - /* pthreads and rthreads. */ - p -> stop_info.stack_ptr = - *(ptr_t *)((char *)p -> id + UTHREAD_SP_OFFSET); + { + stack_t stack; + if (pthread_suspend_np(p -> id) != 0) + ABORT("pthread_suspend_np failed"); + if (pthread_stackseg_np(p->id, &stack)) + ABORT("pthread_stackseg_np failed"); + p -> stop_info.stack_ptr = (ptr_t)stack.ss_sp - stack.ss_size; + } # else # ifndef PLATFORM_ANDROID result = pthread_kill(p -> id, SIG_SUSPEND);