真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

記錄一次采坑--如何處理Linux動態(tài)庫同名函數(shù)?

一、背景介紹

需求描述:業(yè)務(wù)提供一個鑒權(quán)的靜態(tài)庫,我只需要從url 和 參數(shù)中提取相應(yīng)的參數(shù)傳給業(yè)務(wù)的靜態(tài)庫,將靜態(tài)庫的處理結(jié)果直接返回給業(yè)務(wù)(return < 0, 直接返回403)。

創(chuàng)新互聯(lián)建站致力于網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì),成都網(wǎng)站設(shè)計(jì),集團(tuán)網(wǎng)站建設(shè)等服務(wù)標(biāo)準(zhǔn)化,推過標(biāo)準(zhǔn)化降低中小企業(yè)的建站的成本,并持續(xù)提升建站的定制化服務(wù)水平進(jìn)行質(zhì)量交付,讓企業(yè)網(wǎng)站從市場競爭中脫穎而出。 選擇創(chuàng)新互聯(lián)建站,就選擇了安全、穩(wěn)定、美觀的網(wǎng)站建設(shè)服務(wù)!

但是最近業(yè)務(wù)反饋,請求部分url直接返回Error:-1015錯誤,不符合預(yù)期。

二、分析過程

業(yè)務(wù)剛開始反饋問題,我的第一反應(yīng):怎么可能是我的問題,我就僅僅寫了一個so(暫時命名1.so),直接調(diào)用了你們靜態(tài)庫,這個-1015不就是你們庫返回的結(jié)果。 有問題也是業(yè)務(wù)提供的庫有問題。 或者就是業(yè)務(wù)配置不正確。
我臨時解決方案:

  1. 讓業(yè)務(wù)檢查配置 ,是否和校驗(yàn)級別有關(guān)系?
  2. 雙方md5的靜態(tài)庫,本地調(diào)試結(jié)果是否正確?
  3. 上述方案不行: 采用最挫的方案, 既然靜態(tài)庫吐出來的結(jié)果,瘋狂加printf,我就不信這個邪了

最后還是走到方案3,業(yè)務(wù)說printf的結(jié)果不符合預(yù)期,經(jīng)業(yè)務(wù)提醒,突然意識到是不是調(diào)用鏈接到其他庫的xx_func?

因?yàn)轫?xiàng)目比較大, 涉及的庫比較多,我用nm認(rèn)真檢查了編譯時加載的庫,竟然還真找到一模一樣的接口xx_func

nm   ./lib/liba.a | grep xx_func

記錄一次采坑--如何處理Linux動態(tài)庫同名函數(shù)?
編譯代碼的時候,趕緊去掉了同名函數(shù)庫(因?yàn)樵趍akefile文件編譯的時候某些公共庫默認(rèn)都會編譯進(jìn)去)。重新編譯版本。

沒有想到,去掉同名函數(shù)庫,還是存在問題,為什么呢?到底是哪里的問題?

隨手直接 nm *.so | grep xx_func,結(jié)果在另外一個so(暫時命名2.so)中,發(fā)現(xiàn)了同名函數(shù)xx_func。 看了一下配置,程序啟動的時候首先加載了2.so動態(tài)庫, 1.so是在2.so后面加載的. 因?yàn)閮?yōu)先加載哪個庫,就使用哪個庫的同名函數(shù),并不會覆蓋的情況(自己現(xiàn)網(wǎng)測試 + 測試代碼)

到這里問題的原因也算是找到了,下面接著就是如何解決問題?

三、解決方案

1. 最簡單的方案 -- 修改函數(shù)名稱

因?yàn)闃I(yè)務(wù)本身提供的靜態(tài)庫,用nm查看函數(shù)也不多,為了安全起見,修改每個函數(shù)的名稱(增加一些業(yè)務(wù)私有的東西)。 批量修改函數(shù)名可直接使用sed

2. -fvisibility=hidden -- 最安全最推薦的做法

現(xiàn)在C/C++這一塊有幾十年的歷史,該踩的坑大家都應(yīng)該踩過去了。gcc編譯器就直接提供-fvisibility=hidden編譯選項(xiàng),直接讓庫函數(shù)global可見變成local可見, 使用__attribute__((visibility("default")))直接將需要的函數(shù)暴漏在外面就行

