This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Speaking of sigaltstack...


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]