SEGFAULT in pthread_getspecific() in _init()
"Dr. Uwe Girlich" <[email protected]>
| Newsgroups | gmane.linux.ngpt.devel |
|---|---|
| Message-ID | <[email protected]> |
Hello list!
Are there any restrictions on usable pthread_* function in other shared library
_init() hooks?
I found, that pthread_key_create() & pthread_getspecific() called in a _init
function of a shared library will result in a SEGFAULT in pth_key_getdata(),
because at this time, pth_get_current() gave me a NULL pointer as current.
There are several possible solutions:
1) Never allow pthread_getspecific() in _init().
2) Link the shared library against libpthread.so, so _init() of NGPT will be
called before my own _init() function.
3) Apply the attached patch to check for a NULL pointer in pth_key_getdata().
Solutions 1) and 2) are impossible in my current project, so I had to correct
the symptoms and not the real cause.
Attached are 2 source files for main and the shared library. Compiled with
-DWITH_SELFINIT, _init() in the shared library will be activated and crash,
with -UWITH_SELFINIT the main program calls the init function itself and all is
OK. Make sure not to link the shared library itself against -lpthread.
-lpthread should stay at the link line for the executable only (would be
solution 2).
Bye, Uwe
--
Dr. Uwe Girlich email: [email protected]
Philosys Software GmbH www: www.philosys.de
Edisonstrasse 6 phone: +49 89 321407-44
D-85716 Unterschleissheim fax: +49 89 321407-12
library-keygetdata.diff
(text/plain, 468 B)
diff -u -r --exclude='*.o' ngpt-2.0.1-orig/pth_data.c ngpt-2.0.1-production/pth_data.c
--- ngpt-2.0.1-orig/pth_data.c Fri Aug 9 21:31:32 2002
+++ ngpt-2.0.1-production/pth_data.c Tue Sep 10 13:24:12 2002
@@ -105,7 +105,7 @@
return NULL;
if (!pth_keytab[key].used)
return NULL;
- if (current->data_value == NULL)
+ if (current == NULL || current->data_value == NULL)
return NULL;
return (void *)current->data_value[key];
}
gs.c
(text/plain, 264 B)
#include <stdio.h>
#ifndef WITH_SELFINIT
void shlib_init(void);
#endif
int
main(int argc, char** argv)
{
char *fname = "main";
fprintf(stderr,"%s: START\n", fname);
#ifndef WITH_SELFINIT
shlib_init();
#endif
fprintf(stderr,"%s: END\n", fname);
return 0;
}
shlib.c
(text/plain, 698 B)
#include <pthread.h>
#include <stdio.h>
pthread_once_t initialized = PTHREAD_ONCE_INIT;
pthread_key_t key = 0;
void
shlib_init(void)
{
char *fname = "shlib_init";
int error;
int *data;
fprintf(stderr,"%s: START\n", fname);
fprintf(stderr,"%s: call pthread_key_create(&key)\n", fname);
error=pthread_key_create(&key,NULL);
fprintf(stderr,"%s: pthread_key_create()=%d key=%d\n", fname, error, key);
fprintf(stderr,"%s: call pthread_getspecific()\n", fname);
data = pthread_getspecific(key); /* we expect here NULL */
fprintf(stderr,"%s: pthread_getspecific()=%p\n", fname, data);
fprintf(stderr,"%s: END\n", fname);
}
#ifdef WITH_SELFINIT
void
_init(void)
{
shlib_init();
}
#endif