0

In Ubuntu 14.04, I have a C++ API as a shared library which I am opening using dlopen, and then creating pointers to functions using dlsym. One of these functions CloseAPI releases the API from memory. Here is the syntax:

void* APIhandle = dlopen("Kinova.API.USBCommandLayerUbuntu.so", RTLD_NOW|RTLD_GLOBAL);
int (*CloseAPI) = (int (*)()) dlsym(APIhandle,"CloseAPI");

If I ensure that during my code, the CloseAPI function is always called before the main function returns, then everything seems fine, and I can run the program again the next time. However, if I Ctrl-C and interrupt the program before it has had time to call CloseAPI, then on the next time I run the program, I get a return error whenever I call any of the API functions. I have no documentation saying what this error is, but my intuition is that there is some sort of lock on the library from the previous run of the program. The only thing that allows me to run the program again, is to restart my machine. Logging in and out does not work.

So, my questions are:

1) If my library is a shared library, why am I getting this error when I would have thought a shared library can be loaded by more than one program simultaneously?

2) How can I resolve this issue if I am going to be expecting Ctrl-C to be happening often, without being able to call CloseAPI?

Karnivaurus
  • 22,823
  • 57
  • 147
  • 247
  • This isn't really a solution but, what about a signal handler that handles C-c (and the like. SIGINT, is it?)? – keyser Nov 26 '14 at 21:54
  • As @keyser says, signal handling through `signal(2)` or `sigaction(2)` and calling `CloseAPI` in the handler would be the way to go. – clstrfsck Nov 26 '14 at 22:00
  • 1
    Have tried using ltrace. This tool display the calls a userland application makes to shared libraries. It does this by hooking into the dynamic loading system, allowing it to insert shims which display the parameters which the applications uses when making the call, and the return value which the library call reports. ltrace can also trace Linux system calls. – Jens Munk Nov 26 '14 at 22:01
  • It seems like your shared object (Kinova.XXX) isn't made properly. The main application is supposed to release whatever shared objects on exit. The tool ltrace will reveal what is going on – Jens Munk Nov 26 '14 at 22:03

1 Answers1

1

So, if you do use this api correctly then it requires you to do proper clean up after use (which is not really user friendly).

First of all, if you really need to use Ctrl-C, allow program to end properly on this signal: Is destructor called if SIGINT or SIGSTP issued?

Then use a technique with a stack object containing a resource pointer (to a CloseAPI function in this case). Then make sure this object will call CloseAPI in his destructor (you may want to check if CloseAPI wasn't called before). See more in "Effective C++, Chapter 3: Resource Management".

That it, even if you don't call CloseAPI, pointer container will do it for you.

p.s. you should considering doing it even if you're not going to use Ctrl-C. Imagine exception occurred and your program has to be stopped: then you should be sure you don't leave OS in an undefined state.

Community
  • 1
  • 1
d453
  • 519
  • 6
  • 10