当前位置:网站首页>Resolve symbol conflicts for dynamic libraries
Resolve symbol conflicts for dynamic libraries
2022-06-24 13:19:00 【Tiancun information】
once debug The doubts I met
One day I found something wrong with a program . Sacrifice print Dafa , In the key lib_func()
Add... To the function print
Debugging information , Recompile run .
expect print
There's no information out there , But the program was actually executed again libfunc()
, Because in addition to the added debugging print
No implementation ,libfunc()
All the functions are performed . It's strange .
Programs don't cheat . Executive libfunc()
It's definitely not the one we revised libfunc()
, There must be an original somewhere else lib_func()
Carried out . An investigation , Right enough . For the sake of illustration , Simplify the procedures and phenomena as follows :
The program contains the following code file ——
main.c # The main program plugin.c # Plugins lib.c lib.h # A library
Makefile as follows :
all:main plugin main: cc -o main main.c lib.c -ldl -rdynamic plugin: cc -shared -fPIC -o plugin.so plugin.c lib.c
After compiling , Generate executable main, And dynamic library files plugin.so
. When the main program is running , The plug-in will be loaded dynamically plugin.so
( Called lib.c
The procedure in ) And implement .
The suspected problem lies in lib.c in . The modified lib.c The contents are as follows , Added debug word .
void lib_func() { // fprintf(stderr, "%s()\n", __func__); fprintf(stderr, "debug:%s()\n", __func__); }
Because the main program is OK , Just recompile plugin.so
, Rerun .
Expect to get print The result is debug:libfunc()
, The actual result is libfunc()
.
look , There are two in one program lib_func()
Code . from Makefile It can be seen that , One in main In the program , One in plugin.so in . What actually works is main The one in the bag .
It suddenly became interesting : If a program contains multiple identical functions , Which one is actually executed ?
TIPS: Easy to use linux The order of nm < Program files > Look at the functions in the program
Dynamic libraries and symbol tables
Although the procedures are different , But there are always some features that are common . It's not cost-effective for every program to write code for them , So it became a library , Sharing between multiple programs . One library can also use other libraries . There are two ways to share : Static , Dynamic .
At compile time , Copy the library code and merge it into the executable file , Is a static library .
At run time , Load a copy of the library code into memory , It's a dynamic library .
Dynamic libraries save more resources , It doesn't have to be copied many times , It's easy to update .
Responsible for linking things , be called The linker (linker), The one responsible for loading is called loader (loader).
However, the computer does it according to the address , Every instruction must be addressed before it is executed . Before the dynamic library loads , No one knows where it will be loaded , I don't know the address of the instruction in the dynamic library , Only by symbols ( name ) To record the list of functions it provides to others ( Export table ), And the list of functions it expects others to provide him with ( The import table ). After the library is loaded , You get the address . Before the program runs , You need to parse the symbol table first , Determine the actual address of each symbol .
Our first example , Two with the same name libfunc()
, In a main In the program , In a plugin.so in ,main Load first ,plugin.so The use of libfunc()
It's resolved to main Of libfunc()
. Executed the old libfunc()
, Instead of the one we modified with debug edition .
TIPS: Students who are interested in program linking and loading can have a look at Linkers and Loaders This book , Very detailed .
Compiler options and environment variable options related to symbols
If conditions permit , Try not to have two copies of code in the same program , In the case of the same symbol , Cause conflict .
If there is a symbol conflict, it must be solved : In this case , hypothesis main
immutable , Already included lib
Code for .plugin.so
It can be done by gcc
Of -Wl,-Bsymbolic Option tells the loader to use its own symbol first , Instead of giving priority to global symbols . This option resolves symbol conflicts .
TIPS: If you want to see how the loader works , You can use environment variables LD_DEBUG=all ./main
To execute the program , You'll get the detailed parsing process .manpage Of ld.so(8)
There are more details .
Finally, the code for the example is attached :
* sample cat lib.h #ifndef UNTITLED_LIB_H #define UNTITLED_LIB_H void lib_func(); #endif //UNTITLED_LIB_H * sample cat lib.c #include <stdio.h> #include "lib.h" void lib_func() { //fprintf(stderr, "%s()\n", __func__); fprintf(stderr, "debug:%s()\n", __func__); } * sample cat main.c #include <stdio.h> #include <unistd.h> #include <dlfcn.h> #include "lib.h" int main() { void *handle = dlopen("./plugin.so", RTLD_NOW); void (*plugin_func)() = (void (*)()) dlsym(handle, "plugin"); plugin_func(); return 0; } * sample cat plugin.c #include "lib.h" void plugin() { lib_func(); } * sample cat Makefile all:main plugin main: cc -o main main.c lib.c -ldl -rdynamic plugin:plugin.c lib.c #cc -shared -fPIC -o plugin.so plugin.c lib.c -Wl,-Bsymbolic cc -shared -fPIC -o plugin.so plugin.c lib.c clean: rm -f main plugin.so * sample
( Chen Guo | Tiancun information )
边栏推荐
- Main steps of system test
- 我从根上解决了微信占用手机内存问题
- Nifi from introduction to practice (nanny level tutorial) - environment
- "Interesting" is the competitiveness of the new era
- 手把手教你用AirtestIDE无线连接手机!
- 【数据挖掘】期末复习(样卷题目+少量知识点)
- 物联网?快来看 Arduino 上云啦
- Experience of IOS interview strategy - App testing and launching
- 16 safety suggestions from metamask project to solid programmers
- The data value reported by DTU cannot be filled into Tencent cloud database through Tencent cloud rule engine
猜你喜欢
openGauss内核:简单查询的执行
快速了解常用的消息摘要算法,再也不用担心面试官的刨根问底
Party, Google's autoregressive Wensheng graph model
The agile way? Is agile development really out of date?
Creation and use of unified links in Huawei applinking
[database] final review (planning Edition)
Reading notes of returning to hometown
Pycharm中使用Terminal激活conda服务(终极方法,铁定可以)
On the value foam of digital copyright works from the controversial nature of "Meng Hua Lu"
Definition and use of constants in C language
随机推荐
‘高并发&高性能&高可用服务程序’编写及运维指南
Internet of things? Come and see Arduino on the cloud
Use terminal to activate CONDA service in pypharm (the ultimate method is definitely OK)
[data mining] final review (sample questions + a few knowledge points)
如何高效的分析online.log
[live broadcast of celebrities] elastic observability workshop
Richard Sutton, the father of reinforcement learning, paper: pursuing a general model for intelligent decision makers
Kubernetes集群部署
CVPR 2022 | interprétation de certains documents de l'équipe technique de meituan
Codereview tool chain for micro medicine
1、贪吃蛇游戏设计
[highlights] summary of award-winning activities of Tencent cloud documents
Generate the NC file of 4-D air pressure and temperature, and then read the code (provide the code)
What is SCRM? What is the difference between SCRM and CRM
DTU上报的数据值无法通过腾讯云规则引擎填入腾讯云数据库中
MySQL master-slave replication
Use abp Zero builds a third-party login module (I): Principles
Sinomeni vine was selected as the "typical solution for digital technology integration and innovative application in 2021" of the network security center of the Ministry of industry and information te
脚本之美│VBS 入门交互实战
1. Snake game design