Files
build_infra/0_笔记/linux添加环境变量.txt
T
2026-06-16 10:23:51 +08:00

42 lines
3.5 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
echo $PATH
which perf
nano ~/.bashrc == nano /home/wyc/.bashrc
export PATH="/usr/bin/:$PATH"
LD_LIBRARY_PATH
作用:LD_LIBRARY_PATH 用于指定动态链接库的搜索路径。在运行一个可执行文件时,Linux 系统会根据这个环境变量来查找程序所需的共享库。系统首先会在这个路径中查找,如果没有找到,再去默认的库路径(如 /lib 和 /usr/lib)查找。
优先加载:如果 LD_LIBRARY_PATH 中指定了多个路径,系统会按照它们的顺序逐个查找。因此,你可以通过调整这个变量来控制库的加载顺序,确保优先使用特定的版本。
用途:
多版本支持:允许同一程序使用不同版本的库。
自定义路径:在非标准目录中查找库文件。
LD_PRELOAD
作用:LD_PRELOAD 用于强制加载指定的共享库,即使该库不在程序的默认依赖中。它会在程序启动时优先加载你指定的库,覆盖系统中已有的相同函数。
功能替换:如果你在 LD_PRELOAD 中指定了一个库,并且这个库中实现了某些与标准库同名的函数(如 malloc 或 printf),程序将使用你提供的版本,而不是系统库中的版本。
用途:
功能扩展:在不修改程序代码的情况下,添加或替换某些功能。
调试和分析:允许开发人员监控和调试程序的函数调用。
性能优化:可以替换标准函数实现,以改善性能。
为什么需要 LD_PRELOAD
虽然 LD_LIBRARY_PATH 可以影响库的加载顺序,但它并不能直接替换或修改库中已存在的函数实现。以下是几个使用 LD_PRELOAD 的场景,进一步阐明其必要性:
函数覆盖:如果你想替换标准库函数(如 malloc、free、printf)的实现,你需要使用 LD_PRELOAD。LD_LIBRARY_PATH 只能指定库的搜索路径,但无法改变函数的具体实现。
动态注入:LD_PRELOAD 允许你在运行时将自定义的功能动态地注入到程序中。这对于调试和测试非常有用,例如你可以追踪内存分配或函数调用的次数。
临时性和灵活性:通过 LD_PRELOAD,你可以在不需要重新编译或修改程序的情况下,快速改变程序的行为。这种灵活性在开发和调试过程中非常重要。
小结
LD_LIBRARY_PATH:改变库的查找路径,以确保优先加载特定路径下的库文件。
LD_PRELOAD:在程序启动时强制加载指定的库,优先于其他库中的函数实现,从而实现功能的覆盖或注入。
一个很大的缺点是,不同发行版之间,同一发行版的不同版本之间,二进制常常不兼容。而导致这个问题的一个很大原因是,
几乎所有的 Linux 发行版都不允许在系统上同时存在多个版本的 glibc,就算允许,也必须通过 LD_LIBRARY_PATH 或 LD_PRELOAD 等方式来引入。
另外可执行程序默认会链接到系统的动态库而不是当前目录下的(实际上编译的时候可以使用 -rpath),
这使得我们很难把一个软件和它的所有依赖打包成一个独立的包。而为了解决这个问题,人们又搞出了 Docker、Flatpak、Snap、AppImage 这些方案……
然而我想说的是,你们直接在编译的时候设一下 rpath 然后把 .so 全都打包进去不就行了么!实际上仅仅对 kernel 而言,二进制应该是可以兼容的。
不兼容不仅仅是库的问题, kernel的ABI兼容性也是一个问题, 即使你把glibc都一起打包, kernel太老不满足ABI最低要求也没用……