[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