[uClibc 0005014]: dlclose() unmaps memory of libraries too early (resulting in SIGSEGV)

bugs at busybox.net bugs at busybox.net
Wed Sep 17 09:26:05 UTC 2008


A NOTE has been added to this issue. 
====================================================================== 
http://busybox.net/bugs/view.php?id=5014 
====================================================================== 
Reported By:                patchman
Assigned To:                uClibc
====================================================================== 
Project:                    uClibc
Issue ID:                   5014
Category:                   Shared Library Support
Reproducibility:            always
Severity:                   crash
Priority:                   normal
Status:                     assigned
====================================================================== 
Date Submitted:             09-16-2008 09:52 PDT
Last Modified:              09-17-2008 02:26 PDT
====================================================================== 
Summary:                    dlclose() unmaps memory of libraries too early
(resulting in SIGSEGV)
Description: 
I encountered a bit strange problem when calling dlclose() on a plugin
that itself uses multiple c++ shared libraries that make use of
templates. Actually I get an segmentation fault during dlclose().

The reason for this lays in the algorithm how dlclose() handles running
the destructors and unmapping the libraries memory.  Currently this
looks somehow like this:

    foreach $library in @libraries {
	if (--$library->refcount) == 0) {
	    $library->callDestructors();
	    $library->unmap();
	}
    }
	
In general this is not wrong if there are no weak symbols involved.
When using C++ templates it may happen that there are multiple instances
of the same template with the same template parameters in different
libraries. To make the linker happy all these symbols are marked as weak
by the compiler and the runtime linker chooses the physical memory
location based on some magic.

Now look again at the algorithm above. What happens in my case is that
one of the libraries uses some code and data of a template instance in
its destructors that was placed in memory of a library that got unmapped
earlier. This directly results in a segmentation fault because of a
reference to unmapped memory.

I made a check with current glibc and here everything is working fine.
Strace showed me that first all destructors of all libraries were
running and then all memory of all libraries is unmapped. So I think the
algorithm should be splitted in uClibc too:

    foreach $library in @libraries {
	if (--$library->refcount) == 0) {
	    $library->callDestructors();
	}
    }

    foreach $library in @libraries {
	if ($library->refcount) == 0) {
	    $library->unmap();
	}
    }

What do you think?

I hope this gets fixed soon. Thx!
====================================================================== 

---------------------------------------------------------------------- 
 patchman - 09-17-08 02:26  
---------------------------------------------------------------------- 
I added a patch the solves the problem, but I do not know if there are any
regressions now. Can anybody review this patch, please? Thanks! 

Issue History 
Date Modified   Username       Field                    Change               
====================================================================== 
09-16-08 09:52  patchman       New Issue                                    
09-16-08 09:52  patchman       Status                   new => assigned     
09-16-08 09:52  patchman       Assigned To               => uClibc          
09-17-08 02:26  patchman       Note Added: 0011534                          
======================================================================




More information about the uClibc-cvs mailing list