OpenCMISS-Iron Internal API Documentation
cmiss_c.c
Go to the documentation of this file.
1 /* \file
2  * \author Chris Bradley
3  * \brief This file contains system level routines.
4  *
5  * \section LICENSE
6  *
7  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
8  *
9  * The contents of this file are subject to the Mozilla Public License
10  * Version 1.1 (the "License"); you may not use this file except in
11  * compliance with the License. You may obtain a copy of the License at
12  * http://www.mozilla.org/MPL/
13  *
14  * Software distributed under the License is distributed on an "AS IS"
15  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
16  * License for the specific language governing rights and limitations
17  * under the License.
18  *
19  * The Original Code is OpenCMISS
20  *
21  * The Initial Developer of the Original Code is University of Auckland,
22  * Auckland, New Zealand, the University of Oxford, Oxford, United
23  * Kingdom and King's College, London, United Kingdom. Portions created
24  * by the University of Auckland, the University of Oxford and King's
25  * College, London are Copyright (C) 2007-2010 by the University of
26  * Auckland, the University of Oxford and King's College, London.
27  * All Rights Reserved.
28  *
29  * Contributor(s):
30  *
31  * Alternatively, the contents of this file may be used under the terms of
32  * either the GNU General Public License Version 2 or later (the "GPL"), or
33  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
34  * in which case the provisions of the GPL or the LGPL are applicable instead
35  * of those above. If you wish to allow use of your version of this file only
36  * under the terms of either the GPL or the LGPL, and not to allow others to
37  * use your version of this file under the terms of the MPL, indicate your
38  * decision by deleting the provisions above and replace them with the notice
39  * and other provisions required by the GPL or the LGPL. If you do not delete
40  * the provisions above, a recipient may use your version of this file under
41  * the terms of any one of the MPL, the GPL or the LGPL.
42  *
43  */
44 
45 /* Included files */
46 
47 #include <signal.h>
48 #include <stdio.h>
49 #include <stdlib.h>
50 
51 #include "cmiss.h"
52 
53 /* Type definitions */
54 
55 /* Function prototypes */
56 
57 void cmfe_ResetFatalHandler(void);
58 
59 void cmfe_SetFatalHandler(void);
60 
61 void cmfe_InitFatalHandler(void);
62 
63 /* Internal functions */
64 static void cmfe_FatalHandler(int sig
65 #if defined (sun)
66  ,siginfo_t *sip,
67  ucontext_t *uap
68 #else
69  #ifndef __MINGW32__
70  ,int code
71  #if defined(_AIX)
72  ,struct sigcontext *sc
73  #endif
74  #endif
75 #endif
76  );
77 
78 /* Static variables */
79 
80 /* static sigjmp_buf jump_buffer; */
81 static struct sigaction fatal_sigaction;
82 static struct sigaction old_SIGBUS_action;
83 #ifdef SIGEMT
84 static struct sigaction old_SIGEMT_action;
85 #endif
86 static struct sigaction old_SIGFPE_action;
87 static struct sigaction old_SIGILL_action;
88 static struct sigaction old_SIGINT_action;
89 static struct sigaction old_SIGABRT_action;
90 static struct sigaction old_SIGSEGV_action;
91 static struct sigaction old_SIGTRAP_action;
92 
94 {
95 #if defined (SIGBUS)
96  if( 0 != sigaction(SIGBUS,&old_SIGBUS_action,NULL) )
97  {
98  fprintf(stderr,">>WARNING: Could not reset SIGBUS handler.\n");
99  }
100 #endif /* defined (SIGBUS) */
101 #ifdef SIGEMT
102  if( 0 != sigaction(SIGEMT,&old_SIGEMT_action,NULL) )
103  {
104  fprintf(stderr,">>WARNING: Could not reset SIGEMT handler.\n");
105  }
106 #endif
107  if( 0 != sigaction(SIGFPE,&old_SIGFPE_action,NULL) )
108  {
109  fprintf(stderr,">>WARNING: Could not reset SIGFPE handler.\n");
110  }
111  if( 0 != sigaction(SIGILL,&old_SIGILL_action,NULL) )
112  {
113  fprintf(stderr,">>WARNING: Could not reset SIGILL handler.\n");
114  }
115  if( 0 != sigaction(SIGINT,&old_SIGINT_action,NULL) )
116  {
117  fprintf(stderr,">>WARNING: Could not reset SIGINT handler.\n");
118  }
119  if( 0 != sigaction(SIGABRT,&old_SIGABRT_action,NULL) )
120  {
121  fprintf(stderr,">>WARNING: Could not reset SIGABRT handler.\n");
122  }
123  if( 0 != sigaction(SIGSEGV,&old_SIGSEGV_action,NULL) )
124  {
125  fprintf(stderr,">>WARNING: Could not reset SIGSEGV handler.\n");
126  }
127 #if defined (SIGTRAP)
128  if( 0 != sigaction(SIGTRAP,&old_SIGTRAP_action,NULL) )
129  {
130  fprintf(stderr,">>WARNING: Could not reset SIGTRAP handler.\n");
131  }
132 #endif /* defined (SIGTRAP) */
133 }
134 
136 {
137 #if (defined (unix) || defined (_AIX)) && !defined(__MINGW32__)
138 #if defined (SIGBUS)
139  if( 0 != sigaction(SIGBUS,&fatal_sigaction,NULL) )
140  {
141  fprintf(stderr,">>WARNING: Could not set SIGBUS handler.\n");
142  }
143 #endif /* defined (SIGBUS) */
144 #ifdef SIGEMT
145  if( 0 != sigaction(SIGEMT,&fatal_sigaction,NULL) )
146  {
147  fprintf(stderr,">>WARNING: could not set SIGEMT handler.\n");
148  }
149 #endif
150  if( 0 != sigaction(SIGFPE,&fatal_sigaction,NULL) )
151  {
152  fprintf(stderr,">>WARNING: could not set SIGFPE handler.\n");
153  }
154  if( 0 != sigaction(SIGILL,&fatal_sigaction,NULL) )
155  {
156  fprintf(stderr,">>WARNING: could not set SIGILL handler.\n");
157  }
158  if( 0 != sigaction(SIGINT,&fatal_sigaction,NULL) )
159  {
160  fprintf(stderr,">>WARNING: could not set SIGINT handler.\n");
161  }
162  if( 0 != sigaction(SIGABRT,&fatal_sigaction,NULL) )
163  {
164  fprintf(stderr,">>WARNING: could not set SIGABRT handler.\n");
165  }
166  if( 0 != sigaction(SIGSEGV,&fatal_sigaction,NULL) )
167  {
168  fprintf(stderr,">>WARNING: could not set SIGSEGV handler.\n");
169  }
170 #if defined (SIGTRAP)
171  if( 0 != sigaction(SIGTRAP,&fatal_sigaction,NULL) )
172  {
173  fprintf(stderr,">>WARNING: could not set SIGTRAP handler.\n");
174  }
175 #endif /* defined (SIGTRAP) */
176 #endif /* defined (unix) || defined (_AIX) */
177 }
178 
179 static void cmfe_FatalHandler(int sig
180 #if defined (sun)
181  ,siginfo_t *sip,
182  ucontext_t *uap
183 #else
184  #ifndef __MINGW32__
185  ,int code
186  #if defined(_AIX)
187  ,struct sigcontext *sc
188  #endif
189  #endif
190 #endif
191  )
192 {
193 
194 #if defined(_AIX)
195  /* this from libxlf90.a provides a good description of what went wrong */
196  xl__sigdump(sig,code,sc);
197 #else
198  switch(sig)
199  {
200 #if defined (SIGBUS)
201  case SIGBUS:
202  {
203  fprintf(stderr,">>FATAL ERROR: Bus error occurred.\n");
204  } break;
205 #endif /* defined (SIGBUS) */
206 #if defined (SIGEMT)
207  case SIGEMT:
208  {
209  fprintf(stderr,">>FATAL ERROR: EMT occurred.\n");
210  } break;
211 #endif /* defined (SIGEMT) */
212  case SIGFPE:
213  {
214  fprintf(stderr,">>FATAL ERROR: Floating point execption occurred.\n");
215  } break;
216  case SIGILL:
217  {
218  fprintf(stderr,">>FATAL ERROR: Illegal instruction occurred.\n");
219  } break;
220  case SIGINT:
221  {
222  fprintf(stderr,">>FATAL ERROR: Interrupt occurred.\n");
223  } break;
224  case SIGABRT:
225  {
226  fprintf(stderr,">>FATAL ERROR: Abort occurred.\n");
227  } break;
228  case SIGSEGV:
229  {
230  fprintf(stderr,">>FATAL ERROR: Segment violation occurred.\n");
231  } break;
232 #if defined (SIGTRAP)
233  case SIGTRAP:
234  {
235  fprintf(stderr,">>FATAL ERROR: Trace trap occurred.\n");
236  } break;
237 #endif /* defined (SIGTRAP) */
238  default:
239  {
240  fprintf(stderr,">>FATAL ERROR: Unknown signal %d occurred.\n"
241 #ifndef __MINGW32__
242  ,code
243 #endif
244  );
245  } break;
246  }
247 #endif
248 
249  /* There is an issue with signal handling in a library such as OpenCMISS. The best option would be to
250  jump back to where the user called an OpenCMISS routine and let them process the error if that is
251  what they wish. This, however, would require setting the long jump buffer at each entry point to the
252  OpenCMISS library. This could be done by modifying enters in opencmiss.f90 but may cause performance
253  problems (probably not too bad as the major computations are inside the library rather than at the
254  interface). For now just stop the program on a signal. */
255 
256  /* siglongjmp(jump_buffer,sig); */
257 
258  exit(sig);
259 }
260 
262 {
263  fatal_sigaction.sa_flags = SA_NODEFER;
264  fatal_sigaction.sa_handler = (void (*)(int))cmfe_FatalHandler;
265  if( 0 != sigemptyset(&fatal_sigaction.sa_mask) )
266  {
267  fprintf(stderr,">>WARNING: sigemptyset failed in CMISSInitFatalHandler.\n");
268  }
269 
270 #if defined (SIGBUS)
271  sigaction(SIGBUS,NULL,&old_SIGBUS_action);
272 #endif /* defined (SIGBUS) */
273 #if defined (SIGEMT)
274  sigaction(SIGEMT,NULL,&old_SIGEMT_action);
275 #endif /* defined (SIGEMT) */
276  sigaction(SIGFPE,NULL,&old_SIGFPE_action);
277  sigaction(SIGILL,NULL,&old_SIGILL_action);
278  sigaction(SIGINT,NULL,&old_SIGINT_action);
279  sigaction(SIGABRT,NULL,&old_SIGABRT_action);
280  sigaction(SIGSEGV,NULL,&old_SIGSEGV_action);
281 #if defined (SIGTRAP)
282  sigaction(SIGTRAP,NULL,&old_SIGTRAP_action);
283 #endif /* defined (SIGTRAP) */
284 }
285 
static struct sigaction old_SIGILL_action
Definition: cmiss_c.c:87
static struct sigaction old_SIGSEGV_action
Definition: cmiss_c.c:90
static struct sigaction old_SIGTRAP_action
Definition: cmiss_c.c:91
static struct sigaction old_SIGABRT_action
Definition: cmiss_c.c:89
static struct sigaction old_SIGBUS_action
Definition: cmiss_c.c:82
void cmfe_ResetFatalHandler(void)
Definition: cmiss_c.c:93
void cmfe_InitFatalHandler(void)
Definition: cmiss_c.c:261
static void cmfe_FatalHandler(int sig, int code)
Definition: cmiss_c.c:179
void cmfe_SetFatalHandler(void)
Definition: cmiss_c.c:135
static struct sigaction old_SIGFPE_action
Definition: cmiss_c.c:86
static struct sigaction old_SIGINT_action
Definition: cmiss_c.c:88
static struct sigaction fatal_sigaction
Definition: cmiss_c.c:81