[OpenAFS-devel] lwp code vs. recent glibc in FC5

Marc Dionne dionne@cs.wisc.edu
Sun, 05 Mar 2006 15:55:37 -0500


Hello,

After fixing minor compile issues and replacing MODULE_PARM declarations 
by module_param and module_param_array (which fixes the "falsely 
claims..." error at module load time), there was still some serious 
issues with the lwp code (see Bill Murray's message describing a seg 
fault in savecontext()).  A bit of debugging showed that a strange value 
appeared in the jmp_buf where we expect to see the stack pointer, and 
that was the cause of the crashes.

It turns out that a recent glibc change (circa Dec 2005) makes setjmp 
mangle the stack pointer when storing it in the jmp_buf; longjmp 
unmangles it on the way back.  Since we manipulate the stack pointer we 
need to be able to place a mangled value in the buffer so that longjmp 
converts it back to the right value (BTW at least on this platform it's 
a symmetrical function - mangle=unmangle).  See a patch below to 
lwp/process.c that uses assembler mangling code for i386 adapted from 
the glibc source.

- Don't know enough about assembler core to know if this can be 
rewritten in straight C, or if assembler is required
- The mangling algorithm is probably very platform-specific (sounds ugly 
to support...)
- A test will be needed at configure time or at runtime to determine if 
mangling is enabled.  Calling setjmp and comparing the stored SP to a 
nearby variable's address would work.

With this patch both client and server are running on an up-to-date FC5 
rawhide, compiled from current CVS with the various patches mentioned on 
this list.  (also had an authentication issue, but I'm assuming it's 
related to configuration)

Cheers,
Marc


diff -c -r1.21 process.c
*** process.c   3 Feb 2004 06:23:38 -0000       1.21
--- process.c   5 Mar 2006 19:34:44 -0000
***************
*** 178,183 ****
--- 178,184 ----
         printf("\n");
       }
   #endif
+     asm ("xorl %%gs:%c2, %0" : "=r" (savearea->topstack) : "0" 
(savearea->topstack), "i" (24));
       switch (code) {
       case 0:
         if (!sp)
***************
*** 188,193 ****
--- 189,195 ----
             case 0:
                 jmpBuffer = (jmp_buf_type *) jmp_tmp;
                 jmpBuffer[LWP_SP] = (jmp_buf_type) sp;
+               asm ("xorl %%gs:%c2, %0" : "=r" (jmpBuffer[LWP_SP]) : 
"0" (jmpBuffer[LWP_SP]), "i" (24));
   #if defined(AFS_S390_LINUX20_ENV) || defined(AFS_SPARC_LINUX20_ENV) 
|| (defined(AFS_SPARC64_LINUX20_ENV) && defined(AFS_32BIT_USR_ENV))
                 jmpBuffer[LWP_FP] = (jmp_buf_type) sp;
   #endif