Note: This bug is displayed in read-only format because the product is no longer active in Red Hat Bugzilla.
For bugs related to Red Hat Enterprise Linux 5 product line. The current stable release is 5.10. For Red Hat Enterprise Linux 6 and above, please visit Red Hat JIRA https://issues.redhat.com/secure/CreateIssue!default.jspa?pid=12332745 to report new issues.

Bug 549813

Summary: dl_close() race with C++ destructor
Product: Red Hat Enterprise Linux 5 Reporter: Jon Thomas <jthomas>
Component: glibcAssignee: Andreas Schwab <schwab>
Status: CLOSED ERRATA QA Contact: qe-baseos-tools-bugs
Severity: high Docs Contact:
Priority: medium    
Version: 5.4CC: drepper, ebachalo, fweimer, pmuller, rick.beldin, tao
Target Milestone: rc   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: glibc-2.5-54 Doc Type: Bug Fix
Doc Text:
A deadlock that could cause an application to hang could occur when the 'dlclose' function was called. This resulted in the cancellation of a thread. With this update, a deadlock no longer occurs when calling the 'dlclose' function.
Story Points: ---
Clone Of: Environment:
Last Closed: 2011-01-14 00:03:38 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
testcase none

Description Jon Thomas 2009-12-22 18:13:59 UTC
Created attachment 379881 [details]
testcase

This looks like a dup of

http://sources.redhat.com/bugzilla/show_bug.cgi?id=654


Create a pthread in the library init. In fini, cancel the pthread and then join. If the main thread does a dlclose(), the program hangs at pthread_join(). 
It is stuck in a futex. I tried the testcase from http://sources.redhat.com/bugzilla/show_bug.cgi?id=654 and that fails too. 

One thing that may be relevant is that if dlopen is called with RTLD_NODELETE, pthread_join will not hang.


main program->

#include <stdio.h> 
#include <dlfcn.h> 

int main(int argc, char *argv[]) {
	void *handle;

	handle =  dlopen("tiny.so",RTLD_NOW);
	if (handle) 
		printf("loaded shared library\n");
	else {
		printf("could not load shared library\n");
		return (-1);
	}	
	sleep(1);
	dlclose(handle);

}

the lib ->

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
pthread_t t;


void *F(void *arg) {

	int old;
	if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old) == 0) {
		printf("> cancelability enabled.\n");
	}
	else {
		printf("> could not set cancelability\n");
		return (0);
	}

	sleep(2);
} /*end F */

int _init_rick (void) {

printf("in init\n");
    if (pthread_create(&t, NULL, (void *(*)(void *)) F, NULL) == 0) 
	printf("started thread\n");
else
	printf("could not start thread\n");

} /* end _init_rick */

int _fini_rick (void) {

	printf("in fini\n");

	printf("canceling thread\n");
	if (pthread_cancel(t) == 0)
		printf("canceled thread\n");
	else
		printf("could not cancel thread \n");
	
	printf("joining thread\n");
	if (pthread_join(t, NULL) == 0)
		printf("joined with thread\n");
	else
		printf("could not join with thread\n");


} /* end _fini_rick */

Comment 1 Jon Thomas 2009-12-22 18:19:03 UTC
I attached the testcase.

untar, cd to C_Only, and use

make clean
make c_only
make tiny.so
export LD_LIBRARY_PATH=.
./c_only

you will see:

in init
> cancelability enabled.
started thread
loaded shared library
in fini
canceling thread
canceled thread
joining thread

and this is where it hangs.

Comment 2 Andreas Schwab 2010-01-08 13:19:13 UTC
It's a deadlock between dlclose and the cancellation handler which both want to lock GL(_dl_load_lock).

Comment 6 Martin Prpič 2010-12-02 11:17:59 UTC
    Technical note added. If any revisions are required, please edit the "Technical Notes" field
    accordingly. All revisions will be proofread by the Engineering Content Services team.
    
    New Contents:
A deadlock that could cause an application to hang could occur when the 'dlclose' function was called. This resulted in the cancellation of a thread. With this update, a deadlock no longer occurs when calling the 'dlclose' function.

Comment 9 errata-xmlrpc 2011-01-14 00:03:38 UTC
An advisory has been issued which should help the problem
described in this bug report. This report is therefore being
closed with a resolution of ERRATA. For more information
on therefore solution and/or where to find the updated files,
please follow the link below. You may reopen this bug report
if the solution does not work for you.

http://rhn.redhat.com/errata/RHBA-2011-0109.html