1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/
20 #include "CASCatch_CatchSignals.hxx"
22 #include "CASCatch_Failure.hxx"
23 #include "CASCatch_ErrorHandler.hxx"
24 #include <TCollection_AsciiString.hxx>
26 #define MAX_HANDLER_NUMBER 6
29 //================================================================================
31 * \brief creates a CASCatch_CatchSignals
33 //================================================================================
34 CASCatch_CatchSignals::CASCatch_CatchSignals()
35 :myIsActivated(Standard_False)
38 Standard_Integer i = 0;
39 for(; i<=MAX_HANDLER_NUMBER; i++)
40 mySigStates[i] = NULL;
45 //================================ UNIX part ==================================================
48 #include <OSD_WhoAmI.hxx>
49 #include <OSD_SIGHUP.hxx>
50 #include <OSD_SIGINT.hxx>
51 #include <OSD_SIGQUIT.hxx>
52 #include <OSD_SIGILL.hxx>
53 #include <OSD_SIGKILL.hxx>
54 #include <OSD_SIGBUS.hxx>
55 #include <OSD_SIGSEGV.hxx>
56 #include <OSD_SIGSYS.hxx>
58 #include <exception.h>
61 //==============================
62 typedef void (ACT_SIGIO_HANDLER)(void) ;
64 ACT_SIGIO_HANDLER *ADR_ACT_SIGIO_HANDLER = NULL ;
66 typedef void (* SIG_PFV) (int);
69 # include <floatingpoint.h>
73 # include <floatingpoint.h>
74 # include <sys/machsig.h>
80 #include <sys/signal.h>
88 # include <sys/siginfo.h>
96 # include <sys/siginfo.h>
100 //================================================================================
102 * \brief universal handler for signals
104 //================================================================================
105 static void Handler(const OSD_Signals theSig, const OSD_Signals)
109 sigaddset(&set, theSig);
110 sigprocmask(SIG_UNBLOCK, &set, NULL) ;
112 TCollection_AsciiString aMessage(theSig);
113 aMessage+=" signal detected";
115 CASCatch_Failure::Raise(aMessage.ToCString());
120 //================================================================================
122 * \brief handler for SIGSEGV signal
124 //================================================================================
125 static void SegvHandler(const OSD_Signals, const Standard_Address, const Standard_Address)
129 sigaddset(&set, SIGSEGV);
130 sigprocmask (SIG_UNBLOCK, &set, NULL);
132 CASCatch_Failure::Raise("SIGSEGV detected");
137 //================================================================================
139 * \brief activates a signals handling
141 //================================================================================
142 void CASCatch_CatchSignals::Activate()
144 if(myIsActivated) return;
146 struct sigaction act;
148 Standard_Integer i = 0;
149 for(; i<=MAX_HANDLER_NUMBER; i++)
150 mySigStates[i] = new struct sigaction(); //Initialize structures
153 act.sa_handler = (SIG_PFV) &Handler ;
154 sigemptyset(&act.sa_mask) ;
157 stat = sigaction(SIGHUP,&act,(struct sigaction*)mySigStates[0]); // ...... hangup
158 stat = sigaction(SIGFPE,&act,(struct sigaction*) mySigStates[1]); // ...... floating point exception
159 stat = sigaction(SIGINT,&act,(struct sigaction*)mySigStates[2]); // ...... interrupt
160 stat = sigaction(SIGQUIT,&act,(struct sigaction*)mySigStates[3]); // ...... quit
161 stat = sigaction(SIGBUS,&act,(struct sigaction*)mySigStates[4]); // ...... bus error
162 stat = sigaction(SIGILL,&act,(struct sigaction*)mySigStates[5]); // ...... illegal instruction
165 act.sa_flags = SA_RESTART ;
169 act.sa_handler = (SIG_PFV) &SegvHandler ;
171 #ifdef SA_SIGINFO // OSF,SOLARIS,IRIX
172 act.sa_flags = act.sa_flags | SA_SIGINFO ;
174 act.sa_sigaction = (void(*)(int, siginfo_t *, void*)) &SegvHandler ;
178 stat = sigaction( SIGSEGV , &act , (struct sigaction*)mySigStates[6]); // ...... segmentation violation
180 myIsActivated = Standard_True;
184 //================================================================================
186 * \brief deactivates a signals handling
188 //================================================================================
189 void CASCatch_CatchSignals::Deactivate()
191 if(!myIsActivated) return;
193 struct sigaction oact;
196 stat = sigaction(SIGHUP,(struct sigaction*)mySigStates[0],&oact); // ...... hangup
197 stat = sigaction(SIGFPE,(struct sigaction*)mySigStates[1],&oact); // ...... floating point exception
198 stat = sigaction(SIGINT,(struct sigaction*)mySigStates[2],&oact); // ...... interrupt
199 stat = sigaction(SIGQUIT,(struct sigaction*)mySigStates[3],&oact); // ...... quit
200 stat = sigaction(SIGBUS,(struct sigaction*)mySigStates[4],&oact); // ...... bus error
201 stat = sigaction(SIGILL,(struct sigaction*)mySigStates[5],&oact); // ...... illegal instruction
202 stat = sigaction(SIGSEGV,(struct sigaction*)mySigStates[6],&oact); // ...... segmentation violation
205 Standard_Integer i = 0;
206 for(; i<=MAX_HANDLER_NUMBER; i++)
207 delete (struct sigaction*)mySigStates[i];
209 myIsActivated = Standard_False;
215 //====================================== WNT part ====================================================
216 #include <OSD_WNT_1.hxx>
222 #define _OSD_FPX ( _EM_DENORMAL | _EM_INEXACT | _EM_UNDERFLOW | _EM_ZERODIVIDE | _EM_OVERFLOW) //Mask these exceptions
224 //================================================================================
226 * \brief handler for unexpected exceptions
228 //================================================================================
229 static Standard_Integer WntHandler(const Standard_Address theExceptionInfo)
231 LPEXCEPTION_POINTERS lpXP = ( LPEXCEPTION_POINTERS )theExceptionInfo;
232 DWORD dwExceptionCode = lpXP -> ExceptionRecord -> ExceptionCode;
234 TCollection_AsciiString aMessage((Standard_Integer)dwExceptionCode);
235 aMessage+=" Exception code - unexpected exception";
237 CASCatch_Failure::Raise(aMessage.ToCString());
239 return EXCEPTION_EXECUTE_HANDLER;
242 void SIGWntHandler(int , int ) ;
243 static void (*SIGWNTHANDLER)(int) = ( void (*)(int) ) ( &SIGWntHandler ) ;
246 //================================================================================
248 * \brief handler for signals
250 //================================================================================
251 static void SIGWntHandler(const int signum , const int theCode)
254 void (*OLDSIGWNTHANDLER)(int) ;
259 _controlfp ( _OSD_FPX, _MCW_EM );
260 OLDSIGWNTHANDLER = signal( signum , SIGWNTHANDLER );
262 if(theCode == _FPE_UNDERFLOW || theCode == _FPE_INEXACT) return;
263 CASCatch_Failure::Raise ("Floating point error");
266 OLDSIGWNTHANDLER = signal( signum , SIGWNTHANDLER );
267 CASCatch_Failure::Raise("Access violation");
270 OLDSIGWNTHANDLER = signal( signum , SIGWNTHANDLER );
271 CASCatch_Failure::Raise("Illegal instruction" );
277 //================================================================================
279 * \brief activates a signals handling
281 //================================================================================
282 void CASCatch_CatchSignals::Activate()
284 if(myIsActivated) return;
286 mySigStates[0] = SetUnhandledExceptionFilter (( LPTOP_LEVEL_EXCEPTION_FILTER )&WntHandler);
288 myFloatOpWord = _controlfp(0, 0);
289 _controlfp ( _OSD_FPX, _MCW_EM ); //Enable floating point exceptions
291 mySigStates[1] = signal( SIGSEGV , SIGWNTHANDLER );
292 mySigStates[2] = signal( SIGFPE , SIGWNTHANDLER );
293 mySigStates[3] = signal( SIGILL , SIGWNTHANDLER );
295 myIsActivated = Standard_True;
298 //================================================================================
300 * \brief deactivates a signals handling
302 //================================================================================
303 void CASCatch_CatchSignals::Deactivate()
305 if(!myIsActivated) return;
307 SetUnhandledExceptionFilter (( LPTOP_LEVEL_EXCEPTION_FILTER )mySigStates[0]);
309 _controlfp ( myFloatOpWord, _MCW_EM );
311 signal( SIGSEGV , ( void (*)(int) )mySigStates[1]);
312 signal( SIGFPE , ( void (*)(int) )mySigStates[2]);
313 signal( SIGILL , ( void (*)(int) )mySigStates[3]);
315 Standard_Integer i = 0;
316 for(; i<=MAX_HANDLER_NUMBER; i++)
317 mySigStates[i] = NULL;
319 myIsActivated = Standard_False;
324 //================================================================================
326 * \brief deactivates a signals handling
328 //================================================================================
329 void CASCatch_CatchSignals::Destroy()
331 if(myIsActivated) Deactivate();