我试图探索gcc的这些功能如何运作。
我已经创建了一个带有函数的库,该函数应该调用sigprocmask
或pthread_sigmask
,具体取决于libpthread
是否已链接。
我的弱代码版本的代码按预期工作,但我的基于弱符号的版本似乎没有像我期望的那样被真正的pthread_sigmask
符号覆盖。
请你指出我做错了什么?
Weakref版本:
#!/bin/sh
cat > lib.c <<EOF
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <pthread.h>
#include <stdlib.h>
__attribute__((weakref("pthread_sigmask")))
static int pthread_sigmask_ref(int How, sigset_t const *Set, sigset_t *Oldset);
int call_pthread_sigmask(int How, sigset_t const *Set, sigset_t *Oldset)
{
puts("calling pthread_sigmask");
if(pthread_sigmask_ref){
return pthread_sigmask_ref(How, Set, Oldset);
}else{
puts("SIGPROCMASK");
return sigprocmask(How, Set, Oldset);
}
}
EOF
cat > main.c <<EOF
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <pthread.h>
#include <stdlib.h>
int call_pthread_sigmask(int How, sigset_t const *Set, sigset_t *Oldset);
int main()
{
sigset_t all_sigs, old_mask;
sigemptyset(&all_sigs);
sigaddset(&all_sigs, SIGTERM);
call_pthread_sigmask(SIG_SETMASK, &all_sigs, &old_mask);
#if 0
pthread_mutex_t mx;
pthread_mutex_init(&mx,0);
#endif
}
EOF
gcc -c -fpic lib.c
gcc lib.o -o lib.so -shared
gcc main.c $PWD/lib.so -lpthread -o wrap
gcc main.c $PWD/lib.so -Wl,--no-as-needed -lpthread -o real
echo wrap
ldd ./wrap
./wrap
echo real
ldd ./real
./real
示例输出:
wrap
linux-vdso.so.1 => (0x00007ffd5dda0000)
/home/user/tmp/lib.so (0x00007faa4f8cf000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007faa4f507000)
/lib64/ld-linux-x86-64.so.2 (0x00007faa4fad1000)
calling pthread_sigmask
SIGPROCMASK
real
linux-vdso.so.1 => (0x00007ffc7f51e000)
/home/user/tmp/lib.so (0x00007f6ff23b2000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f6ff2194000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6ff1dcc000)
/lib64/ld-linux-x86-64.so.2 (0x00007f6ff25b4000)
calling pthread_sigmask
弱符号版本:
#!/bin/sh
cat > lib.c <<EOF
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <pthread.h>
#include <stdlib.h>
__attribute__((weak,noinline))
int pthread_sigmask(int How, sigset_t const *Set, sigset_t *Oldset)
{
puts("SIGPROCMASK");
return sigprocmask(How, Set, Oldset);
}
int call_pthread_sigmask(int How, sigset_t const *Set, sigset_t *Oldset)
{
puts("calling pthread_sigmask");
return pthread_sigmask(How, Set, Oldset);
}
EOF
cat > main.c <<EOF
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <pthread.h>
#include <stdlib.h>
int call_pthread_sigmask(int How, sigset_t const *Set, sigset_t *Oldset);
int main()
{
sigset_t all_sigs, old_mask;
sigemptyset(&all_sigs);
sigaddset(&all_sigs, SIGTERM);
call_pthread_sigmask(SIG_SETMASK, &all_sigs, &old_mask);
#if 0
pthread_mutex_t mx;
pthread_mutex_init(&mx,0);
#endif
}
EOF
gcc -c -fpic lib.c
gcc lib.o -o lib.so -shared
gcc main.c $PWD/lib.so -lpthread -o wrap
gcc main.c $PWD/lib.so -Wl,--no-as-needed -lpthread -o real
echo wrap
ldd ./wrap
./wrap
echo real
ldd ./real
./real
示例输出:
wrap
linux-vdso.so.1 => (0x00007ffd19d23000)
/home/user/tmp/lib.so (0x00007fdd24b46000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fdd2477e000)
/lib64/ld-linux-x86-64.so.2 (0x00007fdd24d48000)
calling pthread_sigmask
SIGPROCMASK
real
linux-vdso.so.1 => (0x00007fff115f6000)
/home/user/tmp/lib.so (0x00007fb22be95000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fb22bc77000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb22b8af000)
/lib64/ld-linux-x86-64.so.2 (0x00007fb22c097000)
calling pthread_sigmask
SIGPROCMASK
答案 0 :(得分:1)
只需交换库顺序:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.5.2.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>