Messages in this thread | | | Subject | Re: sigaction, fork, malloc, and futex | From | Zan Lynx <> | Date | Tue, 04 May 2004 16:56:36 -0600 |
| |
On Tue, 2004-05-04 at 16:30, chris@scary.beasts.org wrote: > Hi- > > On Tue, 4 May 2004, Steve Beaty wrote: > > > > > anyone have a clue on this one? we set up a signal handler, create > > a child that sends that signal, and have the signal handler fork > > another child. if there is a malloc(), the second child gets stuck > > in a futex(); without the malloc(), no problem. 2.4.20-30.9 > > kernel. straces at the end. any help would be appreciated. > > thanks! > > Your signal handler function is illegally calling non-reentrant functions. > The *printf() family of functions are going to need to call malloc() to > allocate buffers. malloc() cannot be re-entered. > > So specifically your deadlock sequence is: > > Parent: > fork() > fprintf() > -> malloc() > -> take a malloc() lock > (Child schedules and sends SIGALRM at this point) > SIGALRM: > fprintf() > -> malloc() > -> try to take a malloc() lock > -> deadlock, lock is already taken and will never be released! > > Modern glibc / kernel combinations which use futexes in the malloc code > really seem to expose this race. > > Cheers > Chris
No, it's nothing to do with the fprintf. I tried the program without any fprints at all and got the same result.
I'm pretty sure the problem is in glibc. Look at malloc_atfork and free_atfork in glibc's malloc/arena.c. I think the reason you are only seeing it happen when you malloc is that glibc only initializes the malloc system when you first use it.
I am not sure it is really a problem though. I don't think you should be allowed to fork inside a signal handler. That seems very wrong. -- Zan Lynx <zlynx@acm.org> [unhandled content-type:application/pgp-signature] | |