利用core dump进行C++项目socket编程的异常定位(errno为110, Connection timed out)

最近在一个碰到一个socket相关的异常。

  • 环境:linux
  • 项目:C++,涉及大量网络IO
  • 观察对象:一个常驻进程,既是客户端,也是服务端
  • 现象:特定操作后,隔132分钟后,进程便会自动退出。能通过exception异常类捕获到errno为110, 对应的message为"Connection timed out"。

分析过程:

假设1:从该Connection time out这消息提示,结合该项目涉及大量的socket通信,很自然地联想到是该进程在调用connect(),与服务端建立连接的时候出了问题?

推翻假设1:connect()是linux的C实现的库函数,不会抛异常(异常是C++中的机制)。

假设2:回到一开始,正是因为代码里有异常捕获,才得知errno,确实抛了异常。那么就有可能是人为地根据errno,主动throw出来的。

搜索得知,项目中有大量的throw system_error(errno, system_category()),符合假设2。

在这种有大量可疑点的情况下,主动从代码的角度去一个个刻意点排查是很费劲的。既然定时能够复现,且有抛异常的机制。那来一个守株待兔,不捕捉异常处理,让程序直接core dump,便可根据core文件的堆栈信息,定位到原因。

最后有效地找到问题所在:程序作为服务端,其客户端在运行过程中退出了,服务端的连接没有进行关闭,代码层面没有close与客户端的连接socket,且该连接的socket设置了SO_KEEPALIVE属性。这就出现了,默认7200s,服务端就会往一个半打开的连接发送一个心跳报文,对方是不会回复该报文的,引发连接超时的错误。

解决方案:服务端在检测到客户端发起关闭连接后,及时进行关闭连接。
常规来说,客户端close --> 服务端接收完接收缓冲区的数据,close --> 连接关闭。

你可能感兴趣的:(cc++socket编程)