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.mzph.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; 枚举类型名…