Back to index

salome-gui  6.5.0
CASCatch_CatchSignals.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 // File   : CASCatch_CatchSignals.cxx
00024 // Author : Sergey RUIN, Open CASCADE S.A.S (sergey.ruin@opencascade.com)
00025 //
00026 #include "CASCatch_CatchSignals.hxx"
00027 
00028 #include "CASCatch_Failure.hxx"  
00029 #include "CASCatch_ErrorHandler.hxx"
00030 #include <TCollection_AsciiString.hxx>
00031 
00032 #define MAX_HANDLER_NUMBER 6
00033 
00034 
00035 //================================================================================
00039 //================================================================================ 
00040 CASCatch_CatchSignals::CASCatch_CatchSignals() 
00041      :myIsActivated(Standard_False)
00042 {
00043 
00044   Standard_Integer i = 0;
00045   for(; i<=MAX_HANDLER_NUMBER; i++)
00046     mySigStates[i] = NULL;
00047 }
00048 
00049 #ifndef WNT
00050 
00051 //================================ UNIX part ==================================================
00052 
00053 #include <OSD.hxx>
00054 #include <OSD_WhoAmI.hxx>
00055 #include <OSD_SIGHUP.hxx>
00056 #include <OSD_SIGINT.hxx>
00057 #include <OSD_SIGQUIT.hxx>
00058 #include <OSD_SIGILL.hxx>
00059 #include <OSD_SIGKILL.hxx>
00060 #include <OSD_SIGBUS.hxx>
00061 #include <OSD_SIGSEGV.hxx>
00062 #include <OSD_SIGSYS.hxx>
00063 #ifndef LIN
00064 #include <exception.h>
00065 #endif
00066 
00067 //==============================
00068 typedef void (ACT_SIGIO_HANDLER)(void) ;
00069 
00070 ACT_SIGIO_HANDLER *ADR_ACT_SIGIO_HANDLER = NULL ;
00071 
00072 typedef void (* SIG_PFV) (int);
00073 
00074 #ifdef SUN
00075 # include <floatingpoint.h>
00076 #endif
00077 
00078 #ifdef SOLARIS
00079 # include <floatingpoint.h>
00080 # include <sys/machsig.h>
00081 # include <stdlib.h>
00082 # include <stdio.h>
00083 #endif
00084 
00085 #include <signal.h>
00086 #include <sys/signal.h>
00087 
00088 #ifdef LIN
00089 # include <stdlib.h>
00090 # include <stdio.h>
00091 #else
00092 # ifdef SA_SIGINFO 
00093 #   ifndef AIX
00094 # include <sys/siginfo.h>
00095 #    endif
00096 # endif
00097 #endif
00098 
00099 
00100 #ifdef IRIX
00101 # include <sigfpe.h>
00102 # include <sys/siginfo.h>
00103 #endif 
00104 
00105 
00106 //================================================================================
00110 //================================================================================ 
00111 static void Handler(const OSD_Signals theSig, const OSD_Signals)
00112 {
00113   sigset_t set;
00114   sigemptyset(&set);
00115   sigaddset(&set, theSig);
00116   sigprocmask(SIG_UNBLOCK, &set, NULL) ;
00117 
00118   TCollection_AsciiString aMessage(theSig);  
00119   aMessage+=" signal detected";
00120  
00121   CASCatch_Failure::Raise(aMessage.ToCString());
00122 }
00123 
00124 
00125 #ifdef SA_SIGINFO
00126 //================================================================================
00130 //================================================================================ 
00131 static void SegvHandler(const OSD_Signals, const Standard_Address, const Standard_Address)
00132 {
00133   sigset_t set;
00134   sigemptyset(&set);
00135   sigaddset(&set, SIGSEGV);
00136   sigprocmask (SIG_UNBLOCK, &set, NULL); 
00137 
00138   CASCatch_Failure::Raise("SIGSEGV detected");
00139 }
00140 #endif
00141 
00142 
00143 //================================================================================
00147 //================================================================================ 
00148 void CASCatch_CatchSignals::Activate() 
00149 {  
00150   if(myIsActivated) return;
00151 
00152   struct sigaction act;
00153 
00154   Standard_Integer i = 0;
00155   for(; i<=MAX_HANDLER_NUMBER; i++)  
00156     mySigStates[i] = new struct sigaction(); //Initialize structures
00157 
00158   int stat;
00159   act.sa_handler =  (SIG_PFV) &Handler ;
00160   sigemptyset(&act.sa_mask) ;
00161 
00162 
00163   stat = sigaction(SIGHUP,&act,(struct sigaction*)mySigStates[0]);    // ...... hangup
00164   stat = sigaction(SIGFPE,&act,(struct sigaction*) mySigStates[1]);   // ...... floating point exception
00165   stat = sigaction(SIGINT,&act,(struct sigaction*)mySigStates[2]);   // ...... interrupt
00166   stat = sigaction(SIGQUIT,&act,(struct sigaction*)mySigStates[3]);  // ...... quit
00167   stat = sigaction(SIGBUS,&act,(struct sigaction*)mySigStates[4]);   // ...... bus error
00168   stat = sigaction(SIGILL,&act,(struct sigaction*)mySigStates[5]);   // ...... illegal instruction
00169 
00170 #ifdef SA_RESTART
00171   act.sa_flags   = SA_RESTART ;
00172 #else
00173   act.sa_flags   = 0 ;
00174 #endif
00175   act.sa_handler = (SIG_PFV) &SegvHandler ;
00176 
00177 #ifdef SA_SIGINFO       // OSF,SOLARIS,IRIX
00178   act.sa_flags = act.sa_flags | SA_SIGINFO ;
00179 # ifdef SOLARIS
00180   act.sa_sigaction = (void(*)(int, siginfo_t *, void*)) &SegvHandler ;
00181 # endif
00182 #endif
00183 
00184   stat = sigaction( SIGSEGV , &act , (struct sigaction*)mySigStates[6]);    // ...... segmentation violation
00185 
00186   myIsActivated = Standard_True;
00187 }
00188 
00189 
00190 //================================================================================
00194 //================================================================================
00195 void CASCatch_CatchSignals::Deactivate() 
00196 {
00197   if(!myIsActivated) return;
00198 
00199   struct sigaction oact;
00200   int stat;
00201 
00202   stat = sigaction(SIGHUP,(struct sigaction*)mySigStates[0],&oact);   // ...... hangup
00203   stat = sigaction(SIGFPE,(struct sigaction*)mySigStates[1],&oact);   // ...... floating point exception
00204   stat = sigaction(SIGINT,(struct sigaction*)mySigStates[2],&oact);   // ...... interrupt
00205   stat = sigaction(SIGQUIT,(struct sigaction*)mySigStates[3],&oact);  // ...... quit
00206   stat = sigaction(SIGBUS,(struct sigaction*)mySigStates[4],&oact);   // ...... bus error
00207   stat = sigaction(SIGILL,(struct sigaction*)mySigStates[5],&oact);   // ...... illegal instruction
00208   stat = sigaction(SIGSEGV,(struct sigaction*)mySigStates[6],&oact);  // ...... segmentation violation
00209 
00210 
00211   Standard_Integer i = 0;
00212   for(; i<=MAX_HANDLER_NUMBER; i++)
00213     delete (struct sigaction*)mySigStates[i];
00214 
00215   myIsActivated = Standard_False;
00216 }
00217 
00218 
00219 
00220 #else
00221 //====================================== WNT part ====================================================
00222 #include <OSD_WNT_1.hxx>
00223 
00224 #include <process.h>
00225 #include <signal.h>
00226 #include <float.h>
00227 
00228 #define _OSD_FPX ( _EM_DENORMAL | _EM_INEXACT | _EM_UNDERFLOW | _EM_ZERODIVIDE | _EM_OVERFLOW) //Mask these exceptions
00229 
00230 //================================================================================
00234 //================================================================================
00235 static Standard_Integer WntHandler(const Standard_Address theExceptionInfo) 
00236 {
00237   LPEXCEPTION_POINTERS lpXP = ( LPEXCEPTION_POINTERS )theExceptionInfo;
00238   DWORD                dwExceptionCode = lpXP -> ExceptionRecord -> ExceptionCode;
00239 
00240   TCollection_AsciiString aMessage((Standard_Integer)dwExceptionCode);  
00241   aMessage+=" Exception code - unexpected exception";
00242 
00243   CASCatch_Failure::Raise(aMessage.ToCString());
00244 
00245   return EXCEPTION_EXECUTE_HANDLER;
00246 }
00247 
00248 void SIGWntHandler(int , int ) ;
00249 static void (*SIGWNTHANDLER)(int) = ( void (*)(int) ) ( &SIGWntHandler ) ;
00250 
00251 
00252 //================================================================================
00256 //================================================================================
00257 static void SIGWntHandler(const int signum , const int theCode)
00258 {
00259 
00260   void (*OLDSIGWNTHANDLER)(int) ;  
00261   switch( signum ) { 
00262   case SIGFPE : 
00263     _fpreset() ;
00264     _clearfp() ; 
00265     _controlfp ( _OSD_FPX, _MCW_EM ); 
00266     OLDSIGWNTHANDLER = signal( signum , SIGWNTHANDLER ); 
00267 
00268     if(theCode == _FPE_UNDERFLOW || theCode == _FPE_INEXACT) return;
00269     CASCatch_Failure::Raise ("Floating point error"); 
00270     break;
00271   case SIGSEGV : 
00272     OLDSIGWNTHANDLER = signal( signum , SIGWNTHANDLER );
00273     CASCatch_Failure::Raise("Access violation"); 
00274     break; 
00275   case SIGILL : 
00276     OLDSIGWNTHANDLER = signal( signum , SIGWNTHANDLER );
00277     CASCatch_Failure::Raise("Illegal instruction" ); 
00278     break; 
00279   }
00280 }
00281 
00282 
00283 //================================================================================
00287 //================================================================================ 
00288 void CASCatch_CatchSignals::Activate() 
00289 {
00290   if(myIsActivated) return;
00291 
00292   mySigStates[0] = SetUnhandledExceptionFilter (( LPTOP_LEVEL_EXCEPTION_FILTER )&WntHandler);
00293 
00294   myFloatOpWord = _controlfp(0, 0);
00295   _controlfp ( _OSD_FPX, _MCW_EM );  //Enable floating point exceptions
00296 
00297   mySigStates[1] = signal( SIGSEGV , SIGWNTHANDLER );
00298   mySigStates[2] = signal( SIGFPE , SIGWNTHANDLER );
00299   mySigStates[3] = signal( SIGILL , SIGWNTHANDLER );
00300 
00301   myIsActivated = Standard_True;
00302 }
00303 
00304 //================================================================================
00308 //================================================================================
00309 void CASCatch_CatchSignals::Deactivate() 
00310 {
00311   if(!myIsActivated) return;
00312 
00313   SetUnhandledExceptionFilter (( LPTOP_LEVEL_EXCEPTION_FILTER )mySigStates[0]);
00314 
00315   _controlfp ( myFloatOpWord, _MCW_EM );
00316 
00317   signal( SIGSEGV ,  ( void (*)(int) )mySigStates[1]);
00318   signal( SIGFPE , ( void (*)(int) )mySigStates[2]);
00319   signal( SIGILL , ( void (*)(int) )mySigStates[3]);
00320 
00321   Standard_Integer i = 0;
00322   for(; i<=MAX_HANDLER_NUMBER; i++)
00323     mySigStates[i] = NULL;
00324   
00325   myIsActivated = Standard_False;
00326 }
00327 
00328 #endif
00329 
00330 //================================================================================
00334 //================================================================================
00335 void CASCatch_CatchSignals::Destroy() 
00336 {
00337   if(myIsActivated) Deactivate();
00338 }
00339