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

查看:77
本文介绍了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

因此,有了在GLIBC-2.0中也实现了powf()和logf()的信息,我将以下内容添加到了我的项目中(在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天全站免登陆