博客專欄

EEPW首頁 > 博客 > hidden symbol `pthread_atfork'

hidden symbol `pthread_atfork'

發(fā)布人:電子禪石 時間:2020-09-24 來源:工程師 發(fā)布文章
hidden symbol `pthread_atfork'
gcc交叉編譯時發(fā)生這種錯誤

/.. .../voice_demo: hidden symbol `pthread_atfork' in /opt/gcc-linaro-aarch64-linux-gnu-4.9-2014.09_linux/bin/../aarch64-linux-gnu/libc/usr/lib/aarch64-linux-gnu/libpthread_nonshared.a(pthread_atfork.oS) is referenced by DSO

調(diào)用關(guān)系如下:

A->B.so->多線程函數(shù)庫
A依賴B的動態(tài)庫文件。B動態(tài)庫又依賴于多線程函數(shù)庫

原因

實際上,pthread_atfork這個函數(shù)并不在libpthread.so.0庫里面。 是在鏈接的時候直接把一個.a鏈接到庫里面的

B.so在鏈接的時候,使用-lpthread引入多線程庫,而-lpthread并不會把包含pthread_atfork
的靜態(tài)庫鏈進(jìn)來。

解決方法

B.so在編譯的時候 使用-pthread引入多線程庫,而不是-lpthread

-lpthread和pthread的區(qū)別

例如下面的代碼,使用了多線程庫。

#include <sys/types.h>#include <pthread.h>#include <sys/wait.h>
 pid_t self_pid;        /* pid of current process */pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;void fork_prepare(void){
    pthread_mutex_lock(&mutex);
}void fork_parent(void){
    pthread_mutex_unlock(&mutex);
}void fork_child(void){
    self_pid = getpid();
    pthread_mutex_unlock(&mutex);
}void *thread_routine(void *arg){    pid_t child_pid;

    child_pid = fork();    if(child_pid == (pid_t)-1)        return NULL;

    pthread_mutex_lock(&mutex);
    pthread_mutex_unlock(&mutex);    printf("After fork: %d (%d)\n", child_pid, self_pid);    if(child_pid != 0){ // parent process
        if ((pid_t)-1 == waitpid(child_pid, (int*)0, 0))            return NULL;
    }    return NULL;
}int main(int argc, char *argv[]){    pthread_t fork_thread;    int atfork_flag = 1;    if(argc > 1)
        atfork_flag = atoi (argv[1]);    if(atfork_flag){
        pthread_atfork(fork_prepare, fork_parent, fork_child);
    }
    self_pid = getpid();
    pthread_mutex_lock(&mutex);

    pthread_create(&fork_thread, NULL, thread_routine, NULL);
    sleep(5);
    pthread_mutex_unlock (&mutex);
    pthread_join(fork_thread, NULL);    return 0;
}

分別采用兩種方式編譯成動態(tài)庫

gcc -shared -fPIC  -Wall -lpthread -o atfork.so main.cgcc -shared -fPIC  -Wall -pthread -o atfork.so main.c

采用-lpthread生成的so大小為13008
采用-pthread生成的so大小為16816,說明鏈接了一塊東西。。

附:如果直接用-lpthread將上段代碼生成可執(zhí)行程序,是會報錯的,因為找不到符號。

而-pthread是不會有這種問題的。

為什么會有這種區(qū)別呢。

gcc -v -shared -fPIC  -Wall -lpthread -o atfork.so main.cgcc -v -shared -fPIC  -Wall -pthread -o atfork.so main.c

分別打印診斷日志。

進(jìn)行比較發(fā)現(xiàn)。

gcc -v -shared -fPIC  -Wall -pthread -o atfork.so main.c
輸出 /usr/lib/gcc/x86_64-linux-gnu/5/cc1 -quiet -v -imultiarch x86_64-linux-gnu -D_REENTRANT main.c -quiet -dumpbase main.c -mtune=generic -march=x86-64 -auxbase main -Wall -version -fPIC -fstack-protector-strong -Wformat-security -o /tmp/cciFOaoT.s


gcc -v -shared -fPIC  -Wall -lpthread -o atfork.so main.c
輸出 /usr/lib/gcc/x86_64-linux-gnu/5/cc1 -quiet -v -imultiarch x86_64-linux-gnu main.c -quiet -dumpbase main.c -mtune=generic -march=x86-64 -auxbase main -Wall -version -fPIC -fstack-protector-strong -Wformat-security -o /tmp/ccZTeFNI.s

第一個多了-D_REENTRANT, 這個宏是線程安全的意思。

轉(zhuǎn)載的時候,請注明出處哦http://www.cnblogs.com/stonehat/

轉(zhuǎn)載請注明出處:http://www.cnblogs.com/stonehat/


*博客內(nèi)容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點,如有侵權(quán)請聯(lián)系工作人員刪除。



關(guān)鍵詞:

相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