静态链接和动态链接的Golang二进制文件

关注TechLead,复旦博士,分享云服务领域全维度开发技术。拥有10+年互联网服务架构、AI产品研发经验、团队管理经验,复旦机器人智能实验室成员,国家级大学生赛事评审专家,发表多篇SCI核心期刊学术论文,阿里云认证的资深架构师,上亿营收AI产品研发负责人。

本文介绍了 Go 语言中静态链接和动态链接的概念,解释了它们的区别和各自优势。通过示例,展示了如何生成静态或动态链接的二进制文件,以及使用工具进行检查。文章还讨论了内部和外部链接器的区别,如何在编译时选择链接方式,以及在交叉编译时处理 cgo 的方法。最后,提到了减小二进制文件大小的技巧和安全性方面的考虑。

file

概述

Go 语言最大的优势之一就是它的编译器,它为程序员抽象了许多细节,让你可以轻松地为几乎任何平台和架构 https://pkg.go.dev/cmd/dist 编译你的程序。

尽管这看起来很简单,但其中有一些细微的差别,同一个程序有多种编译方式,这会导致生成不同的可执行文件。

在本文中,我们将探讨静态链接和动态链接的可执行文件、内部和外部链接器,并使用 fileldldd 等工具检查二进制文件。

什么是静态链接和动态链接?

静态链接是将程序所需的所有库直接复制到最终可执行文件中的做法。

Go 语言非常喜欢并希望在可能的情况下这样做,因为这样生成的二进制文件更加便携,不需要在运行的主机系统上存在库。因此,你的二进制文件可以在任何系统上运行,无论是哪个发行版或版本,而且不依赖任何系统库。

另一方面,动态链接是在运行时按名称将外部或共享库加载到可执行文件中。

动态链接也有其自身的优势。例如,程序可以重用主机系统上可用的常用 libc 库,而不需要重新实现它们,你还可以在不重新链接程序的情况下受益于主机的更新。在许多情况下,它还可以减小可执行文件的大小。

静态链接的程序

让我们来看一个始终进行静态链接的程序。这个程序没有使用 cgo 调用 C 代码,因此所有内容都可以打包在一个静态二进制文件中。

package mainimport "fmt"func main() {fmt.Println("Hello, World!")
}

什么是二进制文件?

我们可以使用 file 命令首先检查文件类型。

file

它告诉我们这是一个 ELF(可执行和可链接格式)可执行文件,并且是“静态链接”的。

我们不会深入讨论 ELF 是什么,但需要知道的是还有其他可执行文件格式。ELF 是 Linux 上的默认格式,Mach-O 是 macOS 的默认格式,PE/PE32+ 是 Windows 的默认格式,等等。

注意:在本文中,我们将使用 Linux(Ubuntu)及其工具,然而在其他平台上也可以进行类似的操作。

还有一个 Linux 程序 ldd,可以告诉我们二进制文件是静态链接还是动态链接的。

$ ldd mainnot a dynamic executable

动态链接的程序

如前所述,Go 有一个机制叫 cgo,可以从 Go 调用 C 代码,甚至 Go 的标准库在多个地方使用了它。例如,在 net 包中,它使用标准的 C 库来处理 DNS。

默认情况下,导入此类包或在代码中使用 cgo 会生成一个动态链接的二进制文件,链接到那些 libc 库。

file

我们可以再次使用 fileldd 程序来检查第二个二进制文件。

file

file 命令现在显示这是一个动态链接的二进制文件,而 ldd 则显示了二进制文件的动态依赖关系。在这种情况下,它依赖于 libc.so.6ld-linux,后者是 Linux 系统的动态链接器。

我们可以让它静态链接吗?

当你希望二进制文件静态链接时,可能有多种原因,但主要原因是为了简化部署和分发。然而,并不总是有必要这样做。通过链接 libc,你可以从主机更新中受益,并且在使用 net 包的情况下,可以利用 libc 中包含的复杂的 DNS 查找函数。

有趣的是,Go 的 net 包也有一个纯 Go 版本,这使得在编译时禁用 cgo 成为可能。你可以通过指定构建标签或使用 CGO_ENABLED=0 完全禁用 cgo 来实现。

file

上面的截图证明在这两种情况下,我们最终都得到了一个静态二进制文件。

内部链接器 vs 外部链接器

链接器是一个程序,它读取 main 包的 Go 存档或对象,以及它的依赖项,并将它们组合成一个可执行的二进制文件。

默认情况下,Go 的工具链使用其内部链接器(go tool link),但是你可以在编译时指定使用哪个链接器,这样可以让我们在获得静态二进制文件的同时,享受完整的 libc 功能。

