Linux动态链接库加载顺序

突然想到以前遇到的一个问题,动态链接库加载的问题。如果有多个动态链接库里面都有相同符号的函数,程序在执行时会优先执行那个动态链接库中的函数呢?

 

先给结论

动态链接库加载顺序:

1.可执行档同目录下的动态链接库;

2.编译时指定的动态链接库位置;

3.运行可执行档前使用LD_LIBRARY_PATH指定的动态链接库位置;

4./etc/ld.so.conf中指定的动态链接库位置;

5./lib中的动态链接库

6./usr/lib中的动态链接库

 

实验用到的源文件、头文件和CMakeList

hello.h

#ifndef __HELLO_H__

#define __HELLO_H__

 

void hello(void);

 

#endif

hello1.c

#include "hello.h"

#include <stdio.h>

 

void hello(void)

{

printf("This is hello 1!\n");

}

hello2.c

#include "hello.h"

#include <stdio.h>

 

void hello(void)

{

printf("This is hello 1!\n");

}

main.c

#include "hello.h"

#include <stdio.h>

 

void main(void)

{

hello();

}

CMakeList.txt

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)

 

GET_FILENAME_COMPONENT(ROOT_PATH ${CMAKE_SOURCE_DIR}/ REALPATH)

 

PROJECT (HELLO)

SET(SRC_LIST main.c)

SET(DYNAMIC_LIST1 hello1.c)

SET(DYNAMIC_LIST2 hello2.c)

 

INCLUDE_DIRECTORIES(${ROOT_PATH})

 

ADD_LIBRARY(hello1 SHARED ${DYNAMIC_LIST1})

ADD_LIBRARY(hello2 SHARED ${DYNAMIC_LIST2})

 

LINK_DIRECTORIES(${ROOT_PATH}/build/lib)

LINK_DIRECTORIES(${ROOT_PATH}/build/libs)

 

ADD_EXECUTABLE(main ${SRC_LIST})

 

TARGET_LINK_LIBRARIES(main hello1)

 

实验一:编译时不指定动态链接库位置

 

编译后直接运行输出:This is hello 1!

交换libhello1.solibhello2.so,运行输出:This is hello 2!

test1.log

 

实验二:编译时指定动态链接库位置

 

libhello1.solibhello2.so分别放在liblibs文件夹中并都改名为libhello1.so,运行发现

LINK_DIRECTORIES(lib)/LINK_DIRECTORIES(libs)的顺序会影响选择动态链接库的顺序,优先加载排在前面的动态链接库。

test2.log

 

实验三:编译时不指定动态链接库位置,运行前用LD_LIBRARY_PATH指定

 

libhello1.solibhello2.so分别放在liblibs文件夹中并都改名为libhello1.so(并作交换),运行发现优先加载最早填入LD_LIBRARY_PATH

test3.log

 

实验四:编译时指定动态链接库位置,运行前用LD_LIBRARY_PATH指定

 

libhello1.solibhello2.so分别放在liblibs文件夹中并都改名为libhello1.so(并作交换),再加入LD_LIBRARY_PATH,发现优先加载编译程序时指定的动态链接库,找不到再加载LD_LIBRARY_PATH中的动态链接库

 

test4.log

 

实验五:编译时指定动态链接库位置,但是执行档目录下有同名动态链接库

 

优先加载执行档同名路径下的动态链接库

 

test5.log

 

查看编译时是否指定动态链接库位置

$readelf -d main

l 编译时没有指定动态链接库位置

yangfan@ubuntu:~/Workspace/CMake_dynamic/build$ readelf -d main 

 

Dynamic section at offset 0xe08 contains 26 entries:

  Tag        Type                         Name/Value

 0x0000000000000001 (NEEDED)             Shared library: [libhello1.so]

 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

 0x000000000000000f (RPATH)              Library rpath: [/home/yangfan/Workspace/CMake_dynamic/build]

l 编译时指定动态链接库位置

yangfan@ubuntu:~/Workspace/CMake_dynamic/build$ readelf -d main 

 

Dynamic section at offset 0xe08 contains 26 entries:

  Tag        Type                         Name/Value

 0x0000000000000001 (NEEDED)             Shared library: [libhello1.so]

 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

 0x000000000000000f (RPATH)              Library rpath: [/home/yangfan/Workspace/CMake_dynamic/build/lib:/home/yangfan/Workspace/CMake_dynamic/build]

编译时指定动态链接库位置的话Library rpath一般会有多于一个的路径

查看程序将会加载哪个动态链接库

$ldd main

 

yangfan@ubuntu:~/Workspace/CMake_dynamic$ ldd main

linux-vdso.so.1 =>  (0x00007fff1aff6000)

libhello1.so => /home/yangfan/Workspace/CMake_dynamic/build/libhello1.so (0x00007f2f03e38000)

libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2f03a50000)

/lib64/ld-linux-x86-64.so.2 (0x000055d2cfdfa000)

 

转载于:https://www.cnblogs.com/FanZZ/p/6658659.html