标签:死锁 lib64 状态 c函数 use rb_tree 做了 节点 const
某天突然发现进程不再运行处理且有没有崩溃产生core文件;
使用gdb -p pid查看堆栈信息如下:
1 #0 0x000000376faf83ae in __lll_lock_wait_private () from /lib64/libc.so.6 2 #1 0x000000376fa7d35b in _L_lock_10288 () from /lib64/libc.so.6 3 #2 0x000000376fa7ab83 in malloc () from /lib64/libc.so.6 4 #3 0x000000376fa80f42 in strdup () from /lib64/libc.so.6 5 #4 0x000000376fa9d9c1 in tzset_internal () from /lib64/libc.so.6 6 #5 0x000000376fa9db39 in __tz_convert () from /lib64/libc.so.6 7 #6 0x000000376fa9bc59 in ctime () from /lib64/libc.so.6 8 #7 0x0000000000405017 in AdAnalizeBayu::sigHandle (sig=14) at AdAnalizeBayu.cpp:56 9 #8 <signal handler called> 10 #9 0x000000376fa79ade in _int_malloc () from /lib64/libc.so.6 11 #10 0x000000376fa7a7ed in calloc () from /lib64/libc.so.6 12 #11 0x000000000042aaeb in operator new (size=48) at memcheck.cpp:302 13 #12 0x000000000041c3cf in __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<std::string const, std::string> > >::allocate ( 14 this=0x7ffca027e950, __n=1) at /usr/include/c++/4.8.2/ext/new_allocator.h:104 15 #13 0x000000000041c2b8 in std::_Rb_tree<std::string, std::pair<std::string const, std::string>, std::_Select1st<std::pair<std::string const, std::string> >, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > >::_M_get_node (this=0x7ffca027e950) 16 at /usr/include/c++/4.8.2/bits/stl_tree.h:370 17 #14 0x000000000041c1bf in std::_Rb_tree<std::string, std::pair<std::string const, std::string>, std::_Select1st<std::pair<std::string const, std::string> >, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > >::_M_create_node (this=0x7ffca027e950, 18 __x=...) at /usr/include/c++/4.8.2/bits/stl_tree.h:380 19 #15 0x000000000041beb4 in std::_Rb_tree<std::string, std::pair<std::string const, std::string>, std::_Select1st<std::pair<std::string const, std::string> >, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > >::_M_insert_ (this=0x7ffca027e950, 20 __x=0x0, __p=0x27bfa00, __v=...) at /usr/include/c++/4.8.2/bits/stl_tree.h:1023 21 #16 0x000000000041b8b0 in std::_Rb_tree<std::string, std::pair<std::string const, std::string>, std::_Select1st<std::pair<std::string const, std::string> >, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > >::_M_insert_unique_ ( 22 this=0x7ffca027e950, __position=..., __v=...) at /usr/include/c++/4.8.2/bits/stl_tree.h:1482 23 #17 0x000000000041b6a2 in std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > >::insert (this=0x7ffca027e950, __position=..., __x=...) at /usr/include/c++/4.8.2/bits/stl_map.h:648 24 #18 0x000000000041b48f in std::map<std::string, std::string, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > >::operator[] (this=0x7ffca027e950, __k=...) at /usr/include/c++/4.8.2/bits/stl_map.h:469 25 #19 0x0000000000441ada in kfc::CCgiPara::Decode () at kfc_parsepara.cpp:147 26 #20 0x000000000042248b in CUdpServer::OnDoProcess () at udp_server.cpp:76 27 #21 0x00000000004240d5 in CUServer::ReadFromSvrPort (this=0x6622a0 <CUdpServer::getInstance()::srv>) at userver.cpp:97 28 #22 0x000000000042427f in CUServer::Run (this=0x6622a0 <CUdpServer::getInstance()::srv>) at userver.cpp:121 29 #23 0x000000000041aaf6 in main (argc=2, argv=0x7ffca027ff78) at main.cpp:62
由堆栈编号11可以看到程序在往std容器map内插入一个红黑树节点调用了系统调用_int_malloc()函数申请一片空间的时候,定时器信号过来,进程进入了信号处理函数(堆栈编号8)。
此时这片内存空间是有被加上锁的;
在信号处理函数内调用了库函数ctime(),这个函数后来查阅资料得知是不可重入函数(即会导致结果不可预知)。在该函数内调用了malloc函数会对同一批空间加锁,由于这篇内存空间已被之前加过锁导致进程在此处阻塞。进程在信号处理函数内阻塞等待std容器添加完后释放锁,std容器添加过程又在等待信号处理函数处理完毕后释放锁。导致进程进入死锁状态。
解决办法:
ctime函数在我的信号处理函数内不是必须存在的,因此做了删减另外实现。死锁情况解决。
在信号处理函数内一定不要使用不可重入函数。虽然posix标准规定标准库函数必须都是可重入函数,但仍有少数是不可重入函数:
标签:死锁 lib64 状态 c函数 use rb_tree 做了 节点 const
原文地址:https://www.cnblogs.com/jialin0x7c9/p/12027622.html