Date: Mon, 30 Oct 2000 22:48:05 +0100 (CET) From: tegge@trondheim.fast.no To: FreeBSD-gnats-submit@freebsd.org Subject: ports/22429: linuxthreads port compiles liblgcc_r using wrong pthread.h Message-ID: <200010302148.e9ULm5b42061@crash.trondheim.fast.no>
next in thread | raw e-mail | index | archive | help
>Number: 22429 >Category: ports >Synopsis: linuxthreads port compiles liblgcc_r using wrong pthread.h >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-ports >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Mon Oct 30 13:50:01 PST 2000 >Closed-Date: >Last-Modified: >Originator: Tor Egge >Release: FreeBSD 5.0-CURRENT i386 >Organization: Fast Search & Transfer ASA >Environment: FreeBSD 5.0 >Description: When the linuxthread port compiles liblgcc_r, the normal Makefile for libgcc is included and some variables are overridden. Unfortunately the include path is not adjusted to use the linuxthread version of pthread.h. This results in mutexes in liblgcc_r getting the wrong definition, size and initialization, easily leading to deadlock during program startup (before main is called). When mapping anonymous memory for thread stacks, only the initial stack size is given as size argument to mmap(). On FreBSD, the maximum stack size should be given as argument, otherwise the threads will only have 16 KB stack each. When terminating a threaded application in a controlled fashion (e.g. calling exit() from the main trhread after reaping all other threads with pthread_join), global destructors are not always called. This is due to the child process (thread manager) exiting before the main thread has received the restart signal, causing the cancel signal (SIGCHLD equivalent) to be delivered instead. >How-To-Repeat: Compile linuxthread port and have variables initialized to nonzero values right after object_mutex in frame.o (in liblgcc_r.a). The threaded application might hang during startup due in __pthread_lock() due to lock->__status being nonzero. Compile a threaded application using more than 16 KB stack on each thread. Write a memory profiling tool and see memory leaks after controlled application termination caused by destructors for global objects not having been called. >Fix: To compile liblgcc using the correct pthread.h file: ------------------------ Index: files/Makefile.libgcc_r =================================================================== RCS file: /home/ncvs/ports/devel/linuxthreads/files/Makefile.libgcc_r,v retrieving revision 1.2 diff -u -r1.2 Makefile.libgcc_r --- files/Makefile.libgcc_r 2000/07/12 01:43:01 1.2 +++ files/Makefile.libgcc_r 2000/10/30 20:43:21 @@ -4,6 +4,7 @@ LIBDIR= lib/ CFLAGS+=-D_PTHREADS -I../ +CFLAGS+=-I../sysdeps/i386 -I../sysdeps/pthread -I../sysdeps/unix/sysv/linux .include "/usr/src/gnu/lib/libgcc/Makefile" ------------------------ To allow more than 16 KB stack space for each thread: ------------------------ --- manager.c.orig Sun Sep 3 01:09:04 2000 +++ manager.c Sat Sep 9 21:25:47 2000 @@ -300,8 +300,8 @@ /* Allocate space for stack and thread descriptor at default address */ new_thread = default_new_thread; new_thread_bottom = (char *) (new_thread + 1) - stacksize; - if (mmap((caddr_t)((char *)(new_thread + 1) - INITIAL_STACK_SIZE), - INITIAL_STACK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, + if (mmap((caddr_t)((char *)(new_thread + 1) - stacksize), + stacksize, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_GROWSDOWN, -1, 0) == MAP_FAILED) /* Bad luck, this segment is already mapped. */ @@ -475,8 +475,8 @@ { if (new_thread->p_guardsize != 0) munmap(new_thread->p_guardaddr, new_thread->p_guardsize); - munmap((caddr_t)((char *)(new_thread+1) - INITIAL_STACK_SIZE), - INITIAL_STACK_SIZE); + munmap((caddr_t)((char *)(new_thread+1) - STACK_SIZE), + STACK_SIZE); } __pthread_handles[sseg].h_descr = NULL; __pthread_handles[sseg].h_bottom = NULL; ------------------------ To call destructors when main thread is exiting: ------------------------ --- manager.c.orig Thu Sep 28 02:30:32 2000 +++ manager.c Thu Sep 28 02:30:33 2000 @@ -660,10 +660,14 @@ /* Process-wide exit() */ +extern int __pthread_exit_requested_bymainthread; + static void pthread_handle_exit(pthread_descr issuing_thread, int exitcode) { pthread_descr th; __pthread_exit_requested = 1; + if (issuing_thread == __pthread_main_thread) + __pthread_exit_requested_bymainthread = 1; __pthread_exit_code = exitcode; /* Send the CANCEL signal to all running threads, including the main thread, but excluding the thread from which the exit request originated --- pthread.c.orig Thu Sep 28 02:30:32 2000 +++ pthread.c Thu Sep 28 02:30:33 2000 @@ -164,6 +164,7 @@ /* For process-wide exit() */ int __pthread_exit_requested = 0; +int __pthread_exit_requested_bymainthread = 0; int __pthread_exit_code = 0; /* Pointers that select new or old suspend/resume functions @@ -680,6 +681,9 @@ if (__pthread_exit_requested) { /* Main thread should accumulate times for thread manager and its children, so that timings for main thread account for all threads. */ + if (self == __pthread_main_thread && + __pthread_exit_requested_bymainthread != 0) + return; if (self == __pthread_main_thread) waitpid(__pthread_manager_thread.p_pid, NULL, __WCLONE); _exit(__pthread_exit_code); ------------------------ >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-ports" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200010302148.e9ULm5b42061>