ubuntu-c++-可執行模塊-動態鏈接庫-鏈接庫搜索-基礎知識

文章目錄

    • 1.動態鏈接庫簡介
    • 2.動態庫搜索路徑
    • 3.運行時鏈接及搜索順序
    • 4.查看可運行模塊的鏈接庫
    • 5.總結

1.動態鏈接庫簡介

動態庫又叫動態鏈接庫,是程序運行的時候加載的庫,當動態鏈接庫正確安裝后,所有的程序都可以使用動態庫來運行程序。動態庫是目標文件的集合,目標文件在動態庫中的組織方式是按特殊的方式組織形成的。在動態庫中函數和變量的地址是相對地址而不是絕對地址,其真實地址在調用動態庫的程序加載時形成的。
動態庫的名字有別名(soname), 真名(realname)和鏈接名(linkername)。別名是由一個lib前綴,然后是庫的名字,最后以“.so”結尾來構成。真名是動態鏈接庫的真實名字,一般總是在別名的基礎上添加一個版本號信息。除此之外還有一個鏈接名,他是在程序鏈接的時候使用的名字。
動態庫安裝的時候,總是復制庫文件到某一個目錄,然后使用一個軟鏈接生成一個別名,在庫文件更新的時候,僅僅更新軟鏈接即可。

2.動態庫搜索路徑

(僅對ELF格式)如果可執行文件包含DT_RPATH標簽,并且不包含DT_RUNPATH標簽,將從DT_RPATH列出的路徑搜索。(DT_RPATH已經被廢棄,請用DT_RUNPATH)
如果LD_LIBRARY_PATH在程序運行時被定義,那么將從它包含的路徑開始。安全起見,對于set-user-ID或者set-group-ID的程序,這個變量將被忽略。
(僅對ELF格式)如果可執行文件包含DT_RUNPATH標簽,將從這個標簽列出的路徑開始搜索。
從 /etc/ld.so.cache(運行ldconfig產生)中查找文件
從/lib以及/urs/lib,按順序搜索。如果鏈接時指定-z nodefaultlib,這個步驟將被忽略。

3.運行時鏈接及搜索順序

這個過程是由ld-linux.so程序來執行,這個才是真正的鏈接。它所做的工作就是將動態庫的代碼映射到進程的虛擬地址空間中,供進程來調用。程序在連接時使用了共享庫,就必須在運行的時候能夠找到共享庫的位置。linux的可執行程序在執行的時候默認是先搜索/lib和/usr/lib這兩個目錄,然后按照/etc/ld.so.conf里面的配置搜索絕對路徑。同時,Linux也提供了環境變量LD_LIBRARY_PATH供用戶選擇使用,用戶可以通過設定它來查找除默認路徑之外的其他路徑,LD_LIBRARY_PATH路徑優先于系統默認路徑之前查找。

LD_LIBRARY_PATH的設定作用是全局的,過多的使用可能會影響到其他應用程序的運行,所以多用在調試。通常情況下推薦還是使用gcc的-R或-rpath選項來在編譯時就指定庫的查找路徑,并且該庫的路徑信息保存在可執行文件中,運行時它會直接到該路徑查找庫,避免了使用LD_LIBRARY_PATH環境變量查找!!(看到Qt的使用qmake生成的makefile中,有gcc -rpath xxx,指出程序運行時的一個搜索路徑, 或許與qt的QMAKE_RPATHDIR有關)

ld-linux.so.x在可執行的目標文件中被指定,可用readelf -l命令查看 。
(很多現代應用都是通過動態編譯鏈接的,當一個 需要動態鏈接 的應用被操作系統加載時,系統必須要 定位 然后 加載它所 需要的所有動態庫文件。 在Linux環境下,這項工作是由ld-linux.so.x來負責完成的)
和Windows下的PE文件類似,ELF文件是linux系統下可執行文件、動態庫文件、靜態庫文件的標準格式。

例如,運行readelf -l 文件名,在輸出的Headers部分的INTERP部分,會指出該可執行文件需要的ld-linux.so。
在這里插入圖片描述

