Using a shared library constructor

Originally posted on May 15th, 2008 on the now defunct Tuxology technoblog

Shared libraries, sometime also referred to as DSO (for Dynamic Shared Objects) or DLL (for Dynamically Loadable Modules), offer an easy way to pack together useful functions and data as a code library that can be easily reused, updated separately from all the application making use of it and most important – under certain conditions allows most the code and data of the library to only be loaded once to the machine RAM regardless of the number of applications using it.

A shared library is thus normally comprised of a set of global functions which may be called by applications (or other libraries) that link with the library.

Given the shared nature of shared libraries, it is often useful to provide a constructor for the code library which will run each time the library is loaded by an application. Doing this is very simple, using the GNU specific constructor attribute.

Here is a code example:

/* init_demo.c */
 
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
 
static void __attribute__ ((constructor)) \
  lib_init(void);
 
static void lib_init(void) {
 
  printf("Library ready. \n");
 
  return;
}

Then build the the shared library using the following GNU Makefile:

.PHONY: clean
 
libinitdemo.so.1.0.0: init_demo.c 
  $(CC) -fPIC init_demo.c -shared \
  -Wl,-soname,libinitdemo.so.1 -o \
  libinitdemo.so.1.0.0
 
clean:
  $(RM) -f libinitdemo.so.1.0.0

TIP

Combining a shared library constructor as shown above with use of LD_PRELOAD can be a powerful way to add construction code to existing programs without changing their source code and indeed, without requiring access to their source code at all.