1

I am using a .so as a sort of plugin to my program to allow user defined logic to be applied. Muliuple instance of the progam will run, each with their own specific .so that defines the user specific logic for that instance of the program. The program will ideally run indefinately but there will be times that some of the logic needs to be changed, so I had the bright idea of detecting when a .so was modified and uploading the new .so. That way it's possible to change specific implementation logic without killing/restarting the program (which could result in lose of data).

I have the loadPlugin function working, and I'm using inotify to detect when the .so is changed and load it again. This didn't work as planned. I had assumed all .so were loaded in memory and from that point on were completely independent of the physical file, but apparntly that isn't the case. If I change the .so file without warning my program crashes with a segfault. If I rm the .so and then copy a new version it the program doesn't crash-I'm told it knows to keep a version of the plugin in memory when it's removed. However, when my loadPlugin method kicks in to try to load the newly-modified .so it just returns references to the old .so methods rather then the new methods. I assume it defaults to using the version already loaded in memory since it assumes they are identical, but I specifically want it to load the new version! Since only one application will ever use that .so, and I'm gaurenteed that it won't be calling the methods of the .so while I'm loading in the new .so, It's safe to overwrite the definition of the .so if I just knew how to make that happen.

I'm wondering what the best method of getting around these problems are? My first idea is to copy a version of the .so file to another location prior to loading it so that even if the original file is modified my program won't crash, but that doesn't get around the main problem. How do I tell inotify to ignore whatever cached version of the .so file it has in memory and load a NEW version of the plugin? Do I need to alternate between two seperate files (plugin1.so, plugin2.so) so that whhile plugin1.so is running I can modify plugin2.so and load it, freeing up plugin1.so to be changed? Would this even work, or would I end up with both versions 'cached' after I read them once and be unable to load a plugin the third time it's changed?

ps. I'm sure you guessed, but I'm working with C++ on linux (specifically either redhat or centos). I can define my OS in the final runtime enviroment, so while portability is always nice I don't need it if the only method isn't portable.

4
  • @James: well, it's not an easy question... Commented Aug 7, 2012 at 15:46
  • Huh. I work on a large application which uses .so files which can be rebuilt and reloaded at runtime; there are no file locks or lazy loading issues. We didn't use inotify or rm or anything like that; just a call to make followed by an internal library reloading function call. Commented Aug 7, 2012 at 15:48
  • 2
    Are you using dlclose before loading the new so? Commented Aug 7, 2012 at 15:55
  • dani, I am using dlclose, but I was just reading more and it looks like I shouldn't have the issue I'm having if I closed it correctly. I'm going to double check my code and see if I maybe closed incorrectly. Commented Aug 7, 2012 at 16:01

2 Answers 2

1

Have you tried setting a different SONAME for the plugin when you update it? SONAME are what distinguish different versions of the same library, which pretty much is what you're asking for.

If you look into /usr/lib or /lib on your machine, and wonder who defines which symlinks are created there, it's the SONAMES of the individual libraries ;-)

man ld or man gcc should tell you how to specify the SONAME when linking.

Sign up to request clarification or add additional context in comments.

1 Comment

Your right that I hadn't specified the soname and that would probably address the issue. However, I want to minimize the potential mistakes a developer later may make trying to change the plugin; and if I forgot to change the soname they probably will to. Ideally I would like to ignore the soname and force it to just grab whatever the current version is in my plugin directory.
1

As Dani pointed out the problem was in my dlclose call. I was passing in the wrong header and not closing the DL properly. Soon as I fixed that I could properly load newer methods. Still have the issue with a change to the file killing the program, but I know I can work around that if need be.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.