Salome HOME
Killing autotools files.
[modules/gui.git] / src / CASCatch / CASCatch_CatchSignals.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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.
10 //
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.
15 //
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
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 // File   : CASCatch_CatchSignals.cxx
24 // Author : Sergey RUIN, Open CASCADE S.A.S (sergey.ruin@opencascade.com)
25 //
26 #include "CASCatch_CatchSignals.hxx"
27
28 #include "CASCatch_Failure.hxx"  
29 #include "CASCatch_ErrorHandler.hxx"
30 #include <TCollection_AsciiString.hxx>
31
32 #define MAX_HANDLER_NUMBER 6
33
34
35 //================================================================================
36 /*! Public -
37  * \brief creates a CASCatch_CatchSignals
38  */
39 //================================================================================ 
40 CASCatch_CatchSignals::CASCatch_CatchSignals() 
41      :myIsActivated(Standard_False)
42 {
43
44   Standard_Integer i = 0;
45   for(; i<=MAX_HANDLER_NUMBER; i++)
46     mySigStates[i] = NULL;
47 }
48
49 #ifndef WNT
50
51 //================================ UNIX part ==================================================
52
53 #include <OSD.hxx>
54 #include <OSD_WhoAmI.hxx>
55 #include <OSD_SIGHUP.hxx>
56 #include <OSD_SIGINT.hxx>
57 #include <OSD_SIGQUIT.hxx>
58 #include <OSD_SIGILL.hxx>
59 #include <OSD_SIGKILL.hxx>
60 #include <OSD_SIGBUS.hxx>
61 #include <OSD_SIGSEGV.hxx>
62 #include <OSD_SIGSYS.hxx>
63 #ifndef LIN
64 #include <exception.h>
65 #endif
66
67 //==============================
68 typedef void (ACT_SIGIO_HANDLER)(void) ;
69
70 ACT_SIGIO_HANDLER *ADR_ACT_SIGIO_HANDLER = NULL ;
71
72 typedef void (* SIG_PFV) (int);
73
74 #ifdef SUN
75 # include <floatingpoint.h>
76 #endif
77
78 #ifdef SOLARIS
79 # include <floatingpoint.h>
80 # include <sys/machsig.h>
81 # include <stdlib.h>
82 # include <stdio.h>
83 #endif
84
85 #include <signal.h>
86 #include <sys/signal.h>
87
88 #ifdef LIN
89 # include <stdlib.h>
90 # include <stdio.h>
91 #else
92 # ifdef SA_SIGINFO 
93 #   ifndef AIX
94 # include <sys/siginfo.h>
95 #    endif
96 # endif
97 #endif
98
99
100 #ifdef IRIX
101 # include <sigfpe.h>
102 # include <sys/siginfo.h>
103 #endif 
104
105
106 //================================================================================
107 /*! Private -
108  * \brief universal handler for signals
109  */
110 //================================================================================ 
111 static void Handler(const OSD_Signals theSig, const OSD_Signals)
112 {
113   sigset_t set;
114   sigemptyset(&set);
115   sigaddset(&set, theSig);
116   sigprocmask(SIG_UNBLOCK, &set, NULL) ;
117
118   TCollection_AsciiString aMessage(theSig);  
119   aMessage+=" signal detected";
120  
121   CASCatch_Failure::Raise(aMessage.ToCString());
122 }
123
124
125 #ifdef SA_SIGINFO
126 //================================================================================
127 /*! Private -
128  * \brief  handler for SIGSEGV signal
129  */
130 //================================================================================ 
131 static void SegvHandler(const OSD_Signals, const Standard_Address, const Standard_Address)
132 {
133   sigset_t set;
134   sigemptyset(&set);
135   sigaddset(&set, SIGSEGV);
136   sigprocmask (SIG_UNBLOCK, &set, NULL); 
137
138   CASCatch_Failure::Raise("SIGSEGV detected");
139 }
140 #endif
141
142
143 //================================================================================
144 /*! Public -
145  * \brief activates a signals handling
146  */
147 //================================================================================ 
148 void CASCatch_CatchSignals::Activate() 
149 {  
150   if(myIsActivated) return;
151
152   struct sigaction act;
153
154   Standard_Integer i = 0;
155   for(; i<=MAX_HANDLER_NUMBER; i++)  
156     mySigStates[i] = new struct sigaction(); //Initialize structures
157
158   int stat;
159   act.sa_handler =  (SIG_PFV) &Handler ;
160   sigemptyset(&act.sa_mask) ;
161
162
163   stat = sigaction(SIGHUP,&act,(struct sigaction*)mySigStates[0]);    // ...... hangup
164   stat = sigaction(SIGFPE,&act,(struct sigaction*) mySigStates[1]);   // ...... floating point exception
165   stat = sigaction(SIGINT,&act,(struct sigaction*)mySigStates[2]);   // ...... interrupt
166   stat = sigaction(SIGQUIT,&act,(struct sigaction*)mySigStates[3]);  // ...... quit
167   stat = sigaction(SIGBUS,&act,(struct sigaction*)mySigStates[4]);   // ...... bus error
168   stat = sigaction(SIGILL,&act,(struct sigaction*)mySigStates[5]);   // ...... illegal instruction
169
170 #ifdef SA_RESTART
171   act.sa_flags   = SA_RESTART ;
172 #else
173   act.sa_flags   = 0 ;
174 #endif
175   act.sa_handler = (SIG_PFV) &SegvHandler ;
176
177 #ifdef SA_SIGINFO       // OSF,SOLARIS,IRIX
178   act.sa_flags = act.sa_flags | SA_SIGINFO ;
179 # ifdef SOLARIS
180   act.sa_sigaction = (void(*)(int, siginfo_t *, void*)) &SegvHandler ;
181 # endif
182 #endif
183
184   stat = sigaction( SIGSEGV , &act , (struct sigaction*)mySigStates[6]);    // ...... segmentation violation
185
186   myIsActivated = Standard_True;
187 }
188
189
190 //================================================================================
191 /*! Public -
192  * \brief deactivates a signals handling
193  */
194 //================================================================================
195 void CASCatch_CatchSignals::Deactivate() 
196 {
197   if(!myIsActivated) return;
198
199   struct sigaction oact;
200   int stat;
201
202   stat = sigaction(SIGHUP,(struct sigaction*)mySigStates[0],&oact);   // ...... hangup
203   stat = sigaction(SIGFPE,(struct sigaction*)mySigStates[1],&oact);   // ...... floating point exception
204   stat = sigaction(SIGINT,(struct sigaction*)mySigStates[2],&oact);   // ...... interrupt
205   stat = sigaction(SIGQUIT,(struct sigaction*)mySigStates[3],&oact);  // ...... quit
206   stat = sigaction(SIGBUS,(struct sigaction*)mySigStates[4],&oact);   // ...... bus error
207   stat = sigaction(SIGILL,(struct sigaction*)mySigStates[5],&oact);   // ...... illegal instruction
208   stat = sigaction(SIGSEGV,(struct sigaction*)mySigStates[6],&oact);  // ...... segmentation violation
209
210
211   Standard_Integer i = 0;
212   for(; i<=MAX_HANDLER_NUMBER; i++)
213     delete (struct sigaction*)mySigStates[i];
214
215   myIsActivated = Standard_False;
216 }
217
218
219
220 #else
221 //====================================== WNT part ====================================================
222 #include <OSD_WNT_1.hxx>
223
224 #include <process.h>
225 #include <signal.h>
226 #include <float.h>
227
228 #define _OSD_FPX ( _EM_DENORMAL | _EM_INEXACT | _EM_UNDERFLOW | _EM_ZERODIVIDE | _EM_OVERFLOW) //Mask these exceptions
229
230 //================================================================================
231 /*! Private -
232  * \brief handler for unexpected exceptions
233  */
234 //================================================================================
235 static Standard_Integer WntHandler(const Standard_Address theExceptionInfo) 
236 {
237   LPEXCEPTION_POINTERS lpXP = ( LPEXCEPTION_POINTERS )theExceptionInfo;
238   DWORD                dwExceptionCode = lpXP -> ExceptionRecord -> ExceptionCode;
239
240   TCollection_AsciiString aMessage((Standard_Integer)dwExceptionCode);  
241   aMessage+=" Exception code - unexpected exception";
242
243   CASCatch_Failure::Raise(aMessage.ToCString());
244
245   return EXCEPTION_EXECUTE_HANDLER;
246 }
247
248 void SIGWntHandler(int , int ) ;
249 static void (*SIGWNTHANDLER)(int) = ( void (*)(int) ) ( &SIGWntHandler ) ;
250
251
252 //================================================================================
253 /*! Private -
254  * \brief handler for signals
255  */
256 //================================================================================
257 static void SIGWntHandler(const int signum , const int theCode)
258 {
259
260   void (*OLDSIGWNTHANDLER)(int) ;  
261   switch( signum ) { 
262   case SIGFPE : 
263     _fpreset() ;
264     _clearfp() ; 
265     _controlfp ( _OSD_FPX, _MCW_EM ); 
266     OLDSIGWNTHANDLER = signal( signum , SIGWNTHANDLER ); 
267
268     if(theCode == _FPE_UNDERFLOW || theCode == _FPE_INEXACT) return;
269     CASCatch_Failure::Raise ("Floating point error"); 
270     break;
271   case SIGSEGV : 
272     OLDSIGWNTHANDLER = signal( signum , SIGWNTHANDLER );
273     CASCatch_Failure::Raise("Access violation"); 
274     break; 
275   case SIGILL : 
276     OLDSIGWNTHANDLER = signal( signum , SIGWNTHANDLER );
277     CASCatch_Failure::Raise("Illegal instruction" ); 
278     break; 
279   }
280 }
281
282
283 //================================================================================
284 /*! Public -
285  * \brief activates a signals handling
286  */
287 //================================================================================ 
288 void CASCatch_CatchSignals::Activate() 
289 {
290   if(myIsActivated) return;
291
292   mySigStates[0] = SetUnhandledExceptionFilter (( LPTOP_LEVEL_EXCEPTION_FILTER )&WntHandler);
293
294   myFloatOpWord = _controlfp(0, 0);
295   _controlfp ( _OSD_FPX, _MCW_EM );  //Enable floating point exceptions
296
297   mySigStates[1] = signal( SIGSEGV , SIGWNTHANDLER );
298   mySigStates[2] = signal( SIGFPE , SIGWNTHANDLER );
299   mySigStates[3] = signal( SIGILL , SIGWNTHANDLER );
300
301   myIsActivated = Standard_True;
302 }
303
304 //================================================================================
305 /*! Public -
306  * \brief deactivates a signals handling
307  */
308 //================================================================================
309 void CASCatch_CatchSignals::Deactivate() 
310 {
311   if(!myIsActivated) return;
312
313   SetUnhandledExceptionFilter (( LPTOP_LEVEL_EXCEPTION_FILTER )mySigStates[0]);
314
315   _controlfp ( myFloatOpWord, _MCW_EM );
316
317   signal( SIGSEGV ,  ( void (*)(int) )mySigStates[1]);
318   signal( SIGFPE , ( void (*)(int) )mySigStates[2]);
319   signal( SIGILL , ( void (*)(int) )mySigStates[3]);
320
321   Standard_Integer i = 0;
322   for(; i<=MAX_HANDLER_NUMBER; i++)
323     mySigStates[i] = NULL;
324   
325   myIsActivated = Standard_False;
326 }
327
328 #endif
329
330 //================================================================================
331 /*! Private -
332  * \brief deactivates a signals handling
333  */
334 //================================================================================
335 void CASCatch_CatchSignals::Destroy() 
336 {
337   if(myIsActivated) Deactivate();
338 }
339