Re: sigaction, fork, malloc, and futex

From: Zan Lynx
Date: Tue May 04 2004 - 17:58:25 EST


On Tue, 2004-05-04 at 16:30, chris@xxxxxxxxxxxxxxxx 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@xxxxxxx>

Attachment: signature.asc
Description: This is a digitally signed message part