Mailing-List: contact cygwin-developers-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , 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 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> Content-Type: text/plain; charset=koi8-r Content-Transfer-Encoding: 8bit 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 #include #include #include #include #include #include #include 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 *********************************************