【发布时间】:2019-03-07 20:56:12
【问题描述】:
我的公司销售带有许多可执行文件的基于 linux 的设备。其中一个应用程序每隔几天就会挂在我们产品的最新版本中。
我们正在使用 glibc 2.19 和 gcc 4.8.3 以及 Linux 内核版本 3.16.38。我们正在为 x86_64 构建。
我们的 glibc 版本非常旧,据说我们在一年前对它进行了修补,修复了以下问题: 错误 #12926:getaddrinfo()/make_request() 永远旋转 (https://sourceware.org/bugzilla/show_bug.cgi?id=12926)
我们的 crosstool 的维护者发誓我们使用的那个有一个补丁 glibc。然而,还有其他失败的可能性,比如我们的构建可能出于某种原因选择了不同的 glibc。
在我们的构建机器上,我们保存了应用程序可执行文件和共享对象二进制文件的未剥离版本,以便以后在调试核心文件时使用。
我通过登录到一个应用程序挂起的设备并向进程发送 SIGILL 生成了一些核心文件。
核心文件似乎表明我们在 getaddrinfo() 中遇到了挂起,并且堆栈跟踪看起来像我们在修补 glibc 之前获得的那些。使用最新部署构建的最新核心文件示例:
Thread #18 1456 (Suspended : Container)
recvmsg() at 0x7f1fa276c17d
make_request() at 0x7f1fa278695d
__check_pf() at 0x7f1fa2786e54
getaddrinfo() at 0x7f1fa2759501
Thread #16 1454 (Suspended : Container)
__lll_lock_wait_private() at 0x7f1fa277777b
_L_lock_443() at 0x7f1fa2786f4d
__check_pf() at 0x7f1fa2786d05
getaddrinfo() at 0x7f1fa2759501
我希望能够验证我们已部署的发布可执行文件正在执行哪个版本的 getaddrinfo():已修补或未修补。在我的个人开发箱上这样做无济于事,因为那只会验证我自己的工具链/构建环境。有什么办法可以用我们部署的发布二进制文件来做到这一点?
编辑:我忘了提到我们是静态链接的。
编辑 2:我对静态链接的看法是错误的。我们过去几乎静态链接所有内容,但我们不再与系统库静态链接。感谢那些指出这一点的人。
【问题讨论】:
-
你是静态链接的吗?
-
如果你正确使用你的构建服务器,你有一组可执行文件,你可以通过它们的哈希值进行比较(剥离可执行文件将产生相同的结果,无论它是为交付而剥离还是在事实 - 并给出一个可比较的哈希值)。
-
如何反汇编函数并将其与已知良好函数的反汇编进行比较?
-
您可以在已编译和安装的二进制文件上运行
ldd,以查看它将实际获取哪些动态库。但是调试器也应该告诉你。 -
"忘了说我们是静态链接的。" -- 你几乎肯定错了。
标签: gcc gdb glibc freeze getaddrinfo