tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: radiusd: Error detected by libpthread: Invalid mutex.



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



Home | Main Index | Thread Index | Old Index