Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect two ABI-incompatible version of my shared library loaded into single program

I wrote a shared library with several incompatible versions. I changed SONAME, so they are called:

  • lib_mylib.so.1.0.0 (older library)
  • lib_mylib.so.2.0.0

There are some functions only in mylib.so.1, others are only in mylib.so.2 and many functions are common (but several has changed count of arguments)

And I afraid that it is possible to link both versions of mylib into single application, for example when application itself is big and consists of many libraries. When application is rebuilt partially, there can be such situation:

  • Application
  • app_lib1.so (was built with mylib.so.1 - first version of my lib)
  • app_lib2.so (was rebuilt with mylib.so.2 - second version)

I already saw application with both versions loaded into it (ldd reports both).

So, Is it possible to add some checking code to mylib.so.2 to detect that there are both versions of library already loaded and they have conflicting ABI/Interface. (I can't modify lib_mylib.so.1 to add something into it)

like image 222
osgx Avatar asked Oct 03 '13 18:10

osgx


2 Answers

You can modify your version 2 library to resolve some version-1-specific symbol (dlsym(3)) during init and crash when found.

Example:

extern __attribute__((constructor)) void _version_check2()
{
    if (dlsym(RTLD_DEFAULT, "version_1_function"))
        abort();
}

A more graceful solution is to let version 2 library mimic the behaviour of version 1, but that introduces legacy code.

EDIT

To be future proof, you can also introduce a static version variable and all function calls would check if it matches the current. Then in future versions you just need to change the value of that variable and crash if mismatch.

EDIT 2

You can also call this function on every version 2 function so that sooner or later when version 1 gets loaded your app crashes.

like image 74
Maxthon Chan Avatar answered Oct 01 '22 18:10

Maxthon Chan


You can parse /proc/self/maps to get the list of currently loaded objects.

like image 30
grep Avatar answered Oct 01 '22 16:10

grep