为什么连接sdl2和udev都会导致分段错误?

我有以下真正愚蠢的C程序:

#include <SDL2/SDL.h> int main () { SDL_Init(SDL_INIT_VIDEO); } 

如果我编译并链接到sdl2 ,一切都很好:

 [nix-shell:~/work/on-the-limit]$ gcc oddity.c -lSDL2 -o oddity [nix-shell:~/work/on-the-limit]$ ./oddity 

但是,如果我也链接到udev

 [nix-shell:~/work/on-the-limit]$ gcc oddity.c -lSDL2 -ludev -o oddity [nix-shell:~/work/on-the-limit]$ ./oddity Segmentation fault 

发生分段错误

gdb有以下的说法:

 [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 

如果一个程序的行为仅仅依赖于链接的方式而有所不同,那么这个行为必然是由不同的函数实现在某种情况下[动态]链接的。 除此之外,要详细回答需要检查所有涉及的图书馆的细节。

尽管如此,在这一点上,我倾向于指出,你显然是在严重依赖RPATHs,这是非常可疑的。 尤其值得怀疑的是,您似乎是通过RPATH解析了C标准库(从后面的第一行中可以明显看出),而不是使用系统的版本。

最好是通过配置动态链接器来影响动态链接,而不是将RPATH嵌入到程序或库中。 如果目标是使用不同于系统默认值的库,那么你可能会发现建立一个可以运行程序的替代chroot环境是很有用的。 在任何情况下,要确保编译器,静态链接器,动态链接器,程序所依赖的所有库以及程序本身都同意使用每个库的哪个版本。