forked from rpms/glibc
		
	
		
			
				
	
	
		
			92 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			92 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| PURPOSE of /tools/glibc/Regression/bz549813-dl-close-race-with-C-destructor
 | |
| Description: Test for bz549813 (dl_close() race with C++ destructor)
 | |
| Author: Petr Muller <pmuller@redhat.com>
 | |
| Bug summary: dl_close() race with C++ destructor
 | |
| Bugzilla link: https://bugzilla.redhat.com/show_bug.cgi?id=549813
 | |
| 
 | |
| Description:
 | |
| 
 | |
| 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 */
 |