1 // Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // File : CASCatch_CatchSignals.cxx
24 // Author : Sergey RUIN, Open CASCADE S.A.S (sergey.ruin@opencascade.com)
26 #include "CASCatch_CatchSignals.hxx"
27 #include "CASCatch_Failure.hxx"
28 #include "CASCatch_ErrorHandler.hxx"
30 #include <TCollection_AsciiString.hxx>
32 #define MAX_HANDLER_NUMBER 6
34 //================================================================================
36 * \brief creates a CASCatch_CatchSignals
38 //================================================================================
39 CASCatch_CatchSignals::CASCatch_CatchSignals()
40 : myIsActivated( Standard_False )
42 for ( Standard_Integer i = 0; i <= MAX_HANDLER_NUMBER; i++ )
43 mySigStates[i] = NULL;
48 //================================ UNIX part ==================================================
51 #include <OSD_WhoAmI.hxx>
52 #include <OSD_SIGHUP.hxx>
53 #include <OSD_SIGINT.hxx>
54 #include <OSD_SIGQUIT.hxx>
55 #include <OSD_SIGILL.hxx>
56 #include <OSD_SIGKILL.hxx>
57 #include <OSD_SIGBUS.hxx>
58 #include <OSD_SIGSEGV.hxx>
59 #include <OSD_SIGSYS.hxx>
61 typedef void (ACT_SIGIO_HANDLER)(void) ;
62 ACT_SIGIO_HANDLER *ADR_ACT_SIGIO_HANDLER = NULL ;
64 typedef void (* SIG_PFV) (int);
67 # include <floatingpoint.h>
71 # include <floatingpoint.h>
72 # include <sys/machsig.h>
78 #include <sys/signal.h>
85 # include <sys/siginfo.h>
89 //================================================================================
91 * \brief universal handler for signals
93 //================================================================================
94 static void Handler(const int theSig)
98 sigaddset(&set, theSig);
99 sigprocmask(SIG_UNBLOCK, &set, NULL) ;
101 TCollection_AsciiString aMessage(theSig);
102 aMessage+=" signal detected";
104 CASCatch_Failure::Raise(aMessage.ToCString());
108 //================================================================================
110 * \brief handler for SIGSEGV signal
112 //================================================================================
114 static void SegvHandler(const int, siginfo_t*, const Standard_Address)
116 static void SegvHandler(const int)
121 sigaddset(&set, SIGSEGV);
122 sigprocmask (SIG_UNBLOCK, &set, NULL);
124 CASCatch_Failure::Raise("SIGSEGV detected");
128 //================================================================================
130 * \brief activates a signals handling
132 //================================================================================
133 void CASCatch_CatchSignals::Activate()
135 if(myIsActivated) return;
137 struct sigaction act;
139 Standard_Integer i = 0;
140 for(; i<=MAX_HANDLER_NUMBER; i++)
141 mySigStates[i] = new struct sigaction(); //Initialize structures
144 act.sa_handler = (SIG_PFV) &Handler ;
145 sigemptyset(&act.sa_mask) ;
147 /*stat = */sigaction(SIGHUP,&act,(struct sigaction*)mySigStates[0]); // ...... hangup
148 /*stat = */sigaction(SIGFPE,&act,(struct sigaction*) mySigStates[1]); // ...... floating point exception
149 /*stat = */sigaction(SIGINT,&act,(struct sigaction*)mySigStates[2]); // ...... interrupt
150 /*stat = */sigaction(SIGQUIT,&act,(struct sigaction*)mySigStates[3]); // ...... quit
151 /*stat = */sigaction(SIGBUS,&act,(struct sigaction*)mySigStates[4]); // ...... bus error
152 /*stat = */sigaction(SIGILL,&act,(struct sigaction*)mySigStates[5]); // ...... illegal instruction
155 act.sa_flags = SA_RESTART ;
160 act.sa_sigaction = (void(*)(int, siginfo_t *, void*)) &SegvHandler ;
162 act.sa_handler = (SIG_PFV) &SegvHandler ;
164 #ifdef SA_SIGINFO // OSF,SOLARIS,IRIX
165 act.sa_flags = act.sa_flags | SA_SIGINFO ;
168 /*stat = */sigaction( SIGSEGV , &act , (struct sigaction*)mySigStates[6]); // ...... segmentation violation
170 myIsActivated = Standard_True;
174 //================================================================================
176 * \brief deactivates a signals handling
178 //================================================================================
179 void CASCatch_CatchSignals::Deactivate()
181 if(!myIsActivated) return;
183 struct sigaction oact;
186 /*stat = */sigaction(SIGHUP,(struct sigaction*)mySigStates[0],&oact); // ...... hangup
187 /*stat = */sigaction(SIGFPE,(struct sigaction*)mySigStates[1],&oact); // ...... floating point exception
188 /*stat = */sigaction(SIGINT,(struct sigaction*)mySigStates[2],&oact); // ...... interrupt
189 /*stat = */sigaction(SIGQUIT,(struct sigaction*)mySigStates[3],&oact); // ...... quit
190 /*stat = */sigaction(SIGBUS,(struct sigaction*)mySigStates[4],&oact); // ...... bus error
191 /*stat = */sigaction(SIGILL,(struct sigaction*)mySigStates[5],&oact); // ...... illegal instruction
192 /*stat = */sigaction(SIGSEGV,(struct sigaction*)mySigStates[6],&oact); // ...... segmentation violation
195 Standard_Integer i = 0;
196 for(; i<=MAX_HANDLER_NUMBER; i++)
197 delete (struct sigaction*)mySigStates[i];
199 myIsActivated = Standard_False;
205 //====================================== WIN32 part ====================================================
206 #include <OSD_WNT.hxx>
212 #define _OSD_FPX ( _EM_DENORMAL | _EM_INEXACT | _EM_UNDERFLOW | _EM_ZERODIVIDE | _EM_OVERFLOW) //Mask these exceptions
214 //================================================================================
216 * \brief handler for unexpected exceptions
218 //================================================================================
219 static Standard_Integer WntHandler(const Standard_Address theExceptionInfo)
221 LPEXCEPTION_POINTERS lpXP = ( LPEXCEPTION_POINTERS )theExceptionInfo;
222 DWORD dwExceptionCode = lpXP -> ExceptionRecord -> ExceptionCode;
224 TCollection_AsciiString aMessage((Standard_Integer)dwExceptionCode);
225 aMessage+=" Exception code - unexpected exception";
227 CASCatch_Failure::Raise(aMessage.ToCString());
229 return EXCEPTION_EXECUTE_HANDLER;
232 void SIGWntHandler(int , int ) ;
233 static void (*SIGWNTHANDLER)(int) = ( void (*)(int) ) ( &SIGWntHandler ) ;
236 //================================================================================
238 * \brief handler for signals
240 //================================================================================
241 static void SIGWntHandler(const int signum , const int theCode)
244 void (*OLDSIGWNTHANDLER)(int) ;
249 _controlfp ( _OSD_FPX, _MCW_EM );
250 OLDSIGWNTHANDLER = signal( signum , SIGWNTHANDLER );
252 if(theCode == _FPE_UNDERFLOW || theCode == _FPE_INEXACT) return;
253 CASCatch_Failure::Raise ("Floating point error");
256 OLDSIGWNTHANDLER = signal( signum , SIGWNTHANDLER );
257 CASCatch_Failure::Raise("Access violation");
260 OLDSIGWNTHANDLER = signal( signum , SIGWNTHANDLER );
261 CASCatch_Failure::Raise("Illegal instruction" );
267 //================================================================================
269 * \brief activates a signals handling
271 //================================================================================
272 void CASCatch_CatchSignals::Activate()
274 if(myIsActivated) return;
276 mySigStates[0] = SetUnhandledExceptionFilter (( LPTOP_LEVEL_EXCEPTION_FILTER )&WntHandler);
278 myFloatOpWord = _controlfp(0, 0);
279 _controlfp ( _OSD_FPX, _MCW_EM ); //Enable floating point exceptions
281 mySigStates[1] = signal( SIGSEGV , SIGWNTHANDLER );
282 mySigStates[2] = signal( SIGFPE , SIGWNTHANDLER );
283 mySigStates[3] = signal( SIGILL , SIGWNTHANDLER );
285 myIsActivated = Standard_True;
288 //================================================================================
290 * \brief deactivates a signals handling
292 //================================================================================
293 void CASCatch_CatchSignals::Deactivate()
295 if(!myIsActivated) return;
297 SetUnhandledExceptionFilter (( LPTOP_LEVEL_EXCEPTION_FILTER )mySigStates[0]);
299 _controlfp ( myFloatOpWord, _MCW_EM );
301 signal( SIGSEGV , ( void (*)(int) )mySigStates[1]);
302 signal( SIGFPE , ( void (*)(int) )mySigStates[2]);
303 signal( SIGILL , ( void (*)(int) )mySigStates[3]);
305 Standard_Integer i = 0;
306 for(; i<=MAX_HANDLER_NUMBER; i++)
307 mySigStates[i] = NULL;
309 myIsActivated = Standard_False;
314 //================================================================================
316 * \brief deactivates a signals handling
318 //================================================================================
319 void CASCatch_CatchSignals::Destroy()
321 if(myIsActivated) Deactivate();