> Date: Thu, 2 Nov 2023 18:26:43 +0100 > From: Edgar Fuß <e...@math.uni-bonn.de> > > 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.