Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Absence of dynamic loaded libraries in ldd executable ouput

Why dynamic loaded library do not appear when you give ldd executable name?Is this true?because I could not find when it is given. It could be because of dynamic loading and dynamic linking.

Please help me out regarding this and let me know if you need any further details.

The output is as follows.

ldd example6 

    linux-vdso.so.1 =>  (0x00007ffe63369000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f56a2676000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f56a2372000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f56a1fa9000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f56a287a000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f56a1ca3000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f56a1a8d000)

I could see only libdl.so...but my executable,example6 is dependent on libtriangle.so which is created for some testing.

If you are accessing the shared libraries without dlopen commands, I am able to find .so details in executable because it is static loading and dynamic linking I feel.

Structure of the Program

Here executable,main makes calls to shared library,libtriangle.so. Shared library,triangle.so makes calls to another shared library,man.so.. man.so makes call to pthread apis

Makefile is present at the end

man.so is obtained using livingbeing.hpp,man.cpp and man.cpp uses pthread apis.man.so depends on -lpthread

triangle.so makes the function calls to man.so. triangle.so access shared library,man.so using dlopen,dlsym commands.

Executable,main is dependent on triangle.so. main acccess triangle.so using dlopen,dlsym functions.

ldconfig is also done for the .so files present in /usr/local/lib/MYDIR

Please find the below files.

livingbeing.hpp

 #ifndef LIVINGBEING_HPP

 #define LIVINGBEING_HPP

  #include <iostream>

using namespace std;

class livingbeing {
protected:
    double side_length_;




public:
    livingbeing()
        : side_length_(0) {}

    virtual ~livingbeing() {}
    void set_length(double side_length) {
        side_length_ = side_length;
    }

    virtual void eat() = 0;
};

typedef livingbeing* get_instance_t();
typedef void destroy_instance_t(livingbeing*);

 #endif

man.cpp

 #include "livingbeing.hpp"
 #include <stdio.h>
 #include <stdlib.h>
 #include <pthread.h>
void *print_message_function( void *ptr );
class man : public livingbeing {
public:
man()
{
cout<<"man constructor\n";

}
~man()
{
cout<<"man destructor\n";
}

    virtual void eat() {
        cout<<"man eating\n";

        pthread_t thread1, thread2;
    int  iret1;

   /* Create independent threads each of which will execute function */

    iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) NULL);

    pthread_join( thread1, NULL);

    }
};

void *print_message_function( void *ptr )
{
        cout<<"hello thread1 created";
}
extern "C" livingbeing * get_instance()
{
return new man;
}
extern "C" void destroy_instance(livingbeing *lb)
{
delete lb;
}

triangle.cpp

#include "polygon.hpp"
 #include "livingbeing.hpp"
 #include <cmath>

#include <dlfcn.h>
//#include <iostream>

class triangle : public polygon {
public:
    virtual double area() const {

    // load the triangle library
    void* man = dlopen("/usr/local/lib/ramu/libman.so", RTLD_LAZY);
    if (!man) {
        cerr << "Cannot load library: " << dlerror() << '\n';
        return 1;
    }

    // reset errors
    dlerror();

    // load the symbols
    get_instance_t* get_instance_man = (get_instance_t*) dlsym(man, "get_instance");
    const char* dlsym_error = dlerror();
    if (dlsym_error) {
        cerr << "Cannot load symbol create: " << dlsym_error << '\n';
        return 1;
    }

    destroy_instance_t* destroy_instance_man = (destroy_instance_t*) dlsym(man, "destroy_instance");
    dlsym_error = dlerror();
    if (dlsym_error) {
        cerr << "Cannot load symbol destroy: " << dlsym_error << '\n';
        return 1;
    }

    // create an instance of the class
    livingbeing* living = get_instance_man();

    // use the class
    living->set_length(7);
    cout << "The livingbeing is: ";

    living->eat();
    cout<<"\n";


    // destroy the class
        destroy_instance_man(living);

    // unload the triangle library
    dlclose(man);


        return side_length_ * side_length_ * sqrt(3) / 2;
    }
};

// the class factories
extern "C" polygon* create() {
    return new triangle;
}

extern "C" void destroy(polygon* p) {
    delete p;
}

main.cpp

#include "polygon.hpp"

#include <iostream>
#include <dlfcn.h>

int main() {
    using std::cout;
    using std::cerr;

    // load the triangle library
//    void* triangle = dlopen("./triangle.so", RTLD_LAZY);
    void* triangle = dlopen("/usr/local/lib/rakesh/libtriangle.so", RTLD_LAZY);
    if (!triangle) {
        cerr << "Cannot load library: " << dlerror() << '\n';
        return 1;
    }

    // reset errors
    dlerror();

    // load the symbols
    create_t* create_triangle = (create_t*) dlsym(triangle, "create");
    const char* dlsym_error = dlerror();
    if (dlsym_error) {
        cerr << "Cannot load symbol create: " << dlsym_error << '\n';
        return 1;
    }

    destroy_t* destroy_triangle = (destroy_t*) dlsym(triangle, "destroy");
    dlsym_error = dlerror();
    if (dlsym_error) {
        cerr << "Cannot load symbol destroy: " << dlsym_error << '\n';
        return 1;
    }

    // create an instance of the class
    polygon* poly = create_triangle();

    // use the class
    poly->set_side_length(7);
        cout << "The area is: " << poly->area() << '\n';

    // destroy the class
    destroy_triangle(poly);

    // unload the triangle library
    dlclose(triangle);

makefile

example6: main.cpp triangle
        $(CXX) $(CXXFLAGS) main.cpp -o example6 -L/usr/local/lib/roh -ltriangle -ldl

triangle: man triangle.cpp polygon.hpp
        $(CXX) $(CXXFLAGS) -shared -fPIC triangle.cpp -o libtriangle.so

man: man.cpp livingbeing.hpp
        $(CXX) $(CXXFLAGS) -shared -fPIC -o man.so man.cpp -lpthread

clean:
        rm -f example6 *.so *.o

.PHONY: clean
like image 312
vrajen1 Avatar asked Jan 19 '26 04:01

vrajen1


1 Answers

Executable main is not dependent on libtriangle in the sense of having libtriangle symbols in its import table. ldd is not aware of the libraries loaded at runtime with dlopen because it does not run or anyhow analyze the code. It only looks at symbols table. Note that even though you explicitly link libtriangle when building executable it has no effect. Linker will only really link library if executable has some unresolved symbols that are located in this library but in case of main executable there is none.

like image 76
user7860670 Avatar answered Jan 21 '26 17:01

user7860670



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!