tech-userlevel archive

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

Re: child of a multithreaded process looping in malloc()



> Date: Thu, 2 Nov 2023 18:26:43 +0100
> From: Edgar Fuß <ef%math.uni-bonn.de@localhost>
> 
> I've a long-standing problem of a process eating cpu time without doing 
> anything useful, which, most probably, goes like this:
> 
> Of a multi-threaded process,
> one thread is in malloc() while another thread fork()s.
> (So the child is born with the malloc lock held.)
> The child process (becoming single-threaded by the fork) calls malloc().
> The child loops forever because there's no other thread to release the lock.
> 
> Strictly speaking, malloc(3) is not declared to be async-signal-safe, so a 
> threaded program shouldn't call malloc() in a child before fork()ing.
> In my case, the code doing the fork/malloc is the Perl interpreter embedded 
> into collectd, so there's little I can do about it.
> 
> Couldn't malloc simply install a pthread_atfork() handler that releases 
> the lock in the child?

It effectively does -- the calls to _malloc_prefork/postfork(_child)
are baked into fork in NetBSD's libc:

https://nxr.netbsd.org/xref/src/lib/libc/gen/pthread_atfork.c?r=1.17#174
https://nxr.netbsd.org/xref/src/lib/libc/gen/pthread_atfork.c?r=1.17#183
https://nxr.netbsd.org/xref/src/lib/libc/gen/pthread_atfork.c?r=1.17#189

So you'll need to gather some more details about what's going wrong
here.

Perhaps this is a bug in the built-in _malloc_postfork, although that
seems unlikely.

Perhaps you've substituted your own private malloc, in which case in
order to make this work you'll have to either put your own locking
around your calls to it and fork to serialize them, or implement your
own _malloc_prefork/postfork(_child) instead.


Home | Main Index | Thread Index | Old Index