在yifei项目中,通过socketpair生成的两队socket垮进程传输普通数据,以及最重要的传输
fd句柄在做单元测试测试 yf_bridge 的时候,发现了一个非常奇怪的现象,百思不得其解,现象如下:
单元测试跑着跑着,句柄就用完了,导致接下来的单元测试失败;lsof 发现一堆这种句柄:
6u CHR 136,188 0t0 190 /dev/pts/188
7u CHR 136,188 0t0 190 /dev/pts/188
8u CHR 136,188 0t0 190 /dev/pts/188
且一直往上增长,最后把有限的句柄全部耗尽;
网上查了下这种句柄,是和终端相关联的一种虚拟设备节点;但我程序中根本就没有打开这里设备
啊,怎么会莫名其妙打开这么多句柄?
strace 跟踪程序,没发现任何有嫌疑的系统调用;
最后实在没办法了,只能采用最原始的方法查了,把单元测试中的代码慢慢一拆二,二拆四的二分
注释掉;最后定位到了 recvmsg 这个函数上,发现每次调用一下这个函数,程序就会莫名其妙多一个上面
这种句柄;
问题定位到了,就好解决了;仔细一想,recvmsg 是可以用来传输句柄的,跟踪了sendmsg调用处,
果然发现了一个bug;我的发送函数中判断是否是发送句柄的条件和接受函数中的判断条件不一样;导致:
其实sendmsg 把默认的0句柄发送了过来;虽然接收函数没有处理这个句柄,但这个句柄实际在系统底层已经
生成了...
bug找到了,迅速解决了;
总结下:
1, recvmsg 接收句柄,如果句柄耗尽,貌似什么错都没报,静默的表现令人费解...
2,recvmsg 如果用在同一进程的不同线程中,句柄实际上就是被复制了,有点类似 dup 的功能;
//正因为如此,我的bridge测试,多线程也会出现这种一模一样的现象;
查bug的最原始方法虽然是原始了点,但往往是最有效最直接的方法;
百度google,strace, lsof 等等用了个遍,耗费了好几个小时;最后狠下心来用原始方法一段
一段注释,一个小时不到,解决了;
阅读(2803) | 评论(0) | 转发(3) |