• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            tqsheng

            go.....
            隨筆 - 366, 文章 - 18, 評論 - 101, 引用 - 0
            數(shù)據(jù)加載中……

            linux下so動態(tài)庫一些不為人知的秘密(上) (2012-08-14 22:48)



            linux 下有動態(tài)庫和靜態(tài)庫,動態(tài)庫以.so為擴(kuò)展名,靜態(tài)庫以.a為擴(kuò)展名。二者都使用廣泛。本文主要講動態(tài)庫方面知識。

            基本上每一個linux 程序都至少會有一個動態(tài)庫,查看某個程序使用了那些動態(tài)庫,使用ldd命令查看
            1. # ldd /bin/ls
            2. linux-vdso.so.1 => (0x00007fff597ff000)
            3. libselinux.so.1 => /lib64/libselinux.so.1 (0x00000036c2e00000)
            4. librt.so.1 => /lib64/librt.so.1 (0x00000036c2200000)
            5. libcap.so.2 => /lib64/libcap.so.2 (0x00000036c4a00000)
            6. libacl.so.1 => /lib64/libacl.so.1 (0x00000036d0600000)
            7. libc.so.6 => /lib64/libc.so.6 (0x00000036c1200000)
            8. libdl.so.2 => /lib64/libdl.so.2 (0x00000036c1600000)
            9. /lib64/ld-linux-x86-64.so.2 (0x00000036c0e00000)
            10. libpthread.so.0 => /lib64/libpthread.so.0 (0x00000036c1a00000)
            11. libattr.so.1 => /lib64/libattr.so.1 (0x00000036cf600000)
            這么多so,是的。使用ldd顯示的so,并不是所有so都是需要使用的,下面舉個例子
            main.cpp
            1. #include <stdio.h>
            2. #include <iostream>
            3. #include <string>
            4. using namespace std;

            5. int main ()
            6. {
            7. cout << "test" << endl;
            8. return 0;
            9. }
            使用缺省參數(shù)編譯結(jié)果
            1. # g++ -o demo main.cpp
            2. # ldd demo
            3. linux-vdso.so.1 => (0x00007fffcd1ff000)
            4. libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f4d02f69000)
            5. libm.so.6 => /lib64/libm.so.6 (0x00000036c1e00000)
            6. libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00000036c7e00000)
            7. libc.so.6 => /lib64/libc.so.6 (0x00000036c1200000)
            8. /lib64/ld-linux-x86-64.so.2 (0x00000036c0e00000)
            如果我鏈接一些so,但是程序并不用到這些so,又是什么情況呢,下面我加入鏈接壓縮庫,數(shù)學(xué)庫,線程庫
            1. # g++ -o demo -lz -lm -lrt main.cpp
            2. # ldd demo
            3. linux-vdso.so.1 => (0x00007fff0f7fc000)
            4. libz.so.1 => /lib64/libz.so.1 (0x00000036c2600000)
            5. librt.so.1 => /lib64/librt.so.1 (0x00000036c2200000)
            6. libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007ff6ab70d000)
            7. libm.so.6 => /lib64/libm.so.6 (0x00000036c1e00000)
            8. libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00000036c7e00000)
            9. libc.so.6 => /lib64/libc.so.6 (0x00000036c1200000)
            10. libpthread.so.0 => /lib64/libpthread.so.0 (0x00000036c1a00000)
            11. /lib64/ld-linux-x86-64.so.2 (0x00000036c0e00000)
            看看,雖然沒有用到,但是一樣有鏈接進(jìn)來,那看看程序啟動時候有沒有去加載它們呢
            1. # strace ./demo
            2. execve("./demo", ["./demo"], [/* 30 vars */]) = 0
            3. ... = 0
            4. open("/lib64/libz.so.1", O_RDONLY) = 3
            5. ...
            6. close(3) = 0
            7. open("/lib64/librt.so.1", O_RDONLY) = 3
            8. ...
            9. close(3) = 0
            10. open("/usr/lib64/libstdc++.so.6", O_RDONLY) = 3
            11. ...
            12. close(3) = 0
            13. open("/lib64/libm.so.6", O_RDONLY) = 3
            14. ...
            15. close(3) = 0
            16. open("/lib64/libgcc_s.so.1", O_RDONLY) = 3
            17. ...
            18. close(3) = 0
            19. open("/lib64/libc.so.6", O_RDONLY) = 3
            20. ...
            21. close(3) = 0
            22. open("/lib64/libpthread.so.0", O_RDONLY) = 3
            23. ...
            24. close(3) = 0
            25. ...
            看,有加載,所以必定會影響進(jìn)程啟動速度,所以我們最后不要把無用的so編譯進(jìn)來,這里會有什么影響呢?
            大家知不知道linux從程序(program或?qū)ο螅┳兂蛇M(jìn)程(process或進(jìn)程),要經(jīng)過哪些步驟呢,這里如果詳細(xì)的說,估計要另開一篇文章。簡單的說分三步:
            1、fork進(jìn)程,在內(nèi)核創(chuàng)建進(jìn)程相關(guān)內(nèi)核項,加載進(jìn)程可執(zhí)行文件;
            2、查找依賴的so,一一加載映射虛擬地址
            3、初始化程序變量。
            可以看到,第二步中dll依賴越多,進(jìn)程啟動越慢,并且發(fā)布程序的時候,這些鏈接但沒有使用的so,同樣要一起跟著發(fā)布,否則進(jìn)程啟動時候,會失敗,找不到對應(yīng)的so。所以我們不能像上面那樣,把一些毫無意義的so鏈接進(jìn)來,浪費(fèi)資源。但是開發(fā)人員寫makefile 一般有沒有那么細(xì)心,圖省事方便,那么有什么好的辦法呢。繼續(xù)看下去,下面會給你解決方法。
            使用 ldd -u demo 查看不需要鏈接的so,看下面,一面了然,無用的so全部暴露出來了吧
            1. # ldd -u demo
            2. Unused direct dependencies:
            3. /lib64/libz.so.1
            4. /lib64/librt.so.1
            5. /lib64/libm.so.6
            6. /lib64/libgcc_s.so.1
            使用 -Wl,--as-needed 編譯選項
            1. # g++ -Wl,--as-needed -o demo -lz -lm -lrt main.cpp
            2. # ldd demo
            3. linux-vdso.so.1 => (0x00007fffebfff000)
            4. libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007ff665c05000)
            5. libc.so.6 => /lib64/libc.so.6 (0x00000036c1200000)
            6. libm.so.6 => /lib64/libm.so.6 (0x00000036c1e00000)
            7. /lib64/ld-linux-x86-64.so.2 (0x00000036c0e00000)
            8. libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00000036c7e00000)
            9. # ldd -u demo
            10. Unused direct dependencies:

            呵呵,辦法很簡單省事吧,本文主要講so依賴的一些問題,下一篇將介紹so的路徑方面一些不為人知的小秘密

             

            posted on 2013-01-04 16:57 tqsheng 閱讀(284) 評論(0)  編輯 收藏 引用


            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            精品久久久久久久久久中文字幕| 精品久久久久久久久中文字幕| 91性高湖久久久久| 久久久噜噜噜久久| 欧美丰满熟妇BBB久久久| 久久免费精品视频| 亚洲国产精品综合久久一线| 无码超乳爆乳中文字幕久久| 青青热久久综合网伊人| 亚洲午夜无码AV毛片久久| 久久国产亚洲精品无码| 亚洲午夜无码久久久久小说| 久久精品国产一区| 无码AV波多野结衣久久| 久久九九久精品国产免费直播| 久久精品国产亚洲AV无码娇色| 久久久久99精品成人片| 色综合久久88色综合天天| 人妻无码中文久久久久专区| 久久久久成人精品无码| 日韩精品久久久久久| 狠狠色丁香久久婷婷综| 久久亚洲欧美国产精品| 亚洲国产精品18久久久久久| 国产精品无码久久久久| 热99re久久国超精品首页| 99久久精品国产高清一区二区| 777午夜精品久久av蜜臀| 久久午夜综合久久| 欧美久久综合九色综合| 精品免费久久久久国产一区| 国产L精品国产亚洲区久久| 香蕉久久夜色精品国产小说| 青青热久久综合网伊人| 国产69精品久久久久9999| 99久久精品免费看国产一区二区三区| 久久66热人妻偷产精品9| 国产精品女同久久久久电影院| 久久久精品国产sm调教网站| 国产精品99精品久久免费| 2021久久国自产拍精品|