加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

linux – LD_PRELOAD导致动态库加载器中的分段错误

发布时间:2020-12-14 01:40:31 所属栏目:Linux 来源:网络整理
导读:我写了一个库,打算通过LD_PRELOAD加载.在某些 Linux系统上,这会导致动态库加载器在初始化期间出现段错误. 我有一个简单的测试用例,表现出这种行为,但只有当我链接-lm时.例如: # Works finegcc -o vecadd.normal -std=c99 vecadd.c -lOpenCLLD_PRELOAD=/path
我写了一个库,打算通过LD_PRELOAD加载.在某些 Linux系统上,这会导致动态库加载器在初始化期间出现段错误.

我有一个简单的测试用例,表现出这种行为,但只有当我链接-lm时.例如:

# Works fine
gcc -o vecadd.normal -std=c99 vecadd.c -lOpenCL
LD_PRELOAD=/path/to/my/library.so ./vecadd.normal

# Causes segmentation fault
gcc -o vecadd.broken -std=c99 vecadd.c -lOpenCL -lm
LD_PRELOAD=/path/to/my/library.so ./vecadd.broken

关于这一点的奇怪之处在于libm.so似乎包含在两个版本中:ldd显示完全相同的库集,只是以不同的顺序:

vecadd.normal:
  linux-vdso.so.1 =>  (0x00007fffed9ff000)
  libOpenCL.so => /usr/lib64/libOpenCL.so (0x00007f135c9b1000)
  libc.so.6 => /lib64/libc.so.6 (0x00007f135c61c000)
  libdl.so.2 => /lib64/libdl.so.2 (0x00007f135c418000)
  libnuma.so.1 => /usr/lib64/libnuma.so.1 (0x00007f135c20f000)
  libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f135bf08000)
  libm.so.6 => /lib64/libm.so.6 (0x00007f135bc84000)
  libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f135ba6e000)
  /lib64/ld-linux-x86-64.so.2 (0x00007f135cbd4000)
vecadd.broken:
  linux-vdso.so.1 =>  (0x00007fff25c74000)
  libOpenCL.so => /usr/lib64/libOpenCL.so (0x00007fb8c071e000)
  libm.so.6 => /lib64/libm.so.6 (0x00007fb8c0499000)
  libc.so.6 => /lib64/libc.so.6 (0x00007fb8c0105000)
  libdl.so.2 => /lib64/libdl.so.2 (0x00007fb8bff01000)
  libnuma.so.1 => /usr/lib64/libnuma.so.1 (0x00007fb8bfcf7000)
  libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007fb8bf9f1000)
  libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fb8bf7db000)
  /lib64/ld-linux-x86-64.so.2 (0x00007fb8c0941000)

Google指示我使用LD_DEBUG,它也指向libm.so作为问题的一部分:

14143: symbol=fma;  lookup in file=./vecadd.broken [0]
 14143: symbol=fma;  lookup in file=/path/to/my/library.so [0]
 14143: symbol=fma;  lookup in file=/usr/lib64/libOpenCL.so [0]
 14143: symbol=fma;  lookup in file=/lib64/libm.so.6 [0]
 14143: binding file /path/to/my/library.so [0] to /lib64/libm.so.6 [0]: normal symbol `fma' [GLIBC_2.2.5]
Segmentation fault (core dumped)

不幸的是,我可以重现此问题的唯一机器似乎没有可用的动态库加载器的调试符号(并且我没有任何管理权限),因此GDB不会产生任何有用的东西:

gdb ./vecadd.broken
(gdb) set environment LD_PRELOAD /path/to/my/library.so
(gdb) run
Starting program: vecadd.broken 

Program received signal SIGSEGV,Segmentation fault.
0x0000000000003dce in ?? ()
Missing separate debuginfos,use: debuginfo-install glibc-2.12-1.132.el6_5.1.x86_64
(gdb) bt
#0  0x0000000000003dce in ?? ()
#1  0x00007fff7f755369 in ?? ()
#2  0x00007fffffffd840 in ?? ()
#3  0x00007fff7fde9e91 in _dl_relocate_object ()
   from /lib64/ld-linux-x86-64.so.2
#4  0x00007fff7fde18a3 in dl_main () from /lib64/ld-linux-x86-64.so.2
#5  0x00007fff7fdf3a0e in _dl_sysdep_start () from /lib64/ld-linux-x86-64.so.2
#6  0x00007fff7fddf4a4 in _dl_start () from /lib64/ld-linux-x86-64.so.2
#7  0x00007fff7fddeb08 in _start () from /lib64/ld-linux-x86-64.so.2
#8  0x0000000000000001 in ?? ()
#9  0x00007fffffffde01 in ?? ()
#10 0x0000000000000000 in ?? ()

找到问题根源的最佳方法是什么?

解决方法

您可以上传自己使用符号构建的动态加载程序并调用它来链接您的应用程序,例如:

∞/lib/ld-linux-x86-64.so.2 / bin / echo链接关联

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读