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最低要求也没用……