2014-01-13 8 views
3

pthreadglibc.so實現弱符號提供pthread存根函數?是在glibc.so中通過弱符號實現的pthread以提供pthread存根函數?

我知道有pthread.so提供在glibc.so有人與pthread類似的功能說pthreadglibc只提供存根和將取代時明確鏈接到lpthread

所以我的問題是如何支持它?使用弱符號或其他技術?

libsslpthread相似glibc

+0

問題很不清楚:你需要爲pthread和glibc提供什麼樣的「支持」?除非您正在編寫諸如調試器之類的系統工具,否則您應該不在乎pthread符號是否以弱符號或其他方式實現。你想要解決什麼具體問題? – user4815162342

+0

我想知道如何爲pthread提供存根功能? – jiafu

回答

4

是的,glibc使用各種pthread函數的存根實現,以便單線程程序不必浪費週期來執行鎖定和解鎖互斥鎖等操作,但不必鏈接到不同的C庫(如例如在Microsoft世界中完成)。

例如,根據POSIX,每次您撥打fputc(ch, stream)時,都會有互斥鎖和解鎖。如果你不想要,你可以撥打fputc_unlocked。但是當你這樣做時,你正在使用與線程相關的POSIX擴展;對於不使用POSIX或不使用線程API的程序,這不是一個適當的解決方法。

將存根pthread函數重寫爲真實的(在動態glibc中)不基於弱符號。共享庫機制可以覆蓋非弱定義。

弱符號是一種允許在靜態鏈接下進行符號覆蓋的機制。

如果你想爲上述說法的來源,那就是:。

「請注意,在DSO定義爲弱有沒有效果弱定義,只有在靜態鏈接中發揮作用。 「 [Ulrich Drepper,"How To Write Shared Libraries"]。

如果你在你的系統上的靜態glibc的運行nm(如果有的話),libc.a,你會注意到,像pthread_mutex_lock功能標記弱。在動態版中,libc.so.<whatetever>,功能沒有標記爲弱。

注意:您應該使用nm -Dnm --dynamic來查看共享庫中的符號。 nm不會在被剝離的共享庫上產生任何東西。如果是這樣,你正在查看調試符號,而不是動態符號。

3

看到這個SO answer。可以使用幾種技術來允許在多個庫中定義相同的符號,根據是否正在使用動態鏈接或靜態鏈接來鏈接程序。

  1. 符號插入。當動態鏈接,如果一個符號在多個庫中定義,則鏈接器將使用它找到的第一個版本(除非這些符號是內部的,隱藏的或受保護的;參見this blog article爲一個描述)

  2. 弱對象。當靜態鏈接時,如果鏈接器找到兩個相同名稱的符號,並且一個是「弱」引用,那麼鏈接器將使用非弱引用。

  3. 符號版本控制也可能發揮作用。

在幾乎所有情況下,程序都動態鏈接到libc。

您可以在其中看到了庫將使用LDD加載順序:

$ ldd simple_pthread 
     linux-vdso.so.1 => (0x00007fffaddff000) 
     libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fa13a474000) 
     libc.so.6 => /lib64/libc.so.6 (0x00007fa13a0e0000) 
     /lib64/ld-linux-x86-64.so.2 (0x00007fa13a6a0000) 

在這裏你可以看到,pthread是在連接順序的libc之前。這幾乎總是如此; libc始終使用默認編譯器選項進行鏈接。

因此,與libpthread鏈接的程序將使用這些符號的pthread版本,因爲它們首先在鏈接順序中遇到。

如果您仍然不確定,使用設置爲「綁定」的環境變量LD_DEBUG啓動程序將顯示正在發生的實際符號綁定。

如果您使用的是靜態鏈接,您將鏈接到libc.a而不是libc.so.您可以使用'nm'列出符號的詳細信息。弱符號的類型有'W'或'w'。

(感謝@Kaz指出弱符號不影響動態鏈接)。

+0

您正在查看調試符號。一個剝離的'.so'文件不會給你任何符號,除非你使用'nm --dynamic'或'nm -D'。 – Kaz

+0

我想它應該避免鏈接順序問題,所以即使libc.so首先被查找,它也應該在運行時調用正確的函數。 glibc中有一些像轉發一樣的技巧。 – tristan