2.6.x signal handler bug
The bug has been reproduced successfully using the following program on kernel 2.6.5 and 2.6.7, and probably affects any other 2.6 kernel.
Kernel 2.4 produce the correct behavior, an endless loop of handled signals, but on kernel 2.6 the program segfaults.
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
volatile int len;
volatile int real;
volatile int caught;jmp_buf env;
void catcher(int sig){
signal(SIGSEGV,catcher); printf("requested: %9d malloced: %9d\n",len,real); longjmp(env, 1);
}
int main(){
char* p=0;
len = 0;
signal(SIGSEGV,catcher);
setjmp(env);
len++;
free(p);
p = malloc(len);
real = 0;
while(1){
p[real] = 0;
real++; }
return 0;
}
PS. I'm not subscribed to this list, so please include me in the cc
Quoted 6 lines · Paul Maurides
void catcher(int sig){
signal(SIGSEGV,catcher);
printf("requested: %9d malloced: %9d\n",len,real);
longjmp(env, 1);
}Use siglongjmp()
Neither printf() nor longjmp() are safe to call from within the sighandler. Have you tried deleting printf() and replacing longjmp() with siglongjmp()? This is a FAQ; search the list archives for details.
Quoted 3 lines · Paul Maurides
The bug has been reproduced successfully using the following program on kernel 2.6.5 and 2.6.7, and probably affects any other 2.6 kernel.
All, since about 2.5.71 or so.
Quoted 2 lines
Kernel 2.4 produce the correct behavior, an endless loop of handled signals, but on kernel 2.6 the program segfaults.
The program never returns from it's signal handler. Instead, it causes yet another segfault. Any program stupid enough to cause a segfault inside the segfault handler, should be killed. Full stop.
Quoted 16 lines
#include <
signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>volatile int len;
volatile int real;
volatile int caught;jmp_bufenv;void catcher(int sig){ signal(SIGSEGV,catcher); printf("requested: %9d malloced: %9d\n",len,real); longjmp(env, 1); }
Quoted 16 lines
int main(){
char* p=0;
len = 0;
signal(SIGSEGV,catcher);
setjmp(env);
len++;
free(p);
p = malloc(len);
real = 0;
while(1){
p[real] = 0;
real++;
}
return 0;
}Jörn
Signature · 3 lines
Fancy algorithms are buggier than simple ones, and they're much harder to implement. Use simple algorithms as well as simple data structures. -- Rob Pike