Wednesday, August 27, 2014

Shared Objects


Shared objects are must have for any major project with large chunk of data and multiple components. In many cases we may end up in situation where in more than one component may require to include the functionality of one particular component. Consider the case of a network router development. In a typical router code you may see a common Hardware Abstraction Layer and different Protocols will interact with this HAL layer to program the hardware. By using shared libraries it became convenient  for the HAL to generate one single shared library with all the HAL apis and then each of the protocol processes can include this shared library. This greatly improves the code maintainability and more over it highly reduces the final binary size and the ram usage.


Building the Binary with the shared Object


Create the Shared Object file
shared_crasher.c
    #include 

    void crasher_stack_2 (void)
    {
        int a = 0;
        int b;
        b = 100 / a;
    }

    void crasher_stack_1 (void)
    {
        crasher_stack_2();
    }

    void crasher_stack_0 (void)
    {
        crasher_stack_1();
    }
 shared_crasher.h
    void crasher_stack_0 (void);    


Build the shared .so file
The Position Independent Code Flag needs to be set and the shared attribute need to be set for the GCC command.

    gcc -fPIC -shared -o libshared_crasher.so shared_crasher.c

Create the Binary file which uses the shared library
gdb_test.c
    #include "shared_crasher.h"


    void stack_2 (void)
    {
        crasher_stack_0();
    }

    void stack_1 (void)
    {
        stack_2();
    }

    int main ()
    {
        stack_1();
        return (0);
    }

Build the Binary file with the shared library
The shared library needs to specified with the -l argument. The path to the shared library needs to be specified with the -L argument.

    gcc -L /users/pnaduvat/myCode -l shared_crasher -o gdb_test.bin gdb_test.c

Lets try running the Binary now. 
Before running the binary we need to export the path to the library to the LD_LIBRARY_PATH

    export LD_LIBRARY_PATH=/users/pnaduvat/myCode:$LD_LIBRARY_PATH

    ./gdb_test.bin



Debugging the program crash.

Load the program on GDB and add a breakpoint on main. Capture the shared library details and run the program until it crashes. The program will crash and generate a core file.


    Thor myCode]./gdb-7.2.1-64 gdb_test.bin

    (gdb) break main
    Breakpoint 1 at 0x400602

    (gdb) run
    Starting program: /users/pnaduvat/myCode/gdb_test.bin

    Breakpoint 1, 0x0000000000400602 in main ()

    (gdb) info shared
    From                To                  Syms Read   Shared Object Library
    0x0000003398400a70  0x000000339841682e  Yes (*)     /lib64/ld-linux-x86-64.so.2
    0x00002aaaaaab04b0  0x00002aaaaaab05e8  Yes (*)     /users/pnaduvat/myCode/libshared_crasher.so
    0x000000339881d780  0x0000003398909618  Yes (*)     /lib64/libc.so.6
    (*): Shared library is missing debugging information.

    (gdb) detach
    Detaching from program: /users/pnaduvat/myCode/gdb_test.bin, process 6082

    (gdb) quit

Now lets play with the core file. Load the core file to GDB


    Thor myCode]./gdb-7.2.1-64
    (gdb) core-file core.6082

Add the main binary symbol files to the GDB


    (gdb) symbol-file gdb_test.bin
    Reading symbols from /users/pnaduvat/myCode/gdb_test.bin...(no debugging symbols found)...done.

Add the shared library symbol to the GDB at address we got from the info shared output


    (gdb) add-symbol-file libshared_crasher.so 0x00002aaaaaab04b0
    add symbol table from file "libshared_crasher.so" at
        .text_addr = 0x2aaaaaab04b0
    (y or n) y
    Reading symbols from /users/pnaduvat/myCode/libshared_crasher.so...(no debugging symbols found)...done.

Now you are all set happy debugging


    (gdb) bt
    #0  0x00002aaaaaab0591 in crasher_stack_2 ()
    #1  0x00002aaaaaab05a2 in crasher_stack_1 ()
    #2  0x00002aaaaaab05ad in crasher_stack_0 ()
    #3  0x00000000004005f1 in stack_2 ()
    #4  0x00000000004005fc in stack_1 ()
    #5  0x0000000000400611 in main ()



References

[1] http://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html

No comments:

Post a Comment