]> SALOME platform Git repositories - modules/kernel.git/blob - src/CASCatch/CASCatch_CatchSignals.cxx
Salome HOME
PR: merge from branch BR_UnitTests tag mergeto_trunk_17oct05
[modules/kernel.git] / src / CASCatch / CASCatch_CatchSignals.cxx
1 #include "CASCatch_CatchSignals.hxx"
2
3 #include "CASCatch_Failure.hxx"  
4 #include "CASCatch_ErrorHandler.hxx"
5 #include <TCollection_AsciiString.hxx>
6
7 #define MAX_HANDLER_NUMBER 6
8
9
10 //================================================================================
11 /*! Public -
12  * \brief creates a CASCatch_CatchSignals
13  */
14 //================================================================================ 
15 CASCatch_CatchSignals::CASCatch_CatchSignals() 
16      :myIsActivated(Standard_False)
17 {
18
19   Standard_Integer i = 0;
20   for(; i<=MAX_HANDLER_NUMBER; i++)
21     mySigStates[i] = NULL;
22 }
23
24 #ifndef WNT
25
26 //================================ UNIX part ==================================================
27
28 #include <OSD.hxx>
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>
38 #ifndef LIN
39 #include <exception.h>
40 #endif
41
42 //==============================
43 typedef void (ACT_SIGIO_HANDLER)(void) ;
44
45 ACT_SIGIO_HANDLER *ADR_ACT_SIGIO_HANDLER = NULL ;
46
47 typedef void (* SIG_PFV) (int);
48
49 #ifdef SUN
50 # include <floatingpoint.h>
51 #endif
52
53 #ifdef SOLARIS
54 # include <floatingpoint.h>
55 # include <sys/machsig.h>
56 # include <stdlib.h>
57 # include <stdio.h>
58 #endif
59
60 #include <signal.h>
61 #include <sys/signal.h>
62
63 #ifdef LIN
64 # include <stdlib.h>
65 # include <stdio.h>
66 #else
67 # ifdef SA_SIGINFO 
68 #   ifndef AIX
69 # include <sys/siginfo.h>
70 #    endif
71 # endif
72 #endif
73
74
75 #ifdef IRIX
76 # include <sigfpe.h>
77 # include <sys/siginfo.h>
78 #endif 
79
80
81 //================================================================================
82 /*! Private -
83  * \brief universal handler for signals
84  */
85 //================================================================================ 
86 static void Handler(const OSD_Signals theSig, const OSD_Signals)
87 {
88   sigset_t set;
89   sigemptyset(&set);
90   sigaddset(&set, theSig);
91   sigprocmask(SIG_UNBLOCK, &set, NULL) ;
92
93   TCollection_AsciiString aMessage(theSig);  
94   aMessage+=" signal detected";
95  
96   CASCatch_Failure::Raise(aMessage.ToCString());
97 }
98
99
100 #ifdef SA_SIGINFO
101 //================================================================================
102 /*! Private -
103  * \brief  handler for SIGSEGV signal
104  */
105 //================================================================================ 
106 static void SegvHandler(const OSD_Signals, const Standard_Address, const Standard_Address)
107 {
108   sigset_t set;
109   sigemptyset(&set);
110   sigaddset(&set, SIGSEGV);
111   sigprocmask (SIG_UNBLOCK, &set, NULL); 
112
113   CASCatch_Failure::Raise("SIGSEGV detected");
114 }
115 #endif
116
117
118 //================================================================================
119 /*! Public -
120  * \brief activates a signals handling
121  */
122 //================================================================================ 
123 void CASCatch_CatchSignals::Activate() 
124 {  
125   if(myIsActivated) return;
126
127   struct sigaction act;
128
129   Standard_Integer i = 0;
130   for(; i<=MAX_HANDLER_NUMBER; i++)  
131     mySigStates[i] = new struct sigaction(); //Initialize structures
132
133   int stat;
134   act.sa_handler =  (SIG_PFV) &Handler ;
135   sigemptyset(&act.sa_mask) ;
136
137
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
144
145 #ifdef SA_RESTART
146   act.sa_flags   = SA_RESTART ;
147 #else
148   act.sa_flags   = 0 ;
149 #endif
150   act.sa_handler = (SIG_PFV) &SegvHandler ;
151
152 #ifdef SA_SIGINFO       // OSF,SOLARIS,IRIX
153   act.sa_flags = act.sa_flags | SA_SIGINFO ;
154 # ifdef SOLARIS
155   act.sa_sigaction = (void(*)(int, siginfo_t *, void*)) &SegvHandler ;
156 # endif
157 #endif
158
159   stat = sigaction( SIGSEGV , &act , (struct sigaction*)mySigStates[6]);    // ...... segmentation violation
160
161   myIsActivated = Standard_True;
162 }
163
164
165 //================================================================================
166 /*! Public -
167  * \brief deactivates a signals handling
168  */
169 //================================================================================
170 void CASCatch_CatchSignals::Deactivate() 
171 {
172   if(!myIsActivated) return;
173
174   struct sigaction oact;
175   int stat;
176
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
184
185
186   Standard_Integer i = 0;
187   for(; i<=MAX_HANDLER_NUMBER; i++)
188     delete (struct sigaction*)mySigStates[i];
189
190   myIsActivated = Standard_False;
191 }
192
193
194
195 #else
196 //====================================== WNT part ====================================================
197 #include <OSD_WNT_1.hxx>
198
199 #include <process.h>
200 #include <signal.h>
201 #include <float.h>
202
203 #define _OSD_FPX ( _EM_DENORMAL | _EM_INEXACT | _EM_UNDERFLOW | _EM_ZERODIVIDE | _EM_OVERFLOW) //Mask these exceptions
204
205 //================================================================================
206 /*! Private -
207  * \brief handler for unexpected exceptions
208  */
209 //================================================================================
210 static Standard_Integer WntHandler(const Standard_Address theExceptionInfo) 
211 {
212   LPEXCEPTION_POINTERS lpXP = ( LPEXCEPTION_POINTERS )theExceptionInfo;
213   DWORD                dwExceptionCode = lpXP -> ExceptionRecord -> ExceptionCode;
214
215   TCollection_AsciiString aMessage((Standard_Integer)dwExceptionCode);  
216   aMessage+=" Exception code - unexpected exception";
217
218   CASCatch_Failure::Raise(aMessage.ToCString());
219
220   return EXCEPTION_EXECUTE_HANDLER;
221 }
222
223 void SIGWntHandler(int , int ) ;
224 static void (*SIGWNTHANDLER)(int) = ( void (*)(int) ) ( &SIGWntHandler ) ;
225
226
227 //================================================================================
228 /*! Private -
229  * \brief handler for signals
230  */
231 //================================================================================
232 static void SIGWntHandler(const int signum , const int theCode)
233 {
234
235   void (*OLDSIGWNTHANDLER)(int) ;  
236   switch( signum ) { 
237   case SIGFPE : 
238     _fpreset() ;
239     _clearfp() ; 
240     _controlfp ( _OSD_FPX, _MCW_EM ); 
241     OLDSIGWNTHANDLER = signal( signum , SIGWNTHANDLER ); 
242
243     if(theCode == _FPE_UNDERFLOW || theCode == _FPE_INEXACT) return;
244     CASCatch_Failure::Raise ("Floating point error"); 
245     break;
246   case SIGSEGV : 
247     OLDSIGWNTHANDLER = signal( signum , SIGWNTHANDLER );
248     CASCatch_Failure::Raise("Access violation"); 
249     break; 
250   case SIGILL : 
251     OLDSIGWNTHANDLER = signal( signum , SIGWNTHANDLER );
252     CASCatch_Failure::Raise("Illegal instruction" ); 
253     break; 
254   }
255 }
256
257
258 //================================================================================
259 /*! Public -
260  * \brief activates a signals handling
261  */
262 //================================================================================ 
263 void CASCatch_CatchSignals::Activate() 
264 {
265   if(myIsActivated) return;
266
267   mySigStates[0] = SetUnhandledExceptionFilter (( LPTOP_LEVEL_EXCEPTION_FILTER )&WntHandler);
268
269   myFloatOpWord = _controlfp(0, 0);
270   _controlfp ( _OSD_FPX, _MCW_EM );  //Enable floating point exceptions
271
272   mySigStates[1] = signal( SIGSEGV , SIGWNTHANDLER );
273   mySigStates[2] = signal( SIGFPE , SIGWNTHANDLER );
274   mySigStates[3] = signal( SIGILL , SIGWNTHANDLER );
275
276   myIsActivated = Standard_True;
277 }
278
279 //================================================================================
280 /*! Public -
281  * \brief deactivates a signals handling
282  */
283 //================================================================================
284 void CASCatch_CatchSignals::Deactivate() 
285 {
286   if(!myIsActivated) return;
287
288   SetUnhandledExceptionFilter (( LPTOP_LEVEL_EXCEPTION_FILTER )mySigStates[0]);
289
290   _controlfp ( myFloatOpWord, _MCW_EM );
291
292   signal( SIGSEGV ,  ( void (*)(int) )mySigStates[1]);
293   signal( SIGFPE , ( void (*)(int) )mySigStates[2]);
294   signal( SIGILL , ( void (*)(int) )mySigStates[3]);
295
296   Standard_Integer i = 0;
297   for(; i<=MAX_HANDLER_NUMBER; i++)
298     mySigStates[i] = NULL;
299   
300   myIsActivated = Standard_False;
301 }
302
303 #endif
304
305 //================================================================================
306 /*! Private -
307  * \brief deactivates a signals handling
308  */
309 //================================================================================
310 void CASCatch_CatchSignals::Destroy() 
311 {
312   if(myIsActivated) Deactivate();
313 }
314