運行時,ld-linux.so 查找共享庫的路徑:
(1)編譯時使用gcc的-R或-rpath選項指定路徑。
(2)LD_LIBRARY_PATH環境變量中所設定的路徑。
(3)ld-linux.so 缺省在/usr/lib和/lib中搜索;當glibc安裝到/usr/local下時,它查找/usr/local/lib
(4)/etc/ld.so.conf(或/usr/local/etc/ld.so.conf)中所指定的路徑。 (查看/etc/ld.so.conf文件:或許只有一行:“include /etc/ld.so.conf.d/*.conf ”,意味著包括了/etc/ld.so.conf.d/目錄下的所有.conf文件,每個文件中都寫著具體的路徑。如果你想加一個運行時的搜索路徑,可在/etc/ld.so.conf.d目錄下新建一個.conf文件,里面寫上路徑,注意添加完了之后要在root權限下運行ldconfig指令,使其生效,該指令更新記錄了系統中有哪些so文件的緩存文件(/etc /ld.so.cache)。)

4.查看可運行模塊的鏈接庫

可使用ldd指令查看一個可執行文件依賴于哪些庫:ldd xxx

ldd  bash

在這里插入圖片描述
linux-vdso.so.1是Linux為了解決和glibc兼容而想出的絕招。
原來這個 linux-vdso.so.1 文件,并不是一個真實存在的文件,而是 Linux 中的一個虛擬文件,專門用于將內核中一些常用的函數從內核空間映射到用戶空間。也就是說,這個文件不用復制。
VDSO就是Virtual Dynamic Shared Object,就是內核提供的虛擬的.so,這個.so文件不在磁盤上,而是在內核里。內核把包含某.so的內存頁在程序啟動的時候映射入其內存空間,對應的程序就可以當普通的.so來使用其提供的函數接口。

5.總結

在linux下的動態鏈接庫并不從程序所在當前目錄查找連接庫,而是從編譯時指定目錄查找,或者默認目錄查找。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/215379.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/215379.shtml
英文地址,請注明出處:http://en.pswp.cn/news/215379.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android帝國之日志系統--logd、logcat

本文概要 這是Android系統進程系列的第四篇文章,本文以自述的方式來介紹logd進程,通過本文您將了解到logd進程存在的意義,以及日志系統的實現原理。(文中的代碼是基于android13) Android系統進程系列的前三篇文章如下…

C#基礎與進階擴展合集-基礎篇(持續更新)

目錄 本文分兩篇,進階篇點擊:C#基礎與進階擴展合集-進階篇 一、基礎入門 Ⅰ 關鍵字 Ⅱ 特性 Ⅲ 常見異常 Ⅳ 基礎擴展 1、哈希表 2、擴展方法 3、自定義集合與索引器 4、迭代器與分部類 5、yield return 6、注冊表 7、不安全代碼 8、方法…

MATLAB中cell函數的用法

cell用法 在MATLAB中,cell 是一種特殊的數據類型,用于存儲不同大小和類型的數據。cell 數組是一種容器,每個元素可以包含任意類型的數據,包括數值、字符串、矩陣、甚至其他的 cell 數組。 以下是 cell 數組的基本語法和示例&…

gitblit自建git倉庫

安裝 java sudo apt-get update sudo apt-get install openjdk-8-jdk # 或者其它你喜歡的版本 驗證: java -version 下載 gitblit https://github.com/gitblit-org/gitblit/releases 解壓/usr/local tar -zxvf gitblit-1.9.3.tar.gz 修改配置文件 nano /usr/local/…

【React】useCallback 使用的說明

文章目錄 useCallback的優缺點優點缺點JavaScript 的內聯優化 使用場景 用了兩年多的react,今天抽空寫點小內容 useCallback的優缺點 緩存了每次渲染時候 inline callback的實例 優點 關鍵點:利用memoize減少無效的re-render,通常配合shouldC…

ElasticSearch之cat trained model API

命令樣例如下: curl -X GET "https://localhost:9200/_cat/ml/trained_models?vtrue&pretty" --cacert $ES_HOME/config/certs/http_ca.crt -u "elastic:ohCxPHQBEs5*lo7F9"執行結果輸出如下: id heap_size …

如何在OpenWRT軟路由系統部署uhttpd搭建web服務器實現遠程訪問——“cpolar內網穿透”

文章目錄 前言1. 檢查uhttpd安裝2. 部署web站點3. 安裝cpolar內網穿透4. 配置遠程訪問地址5. 配置固定遠程地址 前言 uhttpd 是 OpenWrt/LuCI 開發者從零開始編寫的 Web 服務器,目的是成為優秀穩定的、適合嵌入式設備的輕量級任務的 HTTP 服務器,并且和…

docker-compose的介紹與使用

一、docker-compose 常用命令和指令 1. 概要 默認的模板文件是 docker-compose.yml,其中定義的每個服務可以通過 image 指令指定鏡像或 build 指令(需要 Dockerfile)來自動構建。 注意如果使用 build 指令,在 Dockerfile 中設置…

RHEL網絡服務器

目錄 1.時間同步的重要性 2.配置時間服務器 (1)指定所使用的上層時間服務器。 (2)指定允許訪問的客戶端 (3)把local stratum 前的注釋符#去掉。 3.配置chrony客戶端 (1)修改pool那行,指定要從哪臺時間…

Python常見面試知識總結(一):迭代器、拷貝、線程及底層結構

前言: Hello大家好,我是Dream。 今天來總結一下Python和C語言中常見的面試知識,歡迎大家一起前來探討學習~ 【一】Python中迭代器的概念? 可迭代對象是迭代器、生成器和裝飾器的基礎。簡單來說,可以使用for來循環遍歷…

[古劍山2023] pwn

最近這個打stdout的題真多。這個比賽沒打。拿到附件作了一天。 choice 32位,libc-2.23-i386,nbytes初始值為0x14,讀入0x804A04C 0x14字節后會覆蓋到nbytes 1個字節。當再次向v1讀入nbytes字節時會造成溢出。 先寫0x14p8(0xff)覆蓋到nbytes然后溢出寫傳…

初次參加軟考就想報高級,哪個相對容易考?

如果你想第一次參加軟考時就報考高級科目,但是卻不知道該報考高級中的哪個科目好、 ? ?那么今天的這篇文章你一定不要錯過!首先,我們一起來了解一下,軟考高級中的5個科目。 ? ?軟考高級科目 ? 信息系統項目管理師 ? …

記錄一次postgresql臨時表丟失問題

項目相關技術棧 springboot hikari連接池pgbouncerpostgresql數據庫 背景 為了優化一個任務執行的速度,我將任務的sql中部分語句抽出生成臨時表(create temp table tempqw as xxxxxxxxx),再和其他表關聯,提高查詢速…

三翼鳥2023輝煌收官, 定盤2024高質量棋局

最近在不同平臺上接連看到這樣的熱搜話題:用時間膠囊記錄2023的自己、2023年度問答、2023十大網絡流行語公布… 顯然, 2023年進入最后一個月,時間匆匆,這也意味著又到了總結過去和規劃未來的時候。拿到結果、取得成績當然是對202…

算法通關村第十五關 | 白銀 | 海量數據場景下的熱門算法題

1.從 40 個億中產生一個不存在的整數 可以采用位圖存儲數據,申請一個 bit 類型的數組 bitArr ,每個位置只表示 0 或者 1 狀態,可以將占用內存縮小為使用哈希表的 1/32 。 遍歷給定的 40 億個數,遇到數時就將 bitArr 相應位置設置…

短視頻引流獲客系統:引領未來營銷的新潮流

在這個信息爆炸的時代,短視頻已經成為了人們獲取信息的主要渠道之一。而隨著短視頻的火爆,引流獲客系統也逐漸成為了營銷領域的新寵。本文將詳細介紹短視頻引流獲客系統的開發流程以及涉及到的技術,讓我們一起來看看這個引領未來營銷的新潮流…

華清遠見作業第二十四天

使用消息隊列完成兩個進程之間相互通信 代碼 #include<stdio.h> #include<string.h> #include<stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/ipc.h> #include <sys/msg.h> #in…

k8s一鍵部署uniswap

1、拉取uniswap源碼 github地址 2、編寫Dockerfile并打鏡像 # Set the base image FROM node:18.10.0# WORKDIR /usr/src/app/ WORKDIR /home/gateway# Copy files COPY ./ /home/gateway/# Dockerfile author / maintainer LABEL maintainer"Michael Feng <mikehummi…

Java最全面試題專題---2、Java集合容器(2)

Map接口 說一下 HashMap 的實現原理&#xff1f; HashMap概述&#xff1a; HashMap是基于哈希表的Map接口的非同步實現。此實現提供所有可選的映射操作&#xff0c;并允許使用null值和null鍵。此類不保證映射的順序&#xff0c;特別是它不保證該順序恒久不變。 HashMap的數據…

C語言-枚舉

常量符號化 用符號而不是具體的數字來表示程序中的數字 枚舉 用枚舉而不是定義獨立的const int變量 枚舉是一種用戶定義的數據類型&#xff0c;他用關鍵詞enum以如下語法來聲明&#xff1a; enum枚舉類型名字{名字0&#xff0c;…&#xff0c;名字n}&#xff1b; 枚舉類型名…