delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin-developers/1999/08/31/06:57:28

Mailing-List: contact cygwin-developers-help AT sourceware DOT cygnus DOT com; run by ezmlm
List-Unsubscribe: <mailto:cygwin-developers-unsubscribe-archive-cygwin-developers=delorie DOT com AT sourceware DOT cygnus DOT com>
List-Subscribe: <mailto:cygwin-developers-subscribe AT sourceware DOT cygnus DOT com>
List-Archive: <http://sourceware.cygnus.com/ml/cygwin-developers/>
List-Post: <mailto:cygwin-developers AT sourceware DOT cygnus DOT com>
List-Help: <mailto:cygwin-developers-help AT sourceware DOT cygnus DOT com>,
<http://sourceware.cygnus.com/ml/#faqs>
Sender: cygwin-developers-owner AT sourceware DOT cygnus DOT com
Delivered-To: mailing list cygwin-developers AT sourceware DOT cygnus DOT com
Message-ID: <37CBB4A1.85DE3BEA@1c.ru>
Date: Tue, 31 Aug 1999 14:55:29 +0400
From: Vadim Egorov <egorovv AT 1c DOT ru>
X-Mailer: Mozilla 4.61 [en] (WinNT; I)
X-Accept-Language: ru,en
MIME-Version: 1.0
To: cygwin-developers AT sourceware DOT cygnus DOT com
Subject: Re: longjmp problem
References: <37C65CF3 DOT 50E89A09 AT 1c DOT ru> <19990830113850 DOT A2290 AT cygnus DOT com>
X-MDaemon-Deliver-To: cygwin-developers AT sourceware DOT cygnus DOT com
X-Return-Path: EgorovV AT 1c DOT ru


Chris Faylor wrote:
> 
> On Fri, Aug 27, 1999 at 01:40:03PM +0400, Vadim Egorov wrote:
> >Hello,
> >
> >There is a problem with setjmp/longjmp/signals/exceptions that can be
> >demonstrated by the following code:
> >
... 
> In this case, I suspect that setjmp itself is being interrupted so env
> is in an unknown state when the the signal handler uses it.
> 
> -chris
Hello,

After digging around this problem I think that it concerns win32 SEH 
mechanics. Following code shows the mutations of SEH frame 
list while signals caused by exceptions are processed.


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <setjmp.h>
#include <windows.h>
#include <exceptions.h>

asm (".equ __except_list,0");
extern exception_list *_except_list asm ("%fs:__except_list");

static jmp_buf	env;
int signo = SIGSEGV;

void print_seh(const char* where)
{
    exception_list* p = _except_list;
    printf("%s\n", where);
    while ( p != (exception_list*)-1)
    {
        printf("\thandler: %08x\n", p->handler);
        p = p->prev;
    }
}

static void sig_handler(int sig)
{
    print_seh("in signal");
    longjmp(env, 1);
}

int main(int argc, char * * argv)
{
    if ( setjmp(env) == 0 ) 
    {
        signal(signo, sig_handler);
        print_seh("before signal");
        *(char*)0 = 1;
    }
    else
    {
        print_seh("after signal");
    }
    return 0;
}

Program gives the following output:

before signal
	handler: 6100b654
	handler: 77f3b744
in signal
	handler: 77f9667a
	handler: 6100b654
	handler: 77f3b744
after signal
	handler: 77f9667a
	handler: 6100b654
	handler: 77f3b744

So when signal is invoked there is one extra exception handler 
on the top of the list. I think it is added by Win32 SEH before
it begins to walk through SEH frame list.

Due to longjmp it remains there ever since and handles subsequent 
exceptions. Looks like it returns ExceptionContinueExecution so 
that program hangs at the next faulting instruction.

That's why some unwinding is required after longjmp if  
exception handler is active. In this particular case simple

_except_list = _except_list->prev;

before longjmp is enough but in general case when other seh frames 
can be involved the task is more complicated.
I think SEH unwinding should be performed in longjump based on 
target esp value.

I would be grateful to here any comments about my conclusions
before I try to invent a fix for it.

Regards
Vadim

-- 
*********************************************
Vadim Egorov, 1C      *       ÷ÁÄÉÍ åÇÏÒÏ×,1C
egorovv AT 1c DOT ru         *         egorovv AT 1c DOT ru
*********************************************

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019