christos%astron.com@localhost (Christos Zoulas) writes: > In article <20130430124431.GF82407%trav.math.uni-bonn.de@localhost>, > Edgar Fuß <ef%math.uni-bonn.de@localhost> wrote: >>> It is prolly a radiusd bug: >>Maybe yes. See below. >> >>> $ PTHREAD_DIAGASSERT=a radiusd >>> $ gdb radiusd radiusd.core >>Unfortunately, this (with allow_core_dumps=yes in radiusd.conf) doesn't give >>me a core dump. >> >>The problem seems to be that radiusd sets up mutexes (pthread_mutex_init) >>while reading the config file. It reads the config file before fork()ing >>in order to daemonize. In fact, running it with -f and then manually >>backgrounding it makes the problem disappear. >>Also, moving the config-file reading code below the fork() also helps. >> >>Before reporting a bug to the FreeRADIUS people: It looks weird to me to >>create a mutex, then fork and use the mutex in the child process. However, >>I'm unsure whether this is really illegal (I can't find anything saying so >>besides the sheer existance of pthread_atfork(), which radiusd doesn't call) >>or a problem with NetBSD's implementation. >> >>Any pthread experts to help me? > > It is implementation dependend; for portability pthread_mutex_init() should > be done in the child process and not cross a fork. Eg: > > http://www.sbin.org/doc/glibc/libc_34.html > http://stackoverflow.com/questions/2620313/how-to-use-pthread-atfork-and-pthread-once-to-reinitialize-mutexes-in-child > > Please file a PR to add a note in our man pages. Also, in the general case, when a threaded program forks, essentially nothing can be done in the child - only "async signal safe" calls can be made (without invoking undefined behavior). In practice, I would be surprised if a program with only one thread had any trouble. The basic issue that can't be gotten around is that when fork happens, if some other thread holds a mutex, that thread, being missing in the child, cannot release it, and you have a mess. In FreeBSD, and I think now in NetBSD -current, there is a pthread_atfork handler called by libc to make sure the internal malloc locks don't end up in a bad state. THis is necessary becuase there are so many buggy programs out there. In the radius case, is the parent process running mulitple threads before forking? If so, it really should not do that. If not, I am surprised there is trouble.
Attachment:
pgpJogSTe4mXv.pgp
Description: PGP signature