1 #include "CASCatch_CatchSignals.hxx"
3 #include "CASCatch_Failure.hxx"
4 #include "CASCatch_ErrorHandler.hxx"
5 #include <TCollection_AsciiString.hxx>
7 #define MAX_HANDLER_NUMBER 6
10 //================================================================================
12 * \brief creates a CASCatch_CatchSignals
14 //================================================================================
15 CASCatch_CatchSignals::CASCatch_CatchSignals()
16 :myIsActivated(Standard_False)
19 Standard_Integer i = 0;
20 for(; i<=MAX_HANDLER_NUMBER; i++)
21 mySigStates[i] = NULL;
26 //================================ UNIX part ==================================================
29 #include <OSD_WhoAmI.hxx>
30 #include <OSD_SIGHUP.hxx>
31 #include <OSD_SIGINT.hxx>
32 #include <OSD_SIGQUIT.hxx>
33 #include <OSD_SIGILL.hxx>
34 #include <OSD_SIGKILL.hxx>
35 #include <OSD_SIGBUS.hxx>
36 #include <OSD_SIGSEGV.hxx>
37 #include <OSD_SIGSYS.hxx>
39 #include <exception.h>
42 //==============================
43 typedef void (ACT_SIGIO_HANDLER)(void) ;
45 ACT_SIGIO_HANDLER *ADR_ACT_SIGIO_HANDLER = NULL ;
47 typedef void (* SIG_PFV) (int);
50 # include <floatingpoint.h>
54 # include <floatingpoint.h>
55 # include <sys/machsig.h>
61 #include <sys/signal.h>
69 # include <sys/siginfo.h>
77 # include <sys/siginfo.h>
81 //================================================================================
83 * \brief universal handler for signals
85 //================================================================================
86 static void Handler(const OSD_Signals theSig, const OSD_Signals)
90 sigaddset(&set, theSig);
91 sigprocmask(SIG_UNBLOCK, &set, NULL) ;
93 TCollection_AsciiString aMessage(theSig);
94 aMessage+=" signal detected";
96 CASCatch_Failure::Raise(aMessage.ToCString());
101 //================================================================================
103 * \brief handler for SIGSEGV signal
105 //================================================================================
106 static void SegvHandler(const OSD_Signals, const Standard_Address, const Standard_Address)
110 sigaddset(&set, SIGSEGV);
111 sigprocmask (SIG_UNBLOCK, &set, NULL);
113 CASCatch_Failure::Raise("SIGSEGV detected");
118 //================================================================================
120 * \brief activates a signals handling
122 //================================================================================
123 void CASCatch_CatchSignals::Activate()
125 if(myIsActivated) return;
127 struct sigaction act;
129 Standard_Integer i = 0;
130 for(; i<=MAX_HANDLER_NUMBER; i++)
131 mySigStates[i] = new struct sigaction(); //Initialize structures
134 act.sa_handler = (SIG_PFV) &Handler ;
135 sigemptyset(&act.sa_mask) ;
138 stat = sigaction(SIGHUP,&act,(struct sigaction*)mySigStates[0]); // ...... hangup
139 stat = sigaction(SIGFPE,&act,(struct sigaction*) mySigStates[1]); // ...... floating point exception
140 stat = sigaction(SIGINT,&act,(struct sigaction*)mySigStates[2]); // ...... interrupt
141 stat = sigaction(SIGQUIT,&act,(struct sigaction*)mySigStates[3]); // ...... quit
142 stat = sigaction(SIGBUS,&act,(struct sigaction*)mySigStates[4]); // ...... bus error
143 stat = sigaction(SIGILL,&act,(struct sigaction*)mySigStates[5]); // ...... illegal instruction
146 act.sa_flags = SA_RESTART ;
150 act.sa_handler = (SIG_PFV) &SegvHandler ;
152 #ifdef SA_SIGINFO // OSF,SOLARIS,IRIX
153 act.sa_flags = act.sa_flags | SA_SIGINFO ;
155 act.sa_sigaction = (void(*)(int, siginfo_t *, void*)) &SegvHandler ;
159 stat = sigaction( SIGSEGV , &act , (struct sigaction*)mySigStates[6]); // ...... segmentation violation
161 myIsActivated = Standard_True;
165 //================================================================================
167 * \brief deactivates a signals handling
169 //================================================================================
170 void CASCatch_CatchSignals::Deactivate()
172 if(!myIsActivated) return;
174 struct sigaction oact;
177 stat = sigaction(SIGHUP,(struct sigaction*)mySigStates[0],&oact); // ...... hangup
178 stat = sigaction(SIGFPE,(struct sigaction*)mySigStates[1],&oact); // ...... floating point exception
179 stat = sigaction(SIGINT,(struct sigaction*)mySigStates[2],&oact); // ...... interrupt
180 stat = sigaction(SIGQUIT,(struct sigaction*)mySigStates[3],&oact); // ...... quit
181 stat = sigaction(SIGBUS,(struct sigaction*)mySigStates[4],&oact); // ...... bus error
182 stat = sigaction(SIGILL,(struct sigaction*)mySigStates[5],&oact); // ...... illegal instruction
183 stat = sigaction(SIGSEGV,(struct sigaction*)mySigStates[6],&oact); // ...... segmentation violation
186 Standard_Integer i = 0;
187 for(; i<=MAX_HANDLER_NUMBER; i++)
188 delete (struct sigaction*)mySigStates[i];
190 myIsActivated = Standard_False;
196 //====================================== WNT part ====================================================
197 #include <OSD_WNT_1.hxx>
203 #define _OSD_FPX ( _EM_DENORMAL | _EM_INEXACT | _EM_UNDERFLOW | _EM_ZERODIVIDE | _EM_OVERFLOW) //Mask these exceptions
205 //================================================================================
207 * \brief handler for unexpected exceptions
209 //================================================================================
210 static Standard_Integer WntHandler(const Standard_Address theExceptionInfo)
212 LPEXCEPTION_POINTERS lpXP = ( LPEXCEPTION_POINTERS )theExceptionInfo;
213 DWORD dwExceptionCode = lpXP -> ExceptionRecord -> ExceptionCode;
215 TCollection_AsciiString aMessage((Standard_Integer)dwExceptionCode);
216 aMessage+=" Exception code - unexpected exception";
218 CASCatch_Failure::Raise(aMessage.ToCString());
220 return EXCEPTION_EXECUTE_HANDLER;
223 void SIGWntHandler(int , int ) ;
224 static void (*SIGWNTHANDLER)(int) = ( void (*)(int) ) ( &SIGWntHandler ) ;
227 //================================================================================
229 * \brief handler for signals
231 //================================================================================
232 static void SIGWntHandler(const int signum , const int theCode)
235 void (*OLDSIGWNTHANDLER)(int) ;
240 _controlfp ( _OSD_FPX, _MCW_EM );
241 OLDSIGWNTHANDLER = signal( signum , SIGWNTHANDLER );
243 if(theCode == _FPE_UNDERFLOW || theCode == _FPE_INEXACT) return;
244 CASCatch_Failure::Raise ("Floating point error");
247 OLDSIGWNTHANDLER = signal( signum , SIGWNTHANDLER );
248 CASCatch_Failure::Raise("Access violation");
251 OLDSIGWNTHANDLER = signal( signum , SIGWNTHANDLER );
252 CASCatch_Failure::Raise("Illegal instruction" );
258 //================================================================================
260 * \brief activates a signals handling
262 //================================================================================
263 void CASCatch_CatchSignals::Activate()
265 if(myIsActivated) return;
267 mySigStates[0] = SetUnhandledExceptionFilter (( LPTOP_LEVEL_EXCEPTION_FILTER )&WntHandler);
269 myFloatOpWord = _controlfp(0, 0);
270 _controlfp ( _OSD_FPX, _MCW_EM ); //Enable floating point exceptions
272 mySigStates[1] = signal( SIGSEGV , SIGWNTHANDLER );
273 mySigStates[2] = signal( SIGFPE , SIGWNTHANDLER );
274 mySigStates[3] = signal( SIGILL , SIGWNTHANDLER );
276 myIsActivated = Standard_True;
279 //================================================================================
281 * \brief deactivates a signals handling
283 //================================================================================
284 void CASCatch_CatchSignals::Deactivate()
286 if(!myIsActivated) return;
288 SetUnhandledExceptionFilter (( LPTOP_LEVEL_EXCEPTION_FILTER )mySigStates[0]);
290 _controlfp ( myFloatOpWord, _MCW_EM );
292 signal( SIGSEGV , ( void (*)(int) )mySigStates[1]);
293 signal( SIGFPE , ( void (*)(int) )mySigStates[2]);
294 signal( SIGILL , ( void (*)(int) )mySigStates[3]);
296 Standard_Integer i = 0;
297 for(; i<=MAX_HANDLER_NUMBER; i++)
298 mySigStates[i] = NULL;
300 myIsActivated = Standard_False;
305 //================================================================================
307 * \brief deactivates a signals handling
309 //================================================================================
310 void CASCatch_CatchSignals::Destroy()
312 if(myIsActivated) Deactivate();