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

而动态库链接库是在程序运行时才被链接的,所以磁盘上只要保留一份副本,因此节约了磁盘空间。如果发现了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. [Android开发学iOS系列] 删除storyboard需要几步

    删除iOS项目中的storyboard 删除项目中的storyboard, (变成一个纯代码的iOS UIKit项目), 需要几步? 找到storyboard, 删掉它. 直接用ViewControl ...

  2. #莫比乌斯反演,杜教筛#洛谷 6055 [RC-02] GCD

    题目 分析 如果令 \(u=pj,v=qj\) ,那么本质上就是让 \(gcd(i,u,v)==1\) 那就是 \(\sum_{i=1}^n\sum_{u=1}^n\sum_{v=1}^n[gcd(i ...

  3. #贪心,二叉堆#洛谷 1954 [NOI2010] 航空管制

    题目 分析 首先考虑可行方案,很容易想到拓扑排序, 但是如果建正图第一类的限制有可能不能满足, 考虑第一类限制其实时间倒流就是在 \(T\) 时刻之后才能选它. 那么直接建反图然后 \(a_i\) 大 ...

  4. #模拟#洛谷 5957 [POI2017]Flappy Bird

    题目 分析 小鸟所在坐标的奇偶性一定相同, 考虑每次维护一个可行区间表示小鸟在当前列可以进入的纵坐标区间, 那么它有\(x_i-x_{i-1}\)的纵坐标最大改变差,然后根据奇偶性以及限制区间缩小范围 ...

  5. 如何打造3D立体世界?跟随图片一同探寻

    怎样让平面的手机,呈现出炫酷的三维立体世界效果?虚拟与现实又要怎样完美结合? HMS Core图形等领域能力全面开放,使能3D数字世界创新.请跟随图片一起进入HMS Core打造的3D立体世界吧. 了 ...

  6. 运动App如何实现端侧后台保活,让运动记录更完整?

    你在锻炼健身时,有没有遇到这样的情况?辛辛苦苦锻炼了几小时,却发现App停止了运行,本次运动并没有被记录到App上,从而失去了一个查看完整运动数据的机会? 运动类App是通过手机或者穿戴设备的传感器, ...

  7. 开发指导—利用CSS动画实现HarmonyOS动效(一)

     注:本文内容分享转载自HarmonyOS Developer官网文档 一. CSS语法参考 CSS是描述HML页面结构的样式语言.所有组件均存在系统默认样式,也可在页面CSS样式文件中对组件.页面自 ...

  8. spring boot 学习前提

    前言 总结spring boot的学习前提. 正文 1.spring 程度(可以基本使用,我在学习spring boot的时候,感觉到需要一些spring的基础) 2.maven (这个是包管理,一定 ...

  9. redis 简单整理——客户端案例分析[十八]

    前言 简单整理一下客户端案例分析. 正文 现象一: 服务端现象:Redis主节点内存陡增,几乎用满maxmemory,而从节点 内存并没有变化. 客户端现象:客户端产生了OOM异常,也就是Redis主 ...

  10. redis 简单整理——java 客户端jedis[十六]

    前言 简单介绍一下java客户端jedis. 正文 Java有很多优秀的Redis客户端(详见:http://redis.io/clients#java),这 里介绍使用较为广泛的客户端Jedis,本 ...