Hi! devel/p5-Coro is a perl module providing threading support.
The current version 6.57 had lots of segfaults on NetBSD. I investigated with help of the author Marc Lehmann. We found that setting up the stack (i.e. the mmap()s) worked fine, but then actually using the stack lead to random segfaults. The code is quite straightforward (unifdef'ed for NetBSD), see below. When used as shown below, the random segfaults happen. When the (commented out) pthread_attr_setguardsize() is enabled, the segfaults stop. According to the NetBSD man page for pthread_attr_setguardsize(), the effect of this function is ignored when pthread_attr_setstack() is used. This does not seem to be the case here. --- begin quote from pthread_attr_getguardsize(3) --- If pthread_attr_setstack(3) or pthread_attr_setstackaddr(3) is used to set the stack address attribute in attr, the guard size attribute is ignored and no guard area will be allocated; it is the responsibility of the application to handle the overflow conditions. --- end quote --- Last year's GSoC porting wine had a similar issue, see https://blog.netbsd.org/tnf/entry/porting_wine_to_amd64_on : --- begin quote from blog entry --- Eventually, I found that pthread_attr_setstack(3) was setting the guard size to 65536 bytes even though the man page said otherwise. And Wine relied on it not being set. This resulted in out-of-bound access which caused the unhandled page fault. After setting the guard size to 0 using pthread_attr_setguardsize(3), Wine started behaving fine. --- end quote --- I think there is a bug in libpthread. Is this enough for a bug report or what more information is needed? Or perhaps someone already knows how to fix this? Cheers, Thomas >From Coro-6.57/Coro/libcoro/coro.c: void coro_create (coro_context *ctx, coro_func coro, void *arg, void *sptr, size_t ssize) { static coro_context nctx; static int once; if (!once) { once = 1; pthread_cond_init (&nctx.cv, 0); } pthread_cond_init (&ctx->cv, 0); if (coro) { pthread_attr_t attr; struct coro_init_args args; pthread_t id; args.func = coro; args.arg = arg; args.self = ctx; args.main = &nctx; pthread_attr_init (&attr); // pthread_attr_setguardsize (&attr, 0); pthread_attr_setstack (&attr, sptr, (size_t)ssize); pthread_attr_setscope (&attr, PTHREAD_SCOPE_PROCESS); pthread_create (&id, &attr, coro_init, &args); coro_transfer (args.main, args.self); } }