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

而动态库链接库是在程序运行时才被链接的,所以磁盘上只要保留一份副本,因此节约了磁盘空间。如果发现了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. #trie,动态规划#洛谷 2292 [HNOI2004]L语言

    题目 分析 建一棵trie,然后匹配最长前缀可以用\(dp\)做, 如果这个位置可以被匹配到那么可以从这个位置继续匹配 代码 #include <cstdio> #include < ...

  2. 使用OHOS SDK构建tinyexr

    参照OHOS IDE和SDK的安装方法配置好开发环境. 从github下载源码. 执行如下命令: git clone https://github.com/syoyo/tinyexr.git 进入源码 ...

  3. 技术传递温度,HMS Core手语服务走进暖心课堂

    近日,华为HMS Core手语服务携手吉林大学.长春大学特教学院联合打造暖心课堂,在直播网课中加入AI手语翻译,于人文中融入科技,知识中融入温暖. 手语翻译:同学们大家好 HMS Core手语服务通过 ...

  4. 一文告诉你商业智能BI如何推动推动智慧物流发展

    随着网络消费的不断发展,推动了物流等相关产业的迅速发展,另外无论是2B业务还是2C业务的生产制造企业,对物流的要求都越来越高,尤其体现在对物流全程透明可视化的需求.商业智能BI平台的引入,大大提高了物 ...

  5. Qt线程简单使用一:QThread~创建线程类子类

      需求: 点击QPushButton按钮,QLabel中的数字,不断累加,一直到999.   做法: 点击QPushButton后,启动线程,线程while循环,不断发送累加的数字回主线程,修改QL ...

  6. IDEA快捷键快速补齐类和对象名

    CTRL+ALT+V  ----------快速补齐 类和对象名 如:   new String("123") 光标放到最后 按下快捷键补齐为红色部分  String s = ne ...

  7. 史上最全的中高级JAVA工程师-面试题汇总

    史上最全的中高级JAVA工程师-面试题汇总 置顶 2019-10-15 18:58:32 Jeff.Smile 阅读数 34460更多 分类专栏: # 随笔 版权声明:本文为博主原创文章,遵循CC 4 ...

  8. Web前端 -- 利用Babel来将ES6转化为ES5代码

    一.简介 Babel用来将ES6代码转为ES5代码. 二.安装 安装命令行转码工具 Babel提供babel-cli工具,用于命令行转码.它的安装命令如下: npm install --global ...

  9. CF1933D Turtle Tenacity: Continual Mods

    思路: 此题其实很简单,不要被邪恶的出题人迷惑了双眼. 此题判断有解一共有两种情况. 通过题意可以知道将原数组排序后如果 \(b_{1} \ne b_{2}\),那么最后的结果一定 \(\ne 0\) ...

  10. wordcloud 词云Python

    from wordcloud import WordCloud import matplotlib.pyplot as plt def get_word_cloud(words_list): #首先实 ...