静态链接库在程序编译阶段就完成了链接工作,完成链接后,依赖的库就都打入了可执行文件中,所以文件大小一般会比较大。

而动态库链接库是在程序运行时才被链接的,所以磁盘上只要保留一份副本,因此节约了磁盘空间。如果发现了bug或要升级也很简单,只要用新的库把原来的替换掉就行了。Linux环境下的动态链接对象都是以.so为扩展名的共享对象(Shared Object).

生成共享动态链接库

main_1.c

#include "hello.h"

int main()
{
print_x(1);
sleep(10000);
return 0;
}

hello.c

#include <stdio.h>

void print_x(int x)
{
printf("call hello.so x=%d\n",x);
}

生成共享动态链接库 gcc -fPIC -shared -o hello.so hello.c

将main函数链接此共享库 gcc -o main_1 main_1.c ./hello.so

PIC:Position Independnet Code -fPIC表示生成位置无关的代码

有些系统需要无论加载到什么位置都可以正常工作的位置无关代码。链接器需要提供额外的技巧来支持位置无关代码,与程序中无法做到位置无关的部分隔离开来。

通过/proc 文件系统可以查看动态链接的程序在运行时会加载的额外的库有哪些



除了我们程序本身的main_1的段,还依赖了

  • hello.so这个是我们创建的动态链接库
  • libc.so.6这个是hello文件中所依赖的
  • ld-linux-x86-64.so.2这个是linux上的动态链接器。 使用动态链接库的时候,操作系统在运行程序之间,会先将控制权交给动态链接器,即/lib64/ld-linux-x86-64.so.2,它完成了动态链接的工作之后再把控制权交给应用程序。所以会在进程空间中看到这个

通过动态链接生成的main_1可执行文件中存储了这个信息,通过 readelf -s main_1查看 .interp section的内容

.interp

This section holds the pathname of a program interpreter. If the file has a loadable segment that includes the section, the section's attributes

will include the SHF_ALLOC bit. Otherwise, that bit will be off. This section is of type SHT_PROGBITS.

但是这样的依赖动态链接库,对最终运行时的动态链接库的位置有要求,将hello.so移动位置后就无法找到了。

可执行文件的运行时入口

真正可执行文件的运行时入口并不是main函数,而是glibc的运行时库,在执行main函数之前需要做一些初始化的工作。大部分Linux程序的入口地址应该都是 glibc 中的_start 函数



objdump -d ../PartIV/sta_vs_dyn/dyn_loop



这个对应glibc中的一段入口函数。

基本上到这里就理解了程序的编译,链接和装载的过程。文章只是跟随视频学习过程的一点记录,有些阅读linux内核的源码没有完全跟进去,感兴趣的可以看看原作者的分享视频

https://www.bilibili.com/video/BV1hv411s7ew/

