Linux程序依赖动态链接库目录管理和案例分析

Linux程序运行时查找依赖的动态链接库路径

  • 编译时指定的-rpath:如果程序在编译时使用了-Wl,-rpath,链接器选项,那么程序在运行时也会在这些指定的目录中搜索库。
  • 环境变量LD_LIBRARY_PATH指定的目录:这是一个环境变量,可以包含一系列以冒号分隔的目录路径。程序会在这些目录中搜索动态链接库。
  • 配置文件/etc/ld.so.conf/etc/ld.so.conf.d/*.conf:这些配置文件中定义的路径在LD_LIBRARY_PATH之后被搜索。ldconfig工具会读取这些文件。注意:如果新增了conf文件或内容,需要执行ldconfig命令才会生效。
  • 默认系统库目录:如果以上方法都没有找到所需的库,动态链接器会搜索系统默认的库目录,通常是/lib/usr/lib

ldd命令查看程序依赖的动态库和位置

(sdk) (python) -bash-5.1# ldd demolinux-vdso.so.1 (0x00007fff92f90000)libsum.so => /root/libt/libsum.so (0x00007f1efb4d4000)libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f1efb2db000)libm.so.6 => /usr/lib64/libm.so.6 (0x00007f1efb1ff000)libgcc_s.so.1 => /usr/lib64/libgcc_s.so.1 (0x00007f1efb1e5000)libc.so.6 => /usr/lib64/libc.so.6 (0x00007f1efafee000)/lib64/ld-linux-x86-64.so.2 (0x00007f1efb6d8000)

如果有些库查找失败会提示not found

(sdk) (python) -bash-5.1# ldd demolinux-vdso.so.1 (0x00007ffeda58e000)libsum.so => not foundlibstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007fd7da2f3000)libm.so.6 => /usr/lib64/libm.so.6 (0x00007fd7da217000)libgcc_s.so.1 => /usr/lib64/libgcc_s.so.1 (0x00007fd7da1fd000)libc.so.6 => /usr/lib64/libc.so.6 (0x00007fd7da006000)/lib64/ld-linux-x86-64.so.2 (0x00007fd7da4ee000)

查看正在运行程序依赖的环境变量

Linux 的 /proc 文件系统提供了一个接口,可以查看正在运行的进程的详细信息,包括环境变量。你可以通过读取 /proc/[PID]/environ 文件来查看指定进程 ID (PID) 的环境变量。这个文件中的环境变量以 \0(null 字符)分隔。 例如,要查看 PID 为 1234 的进程的环境变量,你可以使用以下命令,搜索LD_LIBRARY_PATH字段:

cat /proc/1234/environ

命令执行结果样例:(一长行根本不具备可视性。)

(sdk) (python) -bash-5.1# cat /proc/2841724/environ
SHELL=/bin/bashHISTCONTROL=ignoredupsHISTSIZE=1000HOSTNAME=localhostJAVA_HOME=/etc/alternatives/jre_1.8.0_openjdkJRE_HOME=/etc/alternatives/jre_1.8.0_openjdkPOCL_CACHE_DIR=/dl/.cacheorig_PS1=(python) \s-\v\$ PWD=/root/tmpLOGNAME=rootMOTD_SHOWN=pamorig_PATH=/dl/python/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/binHOME=/rootLANG=zh_CN.UTF-8VIRTUAL_ENV=/dl/pythonDLICC_PATH=/dl/sdk/binTOPHUB_LOCATION=NONECUDNN_INSTALL_DIR=/usr/local/cudaSSH_CONNECTION=10.34.6.23 61476 10.38.174.68 22PYTHONPATH=/dl/sdk/python/nne:/dl/sdk/python:/dl/sdk/python/pycuda:/dl/sdk/python/tf_graph_transformer/python:/dl/sdk/python/dl_tf_bridge/python:/dl/sdk/python/tensorflow_dlnn/python:/dl/sdk/python/tvm/python:/dl/sdk/python/tvm/dl/python:TERM=xtermCPLUS_INCLUDE_PATH=/usr/local/cuda-10.1/include/:orig_LD_LIBRARY_PATH=orig_PYTHONPATH=USER=rootenv_dlnn_ACTIVATED=1SHLVL=1CUDA_INSTALL_DIR=/usr/local/cudaDLCI_CACHE_DIR=/dl/.cache/dlciCLASSPATH=.:/etc/alternatives/jre_1.8.0_openjdk/lib/dt.jar:/etc/alternatives/jre_1.8.0_openjdk/lib/tools.jar:/etc/alternatives/jre_1.8.0_openjdk/libLD_LIBRARY_PATH=/root/libt/PS1=(sdk) (python) \s-\v\$ SSH_CLIENT=10.34.6.23 61476 22LD_LIBARY_PATH=/root/libt/PATH=/dl/sdk/bin:/dl/python/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/etc/alternatives/jre_1.8.0_openjdk/bin:/etc/alternatives/jre_1.8.0_openjdk/bin:/usr/bin/flashupdt:/root/binMAIL=/var/spool/mail/rootSSH_TTY=/dev/pts/5OLDPWD=/root_=./demo

所以,为了更易于阅读,你可以使用 tr命令将 null 字符替换为换行符,快速找到LD_LIBRARY_PATH字段:

cat /proc/1234/environ | tr '\0' '\n'

命令执行结果样例:

(sdk) (python) -bash-5.1# cat /proc/2841724/environ | tr '\0' '\n'
SHELL=/bin/bash
HISTCONTROL=ignoredups
HISTSIZE=1000
HOSTNAME=localhost
JAVA_HOME=/etc/alternatives/jre_1.8.0_openjdk
JRE_HOME=/etc/alternatives/jre_1.8.0_openjdk
POCL_CACHE_DIR=/dl/.cache
orig_PS1=(python) \s-\v\$
PWD=/root/tmp
LOGNAME=root
MOTD_SHOWN=pam
orig_PATH=/dl/python/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
HOME=/root
LANG=zh_CN.UTF-8
VIRTUAL_ENV=/dl/python
DLICC_PATH=/dl/sdk/bin
TOPHUB_LOCATION=NONE
CUDNN_INSTALL_DIR=/usr/local/cuda
SSH_CONNECTION=10.34.6.23 61476 10.38.174.68 22
PYTHONPATH=/dl/sdk/python/nne:/dl/sdk/python:/dl/sdk/python/pycuda:/dl/sdk/python/tf_graph_transformer/python:/dl/sdk/python/dl_tf_bridge/python:/dl/sdk/python/tensorflow_dlnn/python:/dl/sdk/python/tvm/python:/dl/sdk/python/tvm/dl/python:
TERM=xterm
CPLUS_INCLUDE_PATH=/usr/local/cuda-10.1/include/:
orig_LD_LIBRARY_PATH=
orig_PYTHONPATH=
USER=root
env_dlnn_ACTIVATED=1
SHLVL=1
CUDA_INSTALL_DIR=/usr/local/cuda
DLCI_CACHE_DIR=/dl/.cache/dlci
CLASSPATH=.:/etc/alternatives/jre_1.8.0_openjdk/lib/dt.jar:/etc/alternatives/jre_1.8.0_openjdk/lib/tools.jar:/etc/alternatives/jre_1.8.0_openjdk/lib
LD_LIBRARY_PATH=/root/libt/
PS1=(sdk) (python) \s-\v\$
SSH_CLIENT=10.34.6.23 61476 22
LD_LIBARY_PATH=/root/libt/
PATH=/dl/sdk/bin:/dl/python/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/etc/alternatives/jre_1.8.0_openjdk/bin:/etc/alternatives/jre_1.8.0_openjdk/bin:/usr/bin/flashupdt:/root/bin
MAIL=/var/spool/mail/root
SSH_TTY=/dev/pts/5
OLDPWD=/root
_=./demo

demo示例

demo程序位置:/root/tmp/demo

libsum.so库位置:/root/libt/libsum.so

设置环境变量前执行程序,报错提示找不到库:

(sdk) (python) -bash-5.1# ./demo
./demo: error while loading shared libraries: libsum.so: cannot open shared object file: No such file or directory

通过命令ldd查看依赖库信息:

(sdk) (python) -bash-5.1# ldd demolinux-vdso.so.1 (0x00007ffe291dd000)libsum.so => not foundlibstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007fd02ff4c000)libm.so.6 => /usr/lib64/libm.so.6 (0x00007fd02fe70000)libgcc_s.so.1 => /usr/lib64/libgcc_s.so.1 (0x00007fd02fe56000)libc.so.6 => /usr/lib64/libc.so.6 (0x00007fd02fc5f000)/lib64/ld-linux-x86-64.so.2 (0x00007fd030147000)

解决方案

  1. 手动export环境变量:export LD_LIBRARY_PATH=/root/libt/
  2. demo编译命令-Wl,-rpath加上库目录:-Wl,-rpath=/root/libt/
  3. 配置文件/etc/ld.so.conf和/etc/ld.so.conf.d/*.conf新增目录:在/etc/ld.so.conf文件新增一行:/root/libt/,或者,在/etc/ld.so.conf.d/新增一个.conf文件,文件内容新增一行:/root/libt/
  4. 将依赖库libsum.so拷贝至系统默认目录/lib/:cp /root/libt/libsum.so /lib/

注意:1方法只对当前会话有效,每次程序启动前都需要设置,3和4方法设置后需要执行ldconfig命令才会生效。

通过以上任何一种方法设置成功后,ldd查看程序链接信息正常,程序启动正常。

(sdk) (python) -bash-5.1# export LD_LIBRARY_PATH=/root/libt/
(sdk) (python) -bash-5.1# ./demo
The sum is: 8
(sdk) (python) -bash-5.1#
(sdk) (python) -bash-5.1#
(sdk) (python) -bash-5.1# ldd demolinux-vdso.so.1 (0x00007fff54b6a000)libsum.so => /root/libt/libsum.so (0x00007fa6085c1000)libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007fa6083c8000)libm.so.6 => /usr/lib64/libm.so.6 (0x00007fa6082ec000)libgcc_s.so.1 => /usr/lib64/libgcc_s.so.1 (0x00007fa6082d2000)libc.so.6 => /usr/lib64/libc.so.6 (0x00007fa6080db000)/lib64/ld-linux-x86-64.so.2 (0x00007fa6087c5000)

demo源码

//sum.h
#ifndef SUM_H
#define SUM_Hextern "C" int add(int a, int b);#endif // SUM_H
//sum.cpp
#include "sum.h"extern "C" int add(int a, int b) {return a + b;
}
//main.cpp
#include <iostream>
#include "sum.h"int main() {int result = add(5, 3);std::cout << "The sum is: " << result << std::endl;int n;std::cin >> n;return 0;
}
#Makefile
CC=g++
CFLAGS=-c -fPIC
LDFLAGS=-shared
OBJ=sum.o
LIB=libsum.soall: $(LIB)$(LIB): $(OBJ)$(CC) $(LDFLAGS) -o $@ $^sum.o: sum.cpp sum.h$(CC) $(CFLAGS) -o $@ sum.cppclean:rm -f $(OBJ) $(LIB)DEMO=demo
OBJ_DEMO=main.o$(DEMO): $(OBJ_DEMO) $(LIB)$(CC) -o $@ $^ -L. -lsumclean: clean-democlean-demo:rm -f $(OBJ_DEMO) $(DEMO)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker八大架构之应用数据分离架构

数据分离架构 什么是数据分离架构&#xff1f; 数据分离架构是指应用服务&#xff08;应用层&#xff09;和数据库服务&#xff08;数据层&#xff09;使用不同的服务器来进行操作&#xff0c;如下边的两个图所示。当访问到应用层后&#xff0c;如果需要获取数据会进行访问另…

prometheus、mysqld_exporter、node_export、Grafana安装配置

工具简介 Prometheus&#xff08;普罗米修斯&#xff09;&#xff1a;是一个开源的服务监控系统和时间序列数据库 mysqld_exporter&#xff1a; 用于监控 mysql 服务器的开源工具&#xff0c;它是由 Prometheus 社区维护的一个官方 Exporter。该工具通过连接到mysql 服务器并执…

MySQL中,关于日期类型的那些事儿,你知道哪些?

在MySQL数据库中&#xff0c;除了前面我们聊到的数字类型和字符串类型&#xff0c;还有一个常用的数据类型&#xff1a;日期类型。在我们业务表中&#xff0c;基本上每个业务表都有日期类型&#xff0c;用于记录创建时间和修改时间。比如我们的用户表&#xff0c;一般除了要记录…

Metasploit Framework渗透测试相关思考题?

1. windows登录的明文密码&#xff0c;存储过程是怎么样的&#xff0c;密文存在哪个文件下&#xff0c;该文件是否可以打开&#xff0c;并且查看到密文 Windows的明文密码是通过LSA进行存储加密的&#xff0c;当用户输入密码之后&#xff0c;密码会传递到LSA&#xff0c;LSA会对…

Linux流程控制

if语句 基本格式 if condition thencommand1 fi 写成一行 if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi if-else语句 格式 if condition thencommand1 command2...commandN elsecommand fi if else- if else if condition1 th…

OpenCV 描述子总结

1.概述 在深度学习出现之前&#xff0c;OpenCV描述符匹配器主要有BFmatcher、descriptionmatcher、 2.理论对比 3.代码实现 #include <iostream> #include <opencv2/opencv.hpp>int main(int argc, char** argv) {if(argc ! 2) {std::cerr << "Usage:…

【Java EasyExcel】自定义处理器

工具类 public class ExcelUtils {public static void setValidation(Sheet sheet, DataValidationHelper helper,DataValidationConstraint constraint,CellRangeAddressList addressList,String msgHead, String msgContext) {DataValidation dataValidation helper.create…

vue3 <script setup> 形式父子组件传值

一、父子组件传值 在Vue 3中&#xff0c;选项式api风格下父子组件传值可以通过props进行父组件向子组件传递数据&#xff0c;通过自定义事件&#xff08;$emit&#xff09;实现子组件向父组件传递数据。但是组合式api风格下有所不同。 1、父组件向子组件传值 父组件通过:par…

【pkuseg】由于网络策略组织下载请求,因此直接在github中下载细分领域模型medicine

【pkuseg】由于网络策略组织下载请求&#xff0c;因此直接在github中下载细分领域模型medicine 写在最前面解决方案pkuseg是什么&#xff1f;报错原因报错详情 &#x1f308;你好呀&#xff01;我是 是Yu欸 &#x1f30c; 2024每日百字篆刻时光&#xff0c;感谢你的陪伴与支持…

黏土滤镜制作方法:探索黏土特效制作的魅力

在数字时代&#xff0c;图像处理已经成为我们生活的一部分&#xff0c;无论是社交媒体上的照片分享&#xff0c;还是专业设计领域的创作&#xff0c;都离不开对图像的精心处理。而黏土滤镜&#xff0c;作为一种独特而富有艺术感的图像处理效果&#xff0c;受到了越来越多人的喜…

时序分解 | Matlab实现LMD局域均值分解

时序分解 | Matlab实现LMD局域均值分解 目录 时序分解 | Matlab实现LMD局域均值分解效果一览基本介绍程序设计参考资料 效果一览 基本介绍 时序分解 | Matlab实现LMD局域均值分解 Matlab语言 1.算法新颖小众&#xff0c;用的人很少&#xff0c;包含分解图 2.直接替换数据即可用…

带头单链表 C++实现

节点定义 带头单链表&#xff1a;我们只需要一个结点指针指向整个链表的第一个节点&#xff0c;这样我们就可以通过next指针访问整个链表内的所有节点 template<class T> struct ListNode {T _val;ListNode* _next;ListNode(const T &val):_val(val),_next(nullptr){…

【C++】继承(菱形继承的深入理解)

在本篇博客中&#xff0c;作者将会带领你深入的理解C中的继承。 注意&#xff01;&#xff01;&#xff01;本篇博客是在32位机器下进行讲解的&#xff0c;64位下会有所不同&#xff0c;但大同小异。 一. 继承的概念及定义 继承的概念 什么是继承&#xff1f;为什么要有继承&…

使用Android数据恢复恢复已删除的文件[Windows]

智能手机或平板电脑等 Android 设备为用户提供了发送、接收、处理和存储各种数据的能力。它提供了传统手机无法实现的多功能性和简化功能。即便如此&#xff0c;您管理存储在安卓设备中的数据的方式完全取决于您。如果您的手机出现问题&#xff0c;例如系统崩溃或操作系统更新失…

Vellum for Mac v3.7.2激活版:一键创建,轻松出版

还在为繁琐的电子书制作流程而烦恼吗&#xff1f;Vellum for Mac&#xff0c;让您的电子书创作变得轻松简单&#xff01;支持多种格式导入&#xff0c;自动构建书籍内容&#xff0c;无需担心排版和格式问题。丰富的编辑和排版功能&#xff0c;让您的书籍更加精美。一键导出多种…

Ant设计理念学习记录

1 AntV &#xff08;1&#xff09;节点展示&#xff1a; 异常/正常节点颜色区分&#xff1b;可以对节点进行归类&#xff0c;combo方式。 &#xff08;2&#xff09;节点交互&#xff1a;比如点击某个tab之后&#xff0c;当前节点可以高亮&#xff0c;并且与之关联的边也高亮…

初始JSVMP

1.初始JSVMP JSVMP是"JavaScript Virtual Machine Protection"的缩写&#xff0c;是一种前端代码虚拟化保护技术。它的核心思想是在JavaScript代码保护过程中引入代码虚拟化&#xff0c;将目标代码转换成自定义的字节码&#xff0c;这些字节码只有特殊的解释器才能识…

Linux无root配置Node,安装nvm

1. 安装NVM&#xff1a; curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash # 或者&#xff0c;如果你使用wget wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash 对于bash用户&#xff0c;可以运行&…

力扣Hot100-T8无重复字符的最长子串(经典)

&#xff08;难度&#xff1a;中等&#xff09;给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长 子串 的长度。 示例 1: 输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc"&#xff0c;所以其长度为 3。示例 2: …

k8s kubectl 常用yaml

存储挂载pvc apiVersion: v1 kind: Pod metadata:name: hw-mountnamespace: cnoc-hw-storage#namespace: project-10321 spec:# nodeSelector:# csi.storage.k8s.io/lvm: "true"# nodeName: 10-10-10-10.hw# schedulerName: lvm-schedulercontainers:- name: busybo…