[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
-enable-omitfp and linuxthreads
From: |
Davin McCall |
Subject: |
-enable-omitfp and linuxthreads |
Date: |
Thu, 28 Aug 2003 11:58:41 +1000 |
Hi,
First apologies for not reporting this directly in GNATS, the web-based access
seems to be unavailable.
This relates to a longstanding problem that I have experienced when configuring
glibc (versions 2.3.2, 2.3.1) with -enable-omitfp. When I do so, all programs
dynamically linked against libpthread segfault.
The cause appears to be that linuxthreads for x86 architectures defines
CURRENT_STACK_FRAME as "__builtin_frame_address(0)" (see
linuxthreads/sysdeps/i386/pt-machine.h, and i686/pt-machine.h). Currently GCC
(version 3.2.3 and prior, and I believe 3.3.X although I have not yet tested)
returns garbage values for this builtin when -fomit-frame-pointer is used. Note
that all other architectures define CURRENT_STACK_FRAME as the current value of
the stack pointer register.
The linuxthreads Makefile turns on "-fno-omit-frame-pointer" for all affected
linuxthread source files, however, other parts of glibc are affected. For
instance, in malloc, from "thread-m.h" is included "libc-tsd.h" which comes
from linuxthreads/sysdeps/pthread/bits and in turn includes
"linuxthreads/descr.h" which uses the existing definition of
CURRENT_STACK_FRAME for TLS functionality. As malloc is not compiled with
-fno-omit-frame-pointer, this causes a problem which manifests itself as a
segfault the first time "malloc" is called.
Of course the real fix involves modifying gcc, but it seems prudent if not to
work around the problem in glibc, then to at least document it specifically and
clearly in the INSTALL file where the current descriptions of problems with
"--enable-omitfp" are very vague.
On the other hand the workaround is very easy. It is not apparent why x86 needs
to use "__builtin_frame_address" at all when all the other architectures seem
to be quite happy using the stack pointer. So, it might be possible to change
the definition of CURRENT_STACK_FRAME.
Another simple fix is to modify linuxthreads/descr.h to avoid using the
builtin, as follows:
#define CURRENT_STACK_FRAME_DESCR_H ({ char __csf; &__csf; })
... and then using "CURRENT_STACK_FRAME_DESCR_H" in place of
"CURRENT_STACK_FRAME" further on:
static inline pthread_descr thread_self (void)
{
#ifdef THREAD_SELF
return THREAD_SELF;
#else
char *sp = CURRENT_STACK_FRAME_DESCR_H;
if (sp >= __pthread_initial_thread_bos)
return &__pthread_initial_thread;
else if (sp >= __pthread_manager_thread_bos
&& sp < __pthread_manager_thread_tos)
return &__pthread_manager_thread;
else if (__pthread_nonstandard_stacks)
return __pthread_find_self();
else
#ifdef _STACK_GROWS_DOWN
return (pthread_descr)(((unsigned long)sp | (STACK_SIZE-1))+1) - 1;
#else
return (pthread_descr)((unsigned long)sp &~ (STACK_SIZE-1));
#endif
#endif
}
These simple changes allowed me to creating a working glibc+linuxthreads
configured with --enable-omitfp. However, there are some other places in glibc
where a similar modification might be needed (visible with a grep -r for
"CURRENT_STACK_FRAME").
Davin
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- -enable-omitfp and linuxthreads,
Davin McCall <=