Я написал библиотеку, предназначенную для загрузки через LD_PRELOAD
. В некоторых системах Linux это приводит к тому, что загрузчик динамической библиотеки выполняет segfault во время инициализации.LD_PRELOAD вызывает ошибку сегментации в загрузчике динамической библиотеки
У меня есть простой тестовый пример, который проявляет это поведение, но только если я связываюсь с -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 ??()
Каков наилучший способ найти основную причину этой проблемы?
ли предварительно загруженную библиотеку скомпилированный в каждой системе или вы просто скопировать .so? –
@thatotherguy Предварительно загруженная библиотека была скомпилирована в каждой системе, которая ее запускает. – jprice