malloc_atfork内部死锁

malloc_atfork内部死锁,c,multithreading,malloc,fork,C,Multithreading,Malloc,Fork,我的程序处于死锁状态,以下是死锁的前4帧: #0 __lll_lock_wait_private () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:97 #1 0x00007f926250b7aa in _L_lock_12502 () at malloc.c:3507 #2 0x00007f926250a2df in malloc_atfork (sz=12, caller=<value optimized ou

我的程序处于死锁状态,以下是死锁的前4帧:

#0  __lll_lock_wait_private () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:97
#1  0x00007f926250b7aa in _L_lock_12502 () at malloc.c:3507
#2  0x00007f926250a2df in malloc_atfork (sz=12, caller=<value optimized out>) at arena.c:217
#3  0x00007f926250881a in __libc_calloc (n=<value optimized out>, elem_size=<value optimized out>) at malloc.c:4040
\0\ull\u lock\u wait\u private(),位于../nptl/sysdeps/unix/sysv/linux/x86\u 64/lowlevellock.S:97
#1 0x00007f926250b7aa位于malloc.c:3507的L_锁_12502()中
#2 0x00007f926250a2df位于竞技场的malloc_atfork(sz=12,调用方=)中。c:217
#3 0x00007f926250881a位于malloc的uuu libc_calloc(n=,elem_size=)中。c:4040

我倾向于认为这是一个由我做错的事情引起的问题。我们在给服务器施加压力并使其达到高使用级别时会看到死锁,但在其他方面,我们无法重现这种情况。有人知道是什么样的错误导致了这种情况吗?

如果不同的执行线程以不同的顺序获取共享资源,则最常出现死锁。在压力下出现是一个很好的指标。您所获得的支持:

A == 1 2
B == 2 1
现在,假设您在获取
1
之后,但在获取
2
之前,得到了一个线程重新调度。线程B运行并获取
2
,然后控制返回到A;它现在被阻止等待资源2,该资源由B持有,B正在等待A持有的资源1。现在,A不能继续,B也不能继续;僵局

死锁的另一个原因是在这一点上有一个微小的变化,其中一个执行路径声明一个资源而不遵守资源锁定;这将误导遵循规则的其他执行线程


希望这有帮助。

在多线程进程中调用
fork
后,按照POSIX,子进程处于异步信号上下文中,如果在调用
\u exit
exec
系列函数之一之前调用异步信号安全函数以外的任何操作,则会调用未定义的行为。

malloc是否可能需要非常大的数字?(例如3gb+)@dheer:你能显示死锁时所有线程的调用堆栈吗?从这个调用堆栈看,这个线程似乎在等待其他线程获得的某个锁。如果子进程没有立即覆盖程序映像,通常不可能在多线程程序中使用
fork()
。典型的世界末日场景涉及一个多线程内存分配器,该分配器将在分叉进程中立即中断。在您的
分叉
/
克隆
调用站点周围发布其他线程和代码的堆栈跟踪会很有帮助。@KerrekSB:这可能是一个答案。我的程序现在没有调用分叉,它叫calloc。当程序发送电子邮件时,它有一个fork,但子进程只执行dup、关闭文件描述符、调用execv,然后在execv返回时退出。我刚刚复制了相同的问题,这次malloc_atfork()调用在程序对new的调用中。在这两种情况下,或者在任何其他情况下,我实际上都没有调用fork()。您是否有一个最小的测试用例程序来重现这个问题?如果是这样的话,我可以尝试一下,如果真的有bug,我可以向glibc报告bug。另外,您是否有任何信号处理程序,您是否可能从信号处理程序调用
malloc
(可能是间接的)?