Linux环境下:程序的链接, 装载和库[动态链接]的更多相关文章

  1. 如何查看Linux系统下程序运行时使用的库?

    Linux系统下程序运行会实时的用到相关动态库,某些场景下,比如需要裁剪不必要的动态库时,就需要查看哪些动态库被用到了. 以运行VLC为例. VLC开始运行后,首先查看vlc的PID,比如这次查到的V ...

  2. Linux环境下:程序的链接, 装载和库[静态链接]

    看以下例子 main.c extern int x; int main() { int y = 100; swap(&x,&y); return 0; } int x = 1; voi ...

  3. windows和linux环境下使用google的glog日志库

    一.概述 glog是google推出的一款轻量级c++开源日志框架,源码在github上,目前最新release版本是v0.3.5. githut地址:https://github.com/googl ...

  4. Linux 环境下程序不间断运行

    一.背景     在linux命令行中执行程序,程序通常会占用当前终端,如果不启动新的终端就没法执行其他操作.简单可以通过'&'将程序放到后台执行,但是这种方法有个问题就是,一旦连接远程服务器 ...

  5. 编写第一个Linux环境下程序的编译,下载记录

    跟着韦东山学习Linux: 今天系统系统性的学了代码的编译下载,条记录一下: 一,代码:001_led_on.S,就把下面代码编译后Bin文件下载进2440处理器. /* * 点亮LED1: gpf4 ...

  6. [Python学习] Linux环境下的Python配置,必备库的安装配置

    1.默认Python安装情况 一般情况,Linux会预装Python的,版本较低,比如Ubuntu15的系统一般预装的是Python2.7.10. 使用命令:which python可以查看当前的py ...

  7. 【ARM-Linux开发】Linux环境下使用eclipse开发C++动态链接库程序

    Linux环境下使用eclipse开发C++动态链接库程序 Linux中也有类似windows中DLL的变成方法,只不过名称不同而已.在Linux中,动态链接叫做Standard Object,生成的 ...

  8. Linux环境下部署完JDK后运行一个简单的Java程序

    前言 前一篇文章详细讲解了如何在Windows环境下安装虚拟机+Linux系统,并且成功部署了JDK. 不过部署完JDK之后,我们判断部署是否成功的依据是看"java -version&qu ...

  9. 针对 Linux 环境下 gdb 动态调试获取的局部变量地址与直接运行程序时不一致问题的解决方案

    基础的缓冲区溢出实践通常需要确定运行状态下程序中的某些局部变量的地址,如需要确定输入缓冲区的起始地址从而获得注入缓冲区中的机器指令的起始地址等.在 Linux 环境下,可通过 gdb 对程序进行动态调 ...

  10. linux环境下学习使用pro*c/c++工具

    1.proc是oracle用来预编译嵌入SQL语句的c程序. 2.如何使用proc工具 在Linux环境下,首先确保gcc编译器正常使用,安装oracle数据库或者客户端,一般就会默认安装pro*c/ ...

随机推荐

  1. Spring反序列化JNDI分析

    漏洞原理 Spring框架的JtaTransactionManager类中重写了readObject方法,这个方法最终会调用到JNDI中的lookup()方法,关键是里面的参数可控,这就导致了攻击者可 ...

  2. 51nod 1268

    51nod 1268 基础dfs 题目如下: 给出 N 个正整数组成的数组 A,求能否从中选出若干个,使他们的和 为 K.如果可以,输出:"Yes",否则输出"No&qu ...

  3. CentOS9 \ Centos8安装MySQL 8步骤

    centos8 rpm 安装mysql8.0.28_太阳神LoveU的博客-CSDN博客 This upper link is still working for mysql 8 on the Cen ...

  4. button submit你以为你阻止了默认事件?

    前言 先解决掉一个误区: 很多人写button的时候,就这样写: <button><botton> 你认为就是默认的submit的时候,这时候就可能出问题了. 当然之所以你没有 ...

  5. @SpringBootConfiguration注解

    @SpringBootConfiguration继承自@Configuration,二者功能也一致,标注当前类是配置类, 并会将当前类内声明的一个或多个以@Bean注解标记的方法的实例纳入到sprin ...

  6. textfsm 案例分享

    由于安全需要,需要定期对接入层交换机配置进行合规检查,避免不规范配置存在的漏洞给公司网络带来安全风险. 如下案例是通过textfsm 提取交换机接口的配置信息,进一步进行检查准入配置是否开启: 1.首 ...

  7. Quick Audience 营销活动功能一期上线

    ​简介: 营销活动为Quick Audience(QA)用户洞察下的一个功能模块,通过这个模块,可以将QA侧生成的受众以及营销渠道全部关联起来,从营销活动的视角,一站式完成活动目标制定.活动计划制定到 ...

  8. 项目实战总结以及接入U-APM

    ​简介: 导致 App 性能低下的原因有很多,除去设备硬件和软件的外部因素,其中大部分是开发者错误地使用线.系统函数.编程范式.数据结构等导致的.即便是较有经验的程序员,也很难在开发时就能避免所有导致 ...

  9. [PHP] 小数转科学计数法, 小数保留 n 位

    使用sprintf / printf 的 %e 或%E 格式说明符将其转换为科学计数法. 使用精度控制符指定保留多少位. 例如:sprintf('%.4e', 0.00000123); Link:ht ...

  10. [FAQ] Error: com.mysql.jdbc.Driver not loaded. :jdbc_driver_library

    以上问题出现在 logstash.conf 未配置好 MySQL 的 JDBC 驱动时导致的错误提示. 首先,下载好 MySQL JDBC 驱动库,可以放到 logstash.conf 所在当前目录或 ...