-fvisibility=[default|internal|hidden|protected]
Set the default ELF image symbol visibility to the specified option---all symbols are marked with this unless overridden within the code. Using this feature can very substantially improve linking and load times of shared object libraries, produce more optimized code, provide near-perfect API export and prevent symbol clashes. It is strongly recommended that you use this in any shared objects you distribute.
A good explanation of the benefits offered by ensuring ELF symbols have the correct visibility is given by "How To Write Shared Libraries" by Ulrich Drepper (which can be found at )---however a superior solution made possible by this option to marking things hidden when the default is public is to make the default hidden and mark things public.

     將默認(rèn)ELF符號可見性設(shè)置為指定選項(xiàng)---除非在代碼中覆蓋,否則所有符號都標(biāo)記為此。 使用此功能可以極大地改善共享對象庫的鏈接和加載時間,生成更優(yōu)化的代碼,提供近乎完美的API導(dǎo)出并防止符號沖突。 強(qiáng)烈建議您在分發(fā)的任何共享對象中使用它
     Ulrich Drepper的“如何編寫共享庫”(可在上找到)中給出了確保ELF符號具有正確可見性所帶來的好處的一個很好的解釋 - - 當(dāng)默認(rèn)為公共時,通過此選項(xiàng)可以標(biāo)記隱藏的內(nèi)容的優(yōu)秀解決方案是隱藏默認(rèn)值并將事物標(biāo)記為公共

四、練習(xí)實(shí)踐---驗(yàn)證動態(tài)庫的同名函數(shù)調(diào)串

1.代碼結(jié)構(gòu)很簡單
.  
├── libqqmusic.c              
├── libtmemusic.c              
├── main
├── main.c
├── makefile
└── README.md
2. libqqmusic.c
//libqqmusic.c

#include

int get_music_id()
{
    return 1111;
}

void qqmusic_print()
{
    printf("qqmusic id: %d\n", get_music_id());

    return;
}
3. libtmemusic.c
//libtmemusic.c

#include

int get_music_id()
{
    return 2222;
}

void tmemusic_print()
{
    printf("tmemusic id: %d\n", get_music_id());

    return;
}
4. main.c
//main.c

#include

int main(int argc, char *argv[])
{

    printf("start\n");

    tmemusic_print();

    qqmusic_print();

    tmemusic_print();

    printf("end\n");

    return 0;
}
5.makefile
# 1. create  /etc/ld.so.conf.d/vaynedu-test.conf
#         /usr/lib64/vaynedu
# 2. mkdir /usr/lib64/vaynedu 
#
# 3. \cp *.so /usr/lib64/vaynedu

all:
    gcc -g -fpic -c -o libqqmusic.o libqqmusic.c
    gcc -g -shared -o libqqmusic.so libqqmusic.o 
    gcc -g -fpic -c -o libtmemusic.o libtmemusic.c
    gcc -g -shared -o libtmemusic.so libtmemusic.o
    \cp *.so /usr/lib64/vaynedu
    @ldconfig
    #gcc -g -o main main.c -L. -lqqmusic -ltmemusic
    gcc -g -o main main.c -L. -ltmemusic -lqqmusic
    @echo -e "\n\ncompile complete\n\n"

clean:
    rm -fr *.so *.o 
6.測試結(jié)果--證明同名函數(shù)庫受編譯時加載順序的影響

將tmemusic放在前面gcc -g -o main main.c -L. -ltmemusic -lqqmusic
記錄一次采坑--如何處理Linux動態(tài)庫同名函數(shù)?
將qqmusic放在前面gcc -g -o main main.c -L. -lqqmusic -ltmemusic
記錄一次采坑--如何處理Linux動態(tài)庫同名函數(shù)?

五、總結(jié)

《程序的自我修養(yǎng)-鏈接、裝載與庫》應(yīng)該好好的啃一遍, 這個一個后臺開發(fā)必備的知識技能

-fvisibility=hidden的用法 https://blog.csdn.net/caspiansea/article/details/77113066
多共享動態(tài)庫中同名對象重復(fù)析構(gòu)問題的解決方法 https://www.ibm.com/developerworks/cn/linux/l-cn-sdlstatic/
GCC的符號可見性——解決多個庫同名符號沖突問題 http://blog.chinaunix.net/uid-27875-id-5759441.html


名稱欄目:記錄一次采坑--如何處理Linux動態(tài)庫同名函數(shù)?
網(wǎng)站網(wǎng)址:http://weahome.cn/article/ijscii.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部