Saturday, November 5, 2022

Simple dlopen-example

        A simple sample for checking whether a .so in Linux both dynamically linked & dynamically loaded-linked in a process will share the same address space. also how the cases of multiple loads are handled.

https://github.com/tvijayas/dlopen-example/blob/main/README.md

main.cpp


int main(void){

   void *handle1,*handle2;
   void (*IncCount)(void);
   void (*GetCount)(void);
   char *error;

   /*lib reference count=1*/
   handle1 = dlopen("libmylib.so", RTLD_LAZY);
   
   if (!handle1) {
      fprintf(stderr, "%s\n", dlerror());
      exit(EXIT_FAILURE);
   }
                 
   dlerror();/* Clear any existing error */
   
   *(void **) (&IncCount) = dlsym(handle1, "increment_count");
   *(void **) (&GetCount) = dlsym(handle1, "get_count");
   
   IncCount();
   
   error = dlerror();
   if (error != NULL) {
      fprintf(stderr, "%s\n", error);
      exit(EXIT_FAILURE);
   }       
                          
   cout<< "I'm in main" <<endl;
   increment_count();
   cout<< get_count() <<endl;
   
   /*lib reference count=2*/
   handle2 = dlopen("libmylib.so", RTLD_LAZY);
   
   if (!handle2) {
      fprintf(stderr, "%s\n", dlerror());
      exit(EXIT_FAILURE);
   }
   
   cout<< "handle1 = " <<(unsigned int)handle1 <<endl;
   cout<< "handle2 = " <<(unsigned int)handle2 <<endl;
   
   /*lib reference count reduced from 2 to 1*/
   dlclose(handle1);
   
   /*handle1 still works as the reference to the library not 0*/
   *(void **) (&IncCount) = dlsym(handle1, "increment_count");
   increment_count();
   cout<< get_count() <<endl;
   
   /*handle2 also works*/
   *(void **) (&IncCount) = dlsym(handle2, "increment_count");
   increment_count();
   cout<< get_count() <<endl;
   
   /*lib reference count reduced from 1 to 0*/
   dlclose(handle1);
      
   return 0;
}


SharedSrc.c

#include "stdio.h"


static int count = 0;
int get_count(void){
  return count;
}

void increment_count(void){
  count++;
}

__attribute__((constructor)) void lib_init(void){
  fprintf(stderr,"%s \n","mylib loaded");   
}

__attribute__((destructor)) void lib_exit(void){
  fprintf(stderr,"%s \n","mylib unload");
}


Output: 
       mylib loaded 
       I'm in main 
       2 
       handle1 = 2439537088 
       handle2 = 2439537088 
       3 
       4 
       mylib unload 


Simple dlopen-example

        A simple sample for checking whether a .so in Linux both dynamically linked & dynamically loaded-linked in a process will share ...