gpt4 book ai didi

c - 声明 -nostartfiles 时 pthread_atfork 无法编译

转载 作者:行者123 更新时间:2023-11-30 15:25:17 28 4
gpt4 key购买 nike

我有一个旧应用程序,它使用 pthread 库中的 pthread_atfork 函数来注册子 Hook 。我正在将应用程序移动到使用 glibc 2.14.90 的较新构建环境。 pthread_atfork 似乎早在 2002 年就已从 pthread 库中删除,我们创建的共享库之一将不再编译。

这是有问题的代码:

void
_init(void)
{
static int first = 1;
if ( first ) {
pthread_atfork(NULL,NULL,_init);
first = 0;
}
{
pthread_t tid;
pthread_create(&tid,0,startUp,0);
}
return;
}

pthread_atfork 调用将 _init 注册为子 Hook ,每次有 fork 时都会在子进程中运行。 Init 只是创建一个新线程来执行 startUp,这是一个初始化函数,用于设置文件、互斥体、读取初始化参数等内容...

由于 pthread_atfork 隐藏在 glibc 2.14 中,是否有另一种方法来注册相同类型的钩子(Hook)以便 init 在 fork 上运行?我更愿意使用标准库而不进行任何修改,以保持构建环境的可移植性。

glibc 2.14源代码在这里,有兴趣的人(pthread_atfork文件位于nptl目录下):

https://sourceware.org/git/?p=glibc.git;a=tree;h=d1e550124ee36b8b62af8984e4b829622a60f725;hb=356f8bc660a154a07b03da7c536831da5c8f74fe

我收到的编译错误:

gcc -g -nostartfiles -o mto.so -shared -I mto.c -lnsl -lresolv -lrt -lm -lpthread -ldl

/usr/bin/ld:/usr/lib/libpthread_nonshared.a(pthread_atfork.oS): 在创建共享对象时,不能使用未定义的隐藏符号“__dso_handle”重定位 R_386_GOTOFF

$ gcc -v

使用内置规范。COLLECT_GCC=gccCOLLECT_LTO_WRAPPER=/usr/libexec/gcc/i686-redhat-linux/4.6.3/lto-wrapper目标:i686-redhat-linux配置为:../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl= http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique -object --enable-linker-build-id --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode - -with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch=i686 --build=i686-redhat-linux线程模型:posixgcc版本4.6.3 20120306(红帽4.6.3-2)(GCC)

$ ldd --version

ldd(GNU libc)2.14.90版权所有 (C) 2011 自由软件基金会, Inc.这是免费软件;请参阅复制条件的来源。没有保修单;甚至不是为了适销性或特定用途的适用性。由罗兰·麦克格拉斯和乌尔里希·德雷珀撰写。

$ nm /usr/lib/libpthread.a|grep -C 1 atfork
00008150 W __pread64
000060b0 T __pthread_atfork
00002ab0 T __pthread_attr_destroy
--
00007ba0 W __recvmsg
U __register_atfork
00008c10 T __res_state
--
00008150 W pread64
000060b0 T pthread_atfork
00002ab0 T pthread_attr_destroy

.

$ nm /usr/lib/libpthread_nonshared.a

pthread_atfork.oS:
U _GLOBAL_OFFSET_TABLE_
w __dso_handle
00000000 T __i686.get_pc_thunk.bx
00000000 T __pthread_atfork
U __register_atfork
00000000 T pthread_atfork

感谢您的宝贵时间。

最佳答案

你的问题是外部包装函数 pthread_atfork似乎已移至libpthread_nonshared.a这样它就可以识别调用它的库,大概这样在卸载库时可以删除已安装的处理程序,并且它通过引用 __dso_handle 来实现这一点符号是在启动文件中定义的,您故意省略了该符号。 你不能这样做。省略启动文件仅对某些低级目的有效;它与链接标准库的任何部分都不兼容。

显然是您使用 -nostartfiles 的原因就是能够自己写_init加载库时将运行的函数,因为没有 -nostartfiles由于与 crti.o 中的同名函数发生冲突,它会导致链接器错误。不幸的是,这是错误的修复。

重新定义_init在库加载时运行代码是一种不受支持的黑客行为,很久以前就已被弃用。在库加载时运行代码的正确方法是应用 __attribute__((__constructor__))到你想要运行的函数。为函数指定一个不会与任何内容冲突的名称,或者直接将其设为 static所以你不必担心它的名称冲突。

关于c - 声明 -nostartfiles 时 pthread_atfork 无法编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28003587/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com