博客專欄

        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ù)庫

        原因

        實(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í)行程序,是會報(bào)錯的,因?yàn)檎也坏椒枴?/p>

        而-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ā)布,僅代表博主個人觀點(diǎn),如有侵權(quán)請聯(lián)系工作人員刪除。



        關(guān)鍵詞:

        相關(guān)推薦

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

        關(guān)閉
        主站蜘蛛池模板: 钟祥市| 忻城县| 若尔盖县| 靖远县| 水城县| 万宁市| 巴马| 容城县| 平原县| 衡阳市| 来凤县| 雅安市| 德昌县| 吉安市| 四平市| 达拉特旗| 昌吉市| 余庆县| 临沭县| 玉田县| 隆安县| 承德县| 秭归县| 吉木萨尔县| 昂仁县| 伊春市| 普安县| 扎赉特旗| 天全县| 镇沅| 姜堰市| 南雄市| 石阡县| 隆德县| 新巴尔虎右旗| 搜索| 彭水| 罗平县| 长宁县| 英德市| 东平县|