Dennis Bijwaard wrote: > > Wine does not seem to work when libsafe is installed: > http://www.bell-labs.com/org/11356/libsafe.html > wine does works when I remove /lib/libsafe.so.1 from /etc/ld.so.preload > libsafe does not show in the logs that there was an illegal access or > overflow. > > wine just crashes with the following output: > > bijwaard@jumbo:~$ wine winfile > fixme:pthread_atfork > Segmentation fault > the attached patch at least let wine start up with libsafe since it's an ugly patch, it will not be applied to CVS (if someone feels like having a clean implementation...) (don't forget to comment out the definition of USE_LIBSAFE in scheduler/pthread.c) anyway, since libsafe makes extensive use of stack, and since wine often switches its stack (from 32 to 16 bit code, some X11 function calls, at startup), I doubt libsafe will be very usefull (AFAICS, libsafe's not even thread safe, because of global var stack_stack which cannot hold a different value for each 32 bit thread - as wine implements) as a conclusion, specific work must be done in order to have libsafe correctly handle wine. A+ -- --------------- Eric Pouech (http://perso.wanadoo.fr/eric.pouech/) "The future will be better tomorrow", Vice President Dan Quayle
Index: scheduler/pthread.c =================================================================== RCS file: /home/cvs/cvsroot/wine/wine/scheduler/pthread.c,v retrieving revision 1.6 diff -u -r1.6 pthread.c --- scheduler/pthread.c 2000/04/29 16:44:20 1.6 +++ scheduler/pthread.c 2000/05/01 08:53:43 @@ -265,9 +265,38 @@ } strong_alias(__pthread_key_delete, pthread_key_delete); +/* to be commented out to turn on LibSafe support in Wine */ +/* #define USE_LIBSAFE */ + +#ifdef USE_LIBSAFE +static struct { + int pid; + pthread_key_t key; + const void *pointer; +} cached_initial_pthread; +#endif + int __pthread_setspecific(pthread_key_t key, const void *pointer) { - TEB *teb = NtCurrentTeb(); + TEB *teb; + +#ifdef USE_LIBSAFE + WORD _fs; + __asm__( "mov %%fs,%0" : "=r" (_fs)); + if (!_fs) { + if (cached_initial_pthread.pid) { + *(volatile int*)0 = 0; + return -1; + } + + cached_initial_pthread.pid = getpid(); + cached_initial_pthread.key = key; + cached_initial_pthread.pointer = pointer; + return 0; + } +#endif + + teb = NtCurrentTeb(); if (!teb->pthread_data) { teb->pthread_data = calloc(MAX_KEYS,sizeof(key_data)); } @@ -278,9 +307,30 @@ void *__pthread_getspecific(pthread_key_t key) { - TEB *teb = NtCurrentTeb(); + TEB* teb; +#ifdef USE_LIBSAFE + WORD _fs; + __asm__( "mov %%fs,%0" : "=r" (_fs)); + if (!_fs) { + if (cached_initial_pthread.pid && + cached_initial_pthread.pid == getpid() && + cached_initial_pthread.key == key) { + return cached_initial_pthread.pointer; + } + return NULL; + } +#endif + teb = NtCurrentTeb(); if (!teb) return NULL; if (!teb->pthread_data) return NULL; +#ifdef USE_LIBSAFE + if (cached_initial_pthread.pid && + cached_initial_pthread.pid == getpid() && + cached_initial_pthread.key == key) { + __pthread_setspecific(key, cached_initial_pthread.pointer); + cached_initial_pthread.pid = 0; + } +#endif return (void *)(((key_data*)(teb->pthread_data))[key]); } strong_alias(__pthread_getspecific, pthread_getspecific);