1

我正在处理一个非常特殊的问题。我有一个旧编译器(gcc 2.95 或更早版本)在 solaris 8/sparc 平台上编译的代码。它在 solaris 8/sparc 上运行良好,但在 solaris 10/sparc 上崩溃。(solaris 10 应该向后兼容 solaris 8)

在调试时,我发现当应用程序尝试将主机名转换为其相应的 i/p 地址时出现问题。它使用 gethostbyname_r,后跟 inet_ntoa 来获取 ipv4 四点分号。gdb'ing 通过解决方案让我看到 gethostbyname_r 返回的 in_addr 具有表示 i/p 地址的正确整数,但 inet_ntoa 调用返回格式错误的字符串。确认它确实是 inet_ntoa 失败的一个困难是代码编写如下

strcpy(hostaddr, inet_ntoa(*((struct in_addr *) hostdata.h_addr)));

所以从技术上讲,我看不到 inet_ntoa 返回的值。但我可以做一个

print (char*)inet_ntoa(*((struct in_addr *) hostdata.h_addr_list[0]))

在 gdb 上查看(我认为这足够接近)并打印格式错误的 i/p 地址。例如,“0.0.”。(主机名具有有效的 i/p 地址,并且可以从该机器解析,因此以 0.0 开头的 i/p 也不是正确的值)

您可以看到将 unsafe strcpy 与 inet_ntoa 一起使用会产生一些未知,并导致分段错误。

很高兴听到经历过类似事情的人的来信,了解导致 inet_ntoa 失败的原因可能是什么。不知何故,系统正在发挥作用,我什至无法确定它是否可以解决这个问题。

所有评论将不胜感激。

约束:我无法修改代码以使其工作(否则这很容易解决)。因此,尽管知道 strcpy 是一个非常不安全的函数 wrt 段错误,并且 inet_ntoa 已被弃用,但我在这方面无能为力。

编辑:我觉得这是一个并行处理问题。我不确定,但我认为该应用程序不是多线程的。但是新的sol10机器是64核的机器。思考链的原因是 inet_ntoa 的唯一真正问题是静态缓冲区,并且代码确实在循环中进行了此调用。

4

1 回答 1

0

我发现链接器(当然还有错误的代码)是问题所在。一些超级好人,尽管拥有一个与标准库函数(inet_ntoa_r)同名的函数是个好主意。当我在将代码与库链接时尝试使用 -static 选项时,它开始抱怨用户库文件中存在此符号。一旦我从用户库中删除了该功能,它就会从崩溃中继续(到我正在尝试修复的其他一些问题。期待另一个问题:))。希望有人觉得这很有用

于 2012-09-18T21:10:05.960 回答