Speaking of sigaltstack...
Tom Gall
tom_gall@vnet.ibm.com
Sun Feb 9 05:18:00 GMT 2003
Greetings All,
Been troubleshooting an interesting bug with linuxthreads and
sigaltstack. The bug is in glibc 2.2.5 for all architectures (and I
wouldn't doubt in later versions of glibc)
Anyway given the following little test program:
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <pthread.h>
void xregister( void );
typedef unsigned long ss_stackframeaccess_t;
static __inline__ ss_stackframeaccess_t ss_readframeanchor( void )
{
ss_stackframeaccess_t r;
__asm__("movl %%ebp,%0"
: "=r" (r));
return r;
} /* End of ss_readframeanchor */
static void ss_signalhandler( int signo, siginfo_t *info, void *uc )
{
int pid;
pid = getpid();
printf ("signal handler 1 pid was %d ebp=%lx\n",
pid,ss_readframeanchor());
sleep(2);
exit(1);
}
static void *thread( void *arg )
{
printf("thread has pid %d\n",getpid());
while ( 1 ) { sleep(1); }
return NULL;
}
void xregister( void )
{
stack_t altstack;
char *stack;
int rc;
struct sigaction sa;
stack = malloc(65536);
altstack.ss_sp = stack;
altstack.ss_flags = SS_ONSTACK;
altstack.ss_size = 65536;
rc = sigaltstack( &altstack, NULL );
if (rc != 0) {
perror("sigaltstack");
exit(1);
}
printf("pid %d stack %p to %p\n",getpid(),stack,stack+65536);
sa.sa_sigaction = ss_signalhandler;
sigemptyset( &sa.sa_mask );
sa.sa_flags = SA_SIGINFO | SA_ONSTACK;
sigaction( SIGHUP, &sa, NULL );
sigaction( SIGINT, &sa, NULL );
sigaction( SIGTERM, &sa, NULL );
sigaction( SIGFPE, &sa, NULL );
sigaction( SIGSEGV, &sa, NULL );
sigaction( SIGILL, &sa, NULL );
sigaction( SIGBUS, &sa, NULL );
}
int main( void )
{
pthread_t thd;
pthread_create( &thd, NULL, thread, NULL );
pthread_create( &thd, NULL, thread, NULL );
pthread_create( &thd, NULL, thread, NULL );
pthread_create( &thd, NULL, thread, NULL );
xregister();
while (1) { sleep(1);
}
return 0;
}
Compile. Run. kill the parent pid. ps and You'll see the manager
thread is defunct.
It would appear that in linuxthreads when the pthread signal handler
wrapper gets control in the manager thread, and calls thread_self, it
gets the alternate stack and BOOM, that's all she wrote.
So the question of the moment is how to fix this beast. Should
thread_self just realize it's on an alt stack and ? If so, any
suggestions as best to the approach? This feels like one of those areas
where thread local storage would come in handy.
Interestly enough RedHat 7.3's glibc appears to do just that. But
later versions fail. SuSE as well.
I'm not particularly familiar with the internal workings of
linuxthreads. Any comments, and suggestions would be very valuable.
Past postings appear to have mentioned the problem but never saw a
resolution. Thanks in advance.
Regards,
Tom
More information about the Libc-alpha
mailing list