4

After doing some research I finally turn to SO to ask my question: what happens to memory dynamically allocated by a shared library (using malloc() or new) after the library is closed with dlclose()? The behaviour I observed is that any access to such memory (dereferencing it, using delete operator with it etc.) results in a segmentation fault. Is it defined somewhere?

Now it seems like a silly question to ask, when I know calling dlclose() before I was finished with the memory was the source of the bug - triggered by using delete operator on a new-created object received from a shared library - I have been struggling against for the last few days, but I would like to know why, instead of just guessing in case I encounter a similar situation in the future.

Maelkum
  • 269
  • 4
  • 14
  • Possibly related questions: https://stackoverflow.com/questions/31375177/why-might-mallocd-memory-from-a-shared-library-be-inaccessible-to-the-applicati https://stackoverflow.com/questions/4732018/what-happens-to-the-global-variables-in-shared-library-when-dlclose-is-called-on https://stackoverflow.com/questions/36420174/linux-c-c-allocate-deallocate-memory-in-dynamic-library – Maelkum Apr 09 '16 at 23:40

2 Answers2

6

what happens to the memory allocated by a shared library after the library is closed with dlclose().

It depends on what you mean by "allocated".

There are at least three cases to consider:

  1. Memory is allocated using malloc or new. dlclose will have no effect.
  2. A global inside the library. dlclose() may munmap() the memory (or not; depending on whether other symbols from the library have been used). If munmap does happen, the memory will be completely inaccessible.
  3. Library creates a global object (such as a global std::string). The object allocates internal storage for itself using ::new (as string would). When the library is dlclosed, the object may be destructed. If it is destructed, it will ::delete that memory. The memory will likely still be accessible, but accessing it invokes undefined behavior (just like any other access to dangling memory).

Update:

For case #1, the newd memory will still be accessible. But any nested pointers within that newd object may not be. In C++, if the object has virtual functions, the virtual table pointer may become inaccessible (it points to read-only data within the now unloaded foo.so), and this case becomes equivalent to #2.

Do you have any clues I should follow to find out what went wrong?

Yes: use the usual debugging technique: run the program under GDB, find out where exactly it crashes. If you still can't understand the crash, edit your question with some code that shows what the program is doing, and GDB output for it.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • 1
    Thanks. I edited the question to clarify that I was accessing memory allocated by operator `new`. But if you say `dlclose()`-ing the library would have no effect on such memory the bug must be somewhere else - for me it looked like that was exactly the case, and accessing the object triggered a segfault. Do you have any clues I should follow to find out what went wrong? – Maelkum Apr 10 '16 at 07:11
  • 2
    @EmployedRussion This is what I was looking for: *virtual table pointer may become inaccessible *. The objects allocated by the `.so` had virtual destructors - what explains why the segfault was triggered by invocation of the `delete` operator. Thank you for sharing knowledge. I marked your answer as the accepted one. – Maelkum Apr 10 '16 at 19:59
-1

The memory is freed back to the operating system. Any references left over are invalid and don't belong to your process anymore, which is why trying to do anything with them trips a segfault.

eoD .J
  • 302
  • 2
  • 5