From c687c3763be66c0cebfded74b540286508fd0f4d Mon Sep 17 00:00:00 2001 From: h_vogt Date: Fri, 12 Aug 2016 22:19:29 +0200 Subject: [PATCH] main.c, misccoms.c, preliminary fix to bug no. 315 longjmp creates segfault under Windows 10 (VS and MINGW), when WM_CLOSE is activated. Set signal handler function to cp_evloop, which leads to com_quit here, undo this function again in com_quit to avoid loops if segfault occurs in com_quit. --- src/frontend/misccoms.c | 21 +++++++++++++++++++++ src/winmain.c | 8 ++++++++ 2 files changed, 29 insertions(+) diff --git a/src/frontend/misccoms.c b/src/frontend/misccoms.c index 11a7ad428..b1b0ad6fc 100644 --- a/src/frontend/misccoms.c +++ b/src/frontend/misccoms.c @@ -41,6 +41,11 @@ extern void sh_delete_myvec(void); extern void sh_delvecs(void); #endif +#ifdef HAS_WINGUI +#include +extern RETSIGTYPE sigsegv(void); +#endif + void com_quit(wordlist *wl) @@ -52,6 +57,22 @@ com_quit(wordlist *wl) (wl && wl->wl_word && cieq(wl->wl_word, "noask")) || !cp_getvar("askquit", CP_BOOL, NULL); + /* work around a segmentation fault during LONGJMP(jbuf, 1) from + signal_handler.c:93 in Windows 10 upon WM_CLOSE: + upon seg fault directly go to com_quit via cp_evloop. + See winmain.c, WM_CLOSE */ +#ifdef HAS_WINGUI +#ifdef NGDEBUG + /* use standard signalling */ + signal(SIGSEGV, SIG_DFL); +#else + /* Restore original signal: Allow a comment and graceful shutdown after seg fault. + Prevents loop if segfault occurs in com_quit and signal function has been + set to cp_evloop */ + signal(SIGSEGV, (SIGNAL_FUNCTION)sigsegv); +#endif +#endif + /* update screen and reset terminal */ gr_clean(); cp_ccon(FALSE); diff --git a/src/winmain.c b/src/winmain.c index ed5ac150d..cff1d4a41 100644 --- a/src/winmain.c +++ b/src/winmain.c @@ -17,6 +17,7 @@ #include // assert macro #include "ngspice/stringutil.h" // copy #include // _read +//#include // check for OS #include @@ -94,6 +95,7 @@ static int HistPtr = 0; /* History management */ extern bool ft_ngdebug; /* some additional debug info printed */ extern bool ft_batchmode; extern FILE *flogp; /* definition see xmain.c, stdout redirected to file */ +extern int cp_evloop(char *string); #include "winmain.h" @@ -445,6 +447,12 @@ static LRESULT CALLBACK MainWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPA /* Put Spice commmand "Quit" to end the program into the text buffer */ PostSpiceCommand( "quit"); + /* work around a segmentation fault during LONGJMP(jbuf, 1) from + signal_handler.c:93 in Windows 10 upon WM_CLOSE: + upon seg fault directly go to com_quit via cp_evloop. + To avoid potential loop, singnal will be reset in com_quit */ + signal(SIGSEGV, (void (*)(int))cp_evloop(NULL)); + /* If simulation is running, set a breakpoint */ raise (SIGINT); return 0;