在 Linux 上,默认的外部链接器是 gcc 的 ld。我们可以告诉它生成一个静态二进制文件。

file

它能工作,但我们会收到一个警告。在我们的例子中,glibc 使用 libnss 来支持多种地址解析服务提供者,而你无法静态链接 libnss。

其他使用 cgo 的包可能会产生类似的警告,你需要查看文档来判断它们是否严重。

交叉编译

如介绍中所述,交叉编译是 Go 的一个非常好的特性,它允许你为几乎任何平台/架构编译程序。然而,如果你的程序使用了 cgo,这可能会非常棘手,因为交叉编译 C 代码通常很困难。

file

你可以通过为目标操作系统和/或架构安装工具链来解决这个问题。

如果可能,最好在交叉编译时不要使用 cgo。你将得到静态链接的稳定二进制文件。

加分项:减小二进制文件大小

你可能注意到,上面 file 命令的输出包含:“not stripped”。这意味着我们的二进制文件中包含调试信息。但我们通常不需要它,删除它可以减小二进制文件的大小。

file

这将删除调试信息和符号表,减小二进制文件的大小。

当心:LD_PRELOAD 技巧

Linux 系统程序 ld-linux.so(动态链接器/加载器)使用 LD_PRELOAD 来加载指定的共享库。特别是,在加载任何其他库之前,动态加载器将首先加载 LD_PRELOAD 中的共享库。

LD_PRELOAD 技巧是在动态链接的二进制文件中使用的一种强大技术,用于覆盖或拦截对共享库的函数调用。

通过将 LD_PRELOAD 环境变量设置为指向自定义的共享对象文件,用户可以将自己的代码注入程序的执行中,从而有效地替换或增强现有的库函数。

这种方法允许各种应用,例如调试、测试,甚至在不修改原始源代码的情况下改变程序行为。

file

这也表明静态链接的二进制文件更安全,因为它们不存在这个问题,因为它们不依赖任何外部库。此外,还有一个“安全执行模式”——这是由 Linux 系统上的动态链接器实现的安全特性,用于在运行需要提升权限的程序时限制某些行为。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1543170.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

抖音截流神器发布:不限量评论采集,实时推送,提升运营效率

在短视频风靡的今天,抖音成为品牌营销的新战场。如何在海量内容中脱颖而出,提升运营效率成为关键。本文将揭秘一款革命性的抖音运营工具,它不仅支持不限量评论采集,还实现了实时推送功能,助力运营者精准把握用户反馈&a…

保姆级 Stable Diffusion 教程,看完这篇就够了!

在美国科罗拉多州举办了一场新兴数字艺术家竞赛,一幅名为《太空歌剧院》的作品获得“数字艺术/数字修饰照片”类别的一等奖,神奇的是,该作品的作者并没有绘画基础,这幅画是他用 AI 生成的。 这让人们充分见识到AI 在绘画领域惊人的…

Shell实战(一)

Shell实战(一) 导语程序实例解压缩交互功能描述代码和运行结果实现解析 监视CPU和内存功能描述代码和运行结果实现解析 用户管理功能描述代码和运行结果实现解析 总结 导语 本篇引入三个书上的shell程序设计项目,由于书上的版本较老&#xf…

异构AI算力资源池:智能世界的新型基础设施

随着人工智能技术的飞速发展,AI应用对计算资源的需求日益增长。然而,传统的同构计算资源池无法满足AI应用对计算能力、能耗和成本的多样化需求。为此,异构AI算力资源池应运而生,成为未来智能世界的重要基础设施。 背 景 人工智能…

H3C交换机手动释放DHCP地址

原本的的配置,释放时间10天 导致所有的地址都被使用完 释放了地址池的地址 重新调整了超期时间为8小时

游戏行业数据集成“利器”

《黑神话:悟空》自公布以来,便在游戏界引起了巨大的轰动。这款游戏以其精湛的画面、精彩的剧情和深度的玩法,让无数玩家充满期待。而在其背后,游戏开发者们面临着诸多挑战,其中之一便是数据的集成与管理。竞争激烈的游…

【C++ Primer Plus习题】17.3

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: #include <iostream> #include <fstream> using namesp…

LeetCode Hot100 C++ 哈希 49.字母异位词分组

给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排…

2-99 基于matlab多尺度形态学提取眼前节组织

基于matlab多尺度形态学提取眼前节组织&#xff0c;通过应用不同尺度的结构元素进行边缘检测&#xff0c;再通过加权融合的思想来整合检测到的边缘&#xff0c;降低图像噪声的影响&#xff0c;提高边缘检测的精度。程序已调通&#xff0c;可直接运行。 下载源程序请点链接&…

