Fedora 28/GLIBC 2.27 libm.so.6 logf() 和 powf() c++ [英] Fedora 28 / GLIBC 2.27 libm.so.6 logf() and powf() c++

查看:41
本文介绍了Fedora 28/GLIBC 2.27 libm.so.6 logf() 和 powf() c++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我相信其他 Fedora 28 用户会知道,操作系统的 glibc 最近更新为 glibc 2.27.除了许多其他功能之外,2.27 还添加了 logf() 和 powf() 的新实现.这导致我的应用程序无法在具有较旧 glibc(例如 Debian)的发行版上运行.在 Debian 上调用应用程序时,会产生以下错误:

As I am sure other Fedora 28 users will know, the OS's glibc was recently updated to glibc 2.27. Amongst many other things, 2.27 has added new implementations of logf() and powf(). This has caused my application to fail to run on distributions with an older glibc (Debian, for example). When the application is invoked on Debian, the following error is produced:

  • ... libm.so.6 版本 GLIBC-2.27 未找到(./app_name 要求)
  • ... libm.so.6 version GLIBC-2.27 not found (required by ./app_name)

我使用以下过程将符号跟踪到 logf 和 powf:

I tracked the symbols down to logf and powf by using the following procedure:

objdump -T ./app_name | grep GLIBC_2.27

它给出了以下输出:

0000000000000000      DF *UND*  0000000000000000  GLIBC_2.27  powf
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.27  logf

然后……

objdump -T /lib/libm.so.6 | grep -w logf
objdump -T /lib/libm.so.6 | grep -w powf

它给出了以下输出:

000397a0 g    DF .text  00000135  GLIBC_2.27  logf
00010430 g    DF .text  0000009e (GLIBC_2.0)  logf

还有……

000397a0 g    DF .text  00000135  GLIBC_2.27  powf
00010430 g    DF .text  0000009e (GLIBC_2.0)  powf

因此,有了 powf() 和 logf() 也在 GLIBC-2.0 中实现的信息,我将以下内容添加到我的项目中(在 main() 之上)并重新编译.

So, armed with the information that powf() and logf() are also implemented in GLIBC-2.0, I added the following to my project (above main()) and recompiled.

__asm__(".symver logf,logf@GLIBC_2.0");
__asm__(".symver powf,powf@GLIBC_2.0"); 

不幸的是,我的项目仍在使用 GLIBC-2.27 中的 powf 和 logf.实际上,我为 Debian 分发二进制文件非常重要,如果可以避免的话,我宁愿不必在该发行版上编译.

Unfortunately, my project is still using powf and logf from GLIBC-2.27. It's actually quite important that I distributed binaries for Debian and I would prefer not to have to compile on that distribution if I can avoid it.

从历史上看,我已经成功地将这个过程用于 libc.so.6 中的符号,但不适用于 libm.so.6.我应该为 libm.so.6 做不同的事情吗?

Historically, I have successfully used this procedure for symbols in libc.so.6 but not libm.so.6. Should I be doing things differently for libm.so.6?

很明显,我在这里遗漏了一些东西,因此我将感谢您提供的任何帮助.

Clearly, I am missing something here so I would be grateful for any help offered.

非常感谢

阿曼达

推荐答案

我认为问题在于您使用 objdump 来查找 32 位 libm 的符号版本,我假设您是重新构建一个 64 位应用程序.在 Fedora 28 容器中,如果我查看 64 位库,则会看到这些版本:

I think the problem is that you used objdump to find the symbol versions of the 32-bit libm, and I assume you're actually building a 64-bit application. In a Fedora 28 container if I look at the 64-bit library then I see these versions instead:

objdump -T /lib64/libm.so.6 | egrep -w 'logf|powf'
0000000000011ea0 g    DF .text  0000000000000138 (GLIBC_2.2.5) powf
000000000004cad0 g   iD  .text  000000000000002a  GLIBC_2.27  powf
000000000004c610 g   iD  .text  000000000000002a  GLIBC_2.27  logf
0000000000011e40 g    DF .text  0000000000000051 (GLIBC_2.2.5) logf

这按预期工作:

#include <math.h>

__asm__(".symver logf,logf@GLIBC_2.2.5");
__asm__(".symver powf,powf@GLIBC_2.2.5");

int main(int argc, char**)
{
  return powf(argc, 2.0f) * logf(argc);
}

它使用 64 位库中的版本:

It uses the versions from the 64-bit library:

$ g++ m.cc 
$ nm  --undefined-only a.out
                 w __gmon_start__
                 U __libc_start_main@@GLIBC_2.2.5
                 U logf@GLIBC_2.2.5
                 U powf@GLIBC_2.2.5

所以我认为问题在于您试图链接到根本不在 64 位库中的符号(因为 glibc 在 2.2.5 版之前没有这些符号的 64 位版本,所以它们GLIBC_2.0 版本不存在).

So I think the problem was that you were trying to link to symbols that simply aren't in the 64-bit library (because glibc didn't have 64-bit versions of those symbols until version 2.2.5, so they don't exist with the GLIBC_2.0 version).

要使其适用于 32 位或 64 位,您可以这样做:

To make it work for 32-bit or 64-bit you could do:

#include <math.h>

#if __LP64__
# define SYMVER "GLIBC_2.2.5"
#else
# define SYMVER "GLIBC_2.0"
#endif
#define USE_OLD_SYM(F,V) __asm__(".symver " #F "," #F "@" V)
USE_OLD_SYM(logf,SYMVER);
USE_OLD_SYM(powf,SYMVER);

int main(int argc, char**)
{
  return powf(argc, 2.0f) * logf(argc);
}

这使用了正确的字号版本:

That uses the right version for the wordsize:

$ g++ m.cc  
$ nm  --undefined-only a.out
                 w __gmon_start__
                 U __libc_start_main@@GLIBC_2.2.5
                 U logf@GLIBC_2.2.5
                 U powf@GLIBC_2.2.5
$ g++ m.cc  -m32
$ nm  --undefined-only a.out
         w __gmon_start__
         U __libc_start_main@@GLIBC_2.0
         U logf@GLIBC_2.0
         U powf@GLIBC_2.0

这篇关于Fedora 28/GLIBC 2.27 libm.so.6 logf() 和 powf() c++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