Source: http://mypyg.iteye.com/blog/845915
So is actually the meaning of shared object. Look at the above blog today, feel good. Hurry up and make a note of the record. The following content is mostly connected, interspersed with my own notes
Involved in the ELF format, GCC compilation options to fill, a simple and practical explanation, the Linux under the so file has a practical understanding.
What is a 1.so file?
2. How do I generate and use a so dynamic library file?
3. Address space, and thread safety.
4. Initialization of the library, parsing:
5. Replace the system function with the function in our own library:
What is a 1.so file?
Also elf format files, shared libraries (dynamic libraries), similar to DLLs. Save resources, speed up, and simplify code upgrades.
It's enough to know so much, pragmatism. And so with the impression to study the principle.
2. How do I generate and use a so dynamic library file?
Write a C file first: S.C
#include <stdio.h> int count; void out_msg (constChar *m) {//2 seconds Output 1 times information and Count For (;;) {printf ("%s%d\n", M, ++count); Sleep (2);} }
Compile: Get output file libs.o
Gcc-fpic-g-C S.c-o LIBS.O
----------------------------------------------------------------------
-fpic:-fpic acts on the compile phase, tells the compiler to generate the location-independent code (Position-independent-coded), the resulting code, no absolute address, all using the relative address, Therefore, the code can be loaded into the memory by the loader anywhere, can be executed correctly. This is exactly what the shared library requires, and when the shared library is loaded, the location of the memory is not fixed.
- G: Enables GCC to generate debug information, which can be generated using the operating system's native format (native format). GDB can take advantage of this information, and other debuggers can use this debug information
- C: Only the compilation operation is performed and no connection operation is made.
- o: Specifies the generated output file name
Attention! -c,-o does not refer to. c files and. o Files!!
----------------------------------------------------------------------
Link: Get output file libs.so
Gcc-g-shared-wl,-soname,libs.so-o libs.so LIBS.O-LC
-----------------------------------------------------------------------
The LIBS.O in the above statement is the input file
-shared:
produce a shared object which can then is linked with the other objects to the form an executable. Not all systems support this option. For predictable results, you must also specify the same set of options used for compilation (-fpic,-fpic, or model subopt ions) When you specify this linker option.
-WL: Note that the second letter is lowercase l, not I
Pass option as an option to the linker. If option contains commas, it is split to multiple options at the commas. You can use this syntax to pass a argument to the option. For example, -wl,-map,output.map passes -map output.map to the linker. When using the GNU linker, you can also get the same effect with-wl,-map=output.map.
-soname:
The key function of Soname is that it provides the standard for compatibility:
When you want to upgrade a library in the system, and the new library's soname is the same as the old Library's soname, the program that was built with the old library link will still work with the new library. This feature makes it easy to upgrade programs and locate errors for shared libraries under Linux.
In Linux, the application uses Soname to specify the version of the desired library, which can be declared by retaining or changing the soname and which versions are compatible, freeing the programmer from the problem of shared library version conflicts.
-LC:
-L is directly added to the name of a library, such as-LC is the LIBC library-L is the path of the library, the search priority in the-L directory search
------------------------------------------------------------------------
A header file: s.h
#ifndef _my_so_header_ #define _my_so_header_ void out_msg (constChar *m); #endif
Another C file to refer to the functions in this library: TS.C
#include <stdio.h>#include"s.h" intMainintargcChar**argv) {printf ("TS main\n"); Out_msg ("TS"); Sleep (5);//This sentence can be commented out, in the 4th quarter when you open it. printf"TS quit\n"); }
Compile link to this file: Get output file ts
Gcc-g ts.c-o ts-l.-ls
Execute./ts, hmm: success ... And almost
Got ts:error while loading shared libraries:libs.so:cannot open Shared object file:no such file or directory
System can not find our own definition of libs.so, then tell him, modify the variable Ld_library_path, for convenience, write a script: E (the file name is E, too lazy to get long)
Export ld_library_path=${pwd}:${ld_library_path}.
Execute:./E &
On the screen began to have information output, of course, TS quit you can not see, the front is a dead loop, the back will use this sentence
----------------------
& placed after the startup parameter indicates that this process is set as a background process . By default, the process is the foreground process, then the shell is occupied, we can not do other operations, for those who do not interact with the process, many times, we want to start in the background, you can start the parameters with a ' & ' to achieve this purpose.
----------------------
3. Address space, and thread safety:
If so:
./E & After you start the execution, wait a little bit and then./e&
What happens to the screen information at this time? How will the global variable count change?
will be two process cross output information, and the respective count does not interfere with each other, although they refer to the same so file.
This means that only the code is thread safe, and that there is no code that is a process security statement.
Not a look at the following, Khan.
4. Initialization of the library, parsing:
Dynamic library loading under Windows, unloading will have initialization functions and unloading functions to complete the initialization of the library and resource recycling, of course, Linux can also be implemented.
The elf file itself executes a _init () function and the _fini () function to do this, and we just have to put our own function to make the system execute at this time.
You can do it.
Modify the S.C file in front of us:
#include <stdio.h>voidMy_init (void) __attribute__ ((constructor));//tell GCC to throw this function into the Init section. voidMy_fini (void) __attribute__ ((destructor));//tell GCC to throw this function into the Fini section. voidOut_msg (Const Char*m) {printf ("ok!\n"); } intI//It's still a counter . voidMy_init (void) {printf ("Init ...%d\n", ++i); } voidMy_fini (void) {printf ("Fini ...%d\n", ++i); }
Re-production Libs.so,ts This is not to recompile, code maintenance upgrade a lot easier.
Then execute:./E &
You can see the screen output: (Incomplete information, just the same order)
Init
Main
Ok
Quit
Fini
We can see that our own defined initialization functions, as well as the parsing functions, are executed, both in front and last.
If Sleep (5) in S.C is not commented out, chances are:
./e&
./e& executes two successive times, the initialization function and the parse function are executed two times, although the system only loads once libs.so.
If you kill the background process while sleep, the parse function is not executed.
5. Replace the system function with the function in our own library:
Create a new file B.C: We want to replace the system function malloc and free (you can write a memory leak Detection tool yourself)
#include <stdio.h> void * malloc (int size) {printf ( " my malloc\n " ); return NULL; void free (void * AD) {printf ( " my free\n ); }
The usual, compiled link into an so file: Get libb.so
Gcc-fpic-g-C B.c-o LIBB.O
Gcc-g-shared-wl,-soname,libb.so-o LIBB.SO-LC
Modify S.C: Regenerate libs.so
void out_msg () { int *p; = (int*)malloc(+); Free (p); printf ("Stop ok!\n"); }
To modify the script file E:
Export ld_preload=${pwd}libb.so:${ld_preload} export ld_library_path=${pwd}:${ld_ Library_path}.
The key is on the ld_preload, and this path specifies that the so will be loaded before all so, and the symbol will overwrite the symbol in the so file that is loaded later. If the permissions of the executable are not appropriate (SID), this variable is ignored.
Execute:./E &
Well, we can see the malloc,free work.
Some understanding of dynamic library so file under "Linux" Linux