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.

This commit is contained in:
h_vogt 2016-08-12 22:19:29 +02:00 committed by rlar
parent 31889516e5
commit c687c3763b
2 changed files with 29 additions and 0 deletions

View File

@ -41,6 +41,11 @@ extern void sh_delete_myvec(void);
extern void sh_delvecs(void);
#endif
#ifdef HAS_WINGUI
#include <signal.h>
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);

View File

@ -17,6 +17,7 @@
#include <assert.h> // assert macro
#include "ngspice/stringutil.h" // copy
#include <io.h> // _read
//#include <VersionHelpers.h> // check for OS
#include <errno.h>
@ -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;