SoFunction
Updated on 2025-03-09

Solution to the conflict problem of symbols of the same name under linux

Solution to the conflict problem of symbols of the same name under linux

I encountered the following problems in my recent work:

There are three modules aa, bb, and cc under Linux, and the basic situation is as follows:

cc compiles and connects to obtain dynamic libraries, and cc has the following interfaces:

cc_fun 
{ 
…… 
do();//Calling the internal function of the cc module named do…… 
} 
 

bb compiles and connects to obtain a static library, and there are the following interfaces in bb:

bb_fun 
{ 
…… 
handle = dlopen(, RTLD_LAZY);//loadpccfun = dlsym(handle, “cc_fun”);//Get the cc_fun function pointer(*pccfun)();//Calling the cc_fun function, the do() function in the cc module should be called at this timedo();//Calling the internal function of the bb module named do (the same name as the do() function in the cc module, but the implementation is different)…… 
} 

After aa is compiled, connect through the -lbb link option to obtain the aa executable program and call the interface function bb_fun():

main 
{ 
…… 
bb_fun();//Calling the bb_fun function…… 
} 
 

During work, I found that aa behaves abnormally at runtime, and there are always memory leaks and functional abnormalities. Through positioning, I found that the problem is concentrated on the do() function of the same name. Through output printing, it was found that the do() function in the program called the do() function in the bb module, while the do() function in the cc module was never called, resulting in abnormal program behavior and memory leakage.

After multiple verifications, it was learned that the symbol tables in each library in the Linux program will eventually be loaded into the global symbol table where the program is located. At this time, if there is a symbol of the same name, you can only call the first symbol loaded, that is, the symbol of the same name loaded later will be overwritten by the previous one. The do() function in the cc module is overwritten by the do() function in the bb module, so it cannot be called.

Don't say much nonsense. . .

After experimenting with many unsatisfactory methods, the final solution is as follows:

1. Add the connection option of -Wl,-Bsymbolic -Wl,--version-script,version to the makefile of cc, which means to use the script in the version file to specify which functions it exports.

The file implementation is as follows:

VERS{ 
global: 
cc_fun; 
local: *; 
}; 

It means that the cc module only exports the interface function cc_fun, and the rest of the functions are set to local and do not export.

Save the file in the directory where the makefile is located.

3. Recompile and connect three modules to solve the problem.

Thank you for reading, I hope it can help you. Thank you for your support for this site!