问题
I have the following really dumb C program:
#include <SDL2/SDL.h>
int main () {
SDL_Init(SDL_INIT_VIDEO);
}
If I compile it and link against sdl2
, all is well:
[nix-shell:~/work/on-the-limit]$ gcc oddity.c -lSDL2 -o oddity
[nix-shell:~/work/on-the-limit]$ ./oddity
However, if I also link against udev
...
[nix-shell:~/work/on-the-limit]$ gcc oddity.c -lSDL2 -ludev -o oddity
[nix-shell:~/work/on-the-limit]$ ./oddity
Segmentation fault
... a segmentation fault happens.
gdb
has the following to say:
[nix-shell:~/work/on-the-limit]$ gdb ./oddity
GNU gdb (GDB) 7.10
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./oddity...done.
(gdb) run
Starting program: /home/ollie/work/on-the-limit/oddity
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/nix/store/npfsi1d9ka8zwnxzn3sr08hbwvpapyk7-glibc-2.21/lib/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff736b36a in strlen () from /nix/store/483br9kb3f5igsgmb6aqsjhl2ipj2bxr-glibc-2.21/lib/libc.so.6
(gdb) bt
#0 0x00007ffff736b36a in strlen () from /nix/store/483br9kb3f5igsgmb6aqsjhl2ipj2bxr-glibc-2.21/lib/libc.so.6
#1 0x00007ffff7fbb54b in strpcpy () from /nix/store/m3k7v0cy7zh6qbjqhrxgd36p105qqf0q-systemd-217/lib/libudev.so.1
#2 0x00007ffff7fbb6b3 in strscpy () from /nix/store/m3k7v0cy7zh6qbjqhrxgd36p105qqf0q-systemd-217/lib/libudev.so.1
#3 0x00007ffff7fb8f3d in device_new_from_parent.isra.7.lto_priv () from /nix/store/m3k7v0cy7zh6qbjqhrxgd36p105qqf0q-systemd-217/lib/libudev.so.1
#4 0x00007ffff7fb6140 in udev_device_get_parent () from /nix/store/m3k7v0cy7zh6qbjqhrxgd36p105qqf0q-systemd-217/lib/libudev.so.1
#5 0x00007ffff4c9b85a in loader_get_pci_id_for_fd () from /run/opengl-driver/lib/libGL.so.1
#6 0x00007ffff4c9be68 in loader_get_driver_for_fd () from /run/opengl-driver/lib/libGL.so.1
#7 0x00007ffff4c95126 in dri2CreateScreen () from /run/opengl-driver/lib/libGL.so.1
#8 0x00007ffff4c748d4 in __glXInitialize () from /run/opengl-driver/lib/libGL.so.1
#9 0x00007ffff4c70c1b in GetGLXPrivScreenConfig.part.2 () from /run/opengl-driver/lib/libGL.so.1
#10 0x00007ffff4c70d4d in glXChooseVisual () from /run/opengl-driver/lib/libGL.so.1
#11 0x00007ffff7b92288 in X11_GL_LoadLibrary () from /nix/store/qcf0jg20x3fnb09p4xc1y5dsbz84m7h9-SDL2-2.0.3/lib/libSDL2-2.0.so.0
#12 0x00007ffff7b89567 in SDL_CreateWindow_REAL () from /nix/store/qcf0jg20x3fnb09p4xc1y5dsbz84m7h9-SDL2-2.0.3/lib/libSDL2-2.0.so.0
#13 0x00007ffff7b89180 in SDL_VideoInit_REAL () from /nix/store/qcf0jg20x3fnb09p4xc1y5dsbz84m7h9-SDL2-2.0.3/lib/libSDL2-2.0.so.0
#14 0x00007ffff7ac8317 in SDL_Init_REAL () from /nix/store/qcf0jg20x3fnb09p4xc1y5dsbz84m7h9-SDL2-2.0.3/lib/libSDL2-2.0.so.0
#15 0x00000000004008b6 in main () at oddity.c:4
回答1:
If a program's behavior differs depending only on how it is linked, then that must result from different function implementations being [dynamically] linked in one case and the other. Beyond that, to answer in any detail would require examining details of all the libraries involved.
Nevertheless, at this point I am inclined to observe that you apparently are relying heavily on RPATHs, which is highly questionable. It is especially questionable that you appear to be resolving the C standard library via RPATH (as is evident from the first line of your back trace) instead of using the system's version.
It would be best to influence dynamic linking by configuring the dynamic linker, instead of by embedding RPATHs in your program or libraries. If the objective is to use different libraries than the system's defaults, then you might find it useful to establish an alternative chroot environment in which your program could run. Under all circumstances, be certain that the compiler, static linker, dynamic linker, all libraries on which your program relies, and the program itself all agree about which version of each library is to be used.
来源:https://stackoverflow.com/questions/34534136/why-does-linking-against-both-sdl2-and-udev-cause-a-segmentation-fault