线程的状态及join()插队方法

一、线程的状态 线程整个生命周期中有6种状态&#xff0c;分别为 NEW 新建状态 、RUNNABLE 可运行状态、TERMINATED 终止状态、TIMED_WAITING计时等待状态、WAITING 等待状态、BLOCKED 阻塞状态 线程各个状态之间的转换&#xff1a; 在 JAVA 程序中&#xff0c;一个线程对象通过…

200Kg大载重多旋翼无人机应用前景详解

大载重多旋翼无人机是一类具备高载重能力和长航时特点的无人机系统&#xff0c;它们融合了多旋翼无人机的灵活性与大载重无人机的实用性&#xff0c;广泛应用于多个领域。 1. 航拍与影视制作 在航拍与影视制作领域&#xff0c;200Kg大载重多旋翼无人机凭借其出色的稳定性和载重…

维信诺三年半亏损近85亿:股价今年跌超四成,550亿大手笔投资8.6代

《港湾商业观察》施子夫 在显示面板领域知名度颇高的维信诺&#xff08;002387.SZ&#xff09;还是交出了持续亏损的半年报。从近些年财务数据上看&#xff0c;亏损似乎已经成为了公司甩不掉的包袱。 在盈利能力并不如预期的情况下&#xff0c;维信诺也对外释放要550亿扩产能…

图片切换示例【JavaScript】

在 JavaScript 中实现图片切换可以通过多种方法&#xff0c;下面是一个简单的示例&#xff0c;使用 HTML、CSS 和 JavaScript 来实现图片的切换效果。 实现效果&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html lang"zh"><head><meta c…

单相电多相电

目录 1. 单相电 2. 多相电 3. 其他多相电系统 单相电和多相电是电力系统中常见的两种供电方式&#xff0c;主要区别在于电力传输的相数。以下分别介绍它们的基本概念、特征、以及应用场景。 1. 单相电 定义&#xff1a; 单相电指的是只有一根火线和一根零线的电力系统。这…

电玩店ps5倒计时软件试用版下载 佳易王电玩计时计费管理系统操作教程

一、前言 电玩店ps5倒计时软件试用版下载 佳易王电玩计时计费管理系统操作教程 佳易王电玩店计时计费软件&#xff0c;有两款&#xff0c;其中一款可显示倒计时剩余分钟数&#xff0c;另外一款是显示用了多长时间&#xff0c;都可以设置定时语音提醒。 二、显示倒计时软件图文…

python之装饰器、生成器

装饰器 什么是装饰器&#xff1f; 用来装饰其他函数&#xff0c;即为其他函数添加特定功能的函数。 装饰器的两个基本原则&#xff1a; 装饰器不能修改被装饰函数的源码 装饰器不能修改被装饰函数的调用方式

css禁止图片保存,CSS中的图片保存方法

“css中的图片”指的就是镶在CSS样式表中的图片。在我们用在浏览器保存网页时&#xff0c;很多时候&#xff0c;下载网页里的图片都下载不到&#xff0c;这样的话就会使网页非常不美观。所以&#xff0c;今天小编就给大家介绍集中保存方法。 以下是几种保存方法。 (一)使用网…

互联网产品经理在 AIGC 时代的升级攻略

在当今科技飞速发展的浪潮中&#xff0c;AIGC&#xff08;人工智能生成内容&#xff09;正以前所未有的速度改变着互联网的格局。对于互联网产品经理而言&#xff0c;这既是一个充满无限可能的机遇&#xff0c;也是需要积极应对的挑战。那么&#xff0c;在 AIGC 时代&#xff0…

Vulnhub:Cybero1

靶机下载地址 主机发现 扫描攻击机同网段存活主机。 nmap 192.168.31.0/24 -Pn -T4 靶机ip&#xff1a;192.168.31.118 端口扫描 nmap 192.168.31.118 -A -p- -T4 开放端口&#xff1a;21(ftp)、22(ssh)、80(http)、8085(http)。 HTTP信息收集 80 访问http://192.168.3…

毫米波雷达预警功能 —— 倒车预警(RCTA)

文档声明&#xff1a; 以下资料均属于本人在学习过程中产出的学习笔记&#xff0c;如果错误或者遗漏之处&#xff0c;请多多指正。并且该文档在后期会随着学习的深入不断补充完善。感谢各位的参考查看。 笔记资料仅供学习交流使用&#xff0c;转载请标明出处&#xff0c;谢谢配…