Hello,
On Tue, 23 Aug 2005, znort wrote:
> Could you tell/help me why the little code :
[...]
> Under cygwin gcc version 3.4.4 (cygming special) and Linux with gcc 3.3.5
> same "strange" results... (no segmentation fault with cygwin anyway)
>
> (notes : Under Solaris x86 (gcc3.4.4) it works perfectly !?)
>
> I think I've forgotten something but where ?
See the attached file - it is modified version of your program. When the
second SIGSEGV occurs SIGSEGV signals are blocked. This is because you
exited the signal handler via a longjmp() and the signal mask is not
cleared. To do what you want you must use sigsetjmp/siglongjmp pair of
calls or remove SIGSEGV from the list of blocked signals.
#include <signal.h>
#include <setjmp.h>
#include <stdio.h>
/* jmp_buf context; */
sigjmp_buf context;
int yog(int n)
{
char *p=NULL;
printf("pass %d\n", n);
if (n<=2)
return 1;
strcpy(p, "dfldflflmflkklfklflkmfdlfldfldlfdlkfd"); // must crash of
course !!!
return 1;
}
void resume(int sig)
{
/* longjmp(context, 6); */
siglongjmp(context, 6);
//signal(SIGSEGV, resume);
}
int main(void)
{
int sig, i;
char *x=NULL;
sigset_t nset, oset;
for (i=0; i<3; i++)
{
/* Remove SIGSEGV from the list of blocked signals if you use
* setjmp/longjmp instead of sigsetjmp/siglongjmp. */
sigemptyset (&nset);
sigaddset(&nset, SIGSEGV);
sigprocmask (SIG_UNBLOCK, &nset, &oset);
signal(SIGSEGV, resume);
/* sig = setjmp(context);*/
sig = sigsetjmp(context, 1);
if (sig == 0)
{
yog(1);
yog(2);
yog(3);
//return 555;
}
else
{
fprintf(stderr, "ouch -- signal %d\n", sig);
}
}
puts("end");
return 0;
}
--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Problem reports: http://cygwin.com/problems.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/