背景
我们有一个小型无头机器,运行 Linux 内核 2.6.35 和一些在 ARM 硬件上的 Open Embedded 发行版。
据我们所知,我们使用的是 glibc 2.10.1。
该盒子有一个未连接的以太网和一个串行连接的 GSM/3G 调制解调器。我们已配置 PPP 以确保继续连接到 Internet。这部分工作没有问题。
我们有一个用 c(实际上是 c++)编写的程序,它使用套接字建立一些连接。该程序是使用 pthreads 进行大量多线程处理的。
要查找要连接的 IP 地址,我们使用 gethostbyname()。
当没有连接到 Internet 时,例如在初始启动期间或 SIM 卡从调制解调器中取出时,gethostbyname() 会返回 NULL,因为它应该返回 NULL。
症状
但有时 gethostbyname() 会一直返回 NULL,即使 Internet 连接已启动并正在运行。
使用时来自 getaddrinfo() 的错误代码是 EAI_NONAME ~“名称或服务未知”。我们手头没有来自 gethostbyname() 的错误代码,但它是等价的。
我们的分析
我们已通过(通过串行控制台)确保互联网连接正常
- 项目清单
- 查看 /var/log/messages 并确保 pppd 表示一切正常
- ping 主机名(转换为 IP 并回复 ok)
- 通过公共 IP 通过 ssh 连接到盒子
我们在进程中有两个线程对同一主机使用 gethostbyname()。它们的代码路径和函数略有不同,但对套接字函数使用通用代码,包括调用 gethostbyname() 的部分。
在 gethostbyname() 不断返回 NULL 的情况下,这通常只适用于其中一个线程,而不是每次都相同。另一个使查找完美。
此外,gethostbyname() 失败的线程可以通过简单的受控停止该线程并重新启动该函数来轻松启动,然后重新启动一个新线程 pthread-wise。
总的来说,我们确信 DNS 翻译和互联网连接在操作系统级别运行良好。
为了排除线程问题,我们使用 getaddrinfo() 重新实现了查找代码,根据手册页,它是可重入的。并得到完全相同的结果。
对我们来说,线程的退出似乎会导致某种影响 gethostbyname()/getaddrinfo() 进行查找的能力的清理。
一种解决方法是强制退出失败的线程,但这意味着应用程序结构的重大变化,并不是真正的选择。
问题
所以问题是:您是否有任何指示可以在哪里寻找解决方案或真正的问题可能在哪里?