This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

segfault with pthread_cancel() and PTHREAD_STACK_MIN on armv7


Hi,

I run Gentoo Linux on Cubieboard2s (armv7v, le and be) with the
distribution's glibc-2.23. The whole system recompiled itself without
problems using gcc-6.3.0. This gcc is hardened, i.e. configured amongst
others with --enable-default-ssp.

Now I've run into a peculiar problem with pthreads, manifesting itself
in ntpd segfaulting upon startup. Turns out for very specific reasons
they spawn a thread doing an endless loop of sleep(10)'s and cancel
that. Also, they set the thread's stack size to PTHREAD_STACK_MIN.
(rationale and code can be seen here:
https://github.com/ntp-project/ntp/blob/stable/ntpd/ntpd.c#L252)

After isolating the code into the attached testcase I found that
increasing the thread's stack size by 6640 bytes or eliminating
pthread_cancel() altogehter both make the segfault go away.

The same testcase runs fine on an otherwise identical x86_64 install of
Gentoo compiled with the same kind of hardened gcc-6.3.0.

So I guess my question is: Is pthread_cancel() supposed to work with a
stack size of PTHREAD_STACK_MIN on every platform?

What might be causing my platform to require 6640 bytes more stack to
succeed?
-- 
Thanks,
Michael
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
#include <string.h>

#define PTHREAD_STACK_MIN 16384
/* segfaults: #define PT_STACK_EXTRA (6639) */
#define PT_STACK_EXTRA (6640) /* works */

static void* my_pthread_warmup_worker(void *thread_args) {
	(void)thread_args;
	for (;;)
		sleep(10);
	return NULL;
}

static void my_pthread_warmup(void) {
	pthread_t	thread;
	pthread_attr_t	thr_attr;
	int		rc;

	pthread_attr_init(&thr_attr);
	rc = pthread_attr_setstacksize(&thr_attr, PTHREAD_STACK_MIN + PT_STACK_EXTRA);
	if (0 != rc)
		printf("my_pthread_warmup: pthread_attr_setstacksize() -> %s",
			strerror(rc));
	rc = pthread_create(
		&thread, &thr_attr, my_pthread_warmup_worker, NULL);
	pthread_attr_destroy(&thr_attr);
	if (0 != rc) {
		printf("my_pthread_warmup: pthread_create() -> %s",
			strerror(rc));
	} else {
		pthread_cancel(thread);
		pthread_join(thread, NULL);
	}
}

int main(void) {
	my_pthread_warmup();
	return 0;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]