当前位置:网站首页>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 )
边栏推荐
- "Interesting" is the competitiveness of the new era
- How stupid of me to hire a bunch of programmers who can only "Google"!
- what the fuck! I'm flattered. He actually wrote down the answers to the redis interview questions that big companies often ask!
- Open source monitoring system Prometheus
- 实现领域驱动设计 - 使用ABP框架 - 创建实体
- Troubleshooting and optimization of files that cannot be globally searched by ordinary users in easydss video platform customization project
- Babbitt | metauniverse daily must read: 618 scores have been announced. How much contribution has the digital collection made behind this satisfactory answer
- 一文讲透研发效能!您关心的问题都在
- The 35 "top 100 counties" of tmall 618 agricultural products come from the central and western regions and Northeast China
- One article explains R & D efficiency! Your concerns are
猜你喜欢

Getting started with the lvgl Library - colors and images

简述聚类分析

面试官:MySQL 数据库查询慢,除了索引问题还可能是什么原因?

几种常见的DoS攻击

手把手教你用AirtestIDE无线连接手机!

青藤入选工信部网安中心“2021年数字技术融合创新应用典型解决方案”

One article explains R & D efficiency! Your concerns are

"I, an idiot, have recruited a bunch of programmers who can only" Google "

CVPR 2022 | 美团技术团队精选论文解读

CVPR 2022 | 美團技術團隊精選論文解讀
随机推荐
系统测试主要步骤
Sphere, openai and ai21 jointly publish the best practice guidelines for deployment models
面试官:MySQL 数据库查询慢,除了索引问题还可能是什么原因?
Mlife forum | microbiome and data mining
One article explains R & D efficiency! Your concerns are
[2022 national tournament simulation] BigBen -- determinant, Du Jiao sieve
【数据库】期末复习(计科版)
用一个软件纪念自己故去的母亲,这或许才是程序员最大的浪漫吧
几种常见的DoS攻击
Comparator 排序函数式接口
Attack Science: ARP attack
nifi从入门到实战(保姆级教程)——环境篇
1、贪吃蛇游戏设计
Cohere、OpenAI、AI21联合发布部署模型的最佳实践准则
IOMMU (VII) -vfio and mdev
谁是鱼谁是饵?红队视角下蜜罐识别方式汇总
How can junior middle school developers effectively reduce their own workload?
Use terminal to activate CONDA service in pypharm (the ultimate method is definitely OK)
Cmput 379 explanation
敏捷之道 | 敏捷开发真的过时了么?