Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ErrorUtil.hpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File ErrorUtil.hpp
4 //
5 // For more information, please see: http://www.nektar.info
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // License for the specific language governing rights and limitations under
14 // Permission is hereby granted, free of charge, to any person obtaining a
15 // copy of this software and associated documentation files (the "Software"),
16 // to deal in the Software without restriction, including without limitation
17 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 // and/or sell copies of the Software, and to permit persons to whom the
19 // Software is furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included
22 // in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 // DEALINGS IN THE SOFTWARE.
31 //
32 // Description: error related utilities
33 //
34 ///////////////////////////////////////////////////////////////////////////////
35 #ifndef ERRORUTIL_HPP
36 #define ERRORUTIL_HPP
37 
38 #include <iostream>
39 #include <stdexcept>
40 #include <boost/lexical_cast.hpp>
41 #include <boost/optional.hpp>
43 
44 #if defined(NEKTAR_USE_MPI)
45 #include <mpi.h>
46 #endif
47 
48 #ifndef _WIN32
49 #include <execinfo.h>
50 #endif
51 
52 namespace ErrorUtil
53 {
54  static boost::optional<std::ostream&> outStream;
55 
56  inline static void SetErrorStream(std::ostream& o)
57  {
58  outStream = o;
59  }
60 
61  inline static bool HasCustomErrorStream()
62  {
63  return outStream ? true : false;
64  }
65 
66  enum ErrType
67  {
70  };
71 
72  class NekError : public std::runtime_error
73  {
74  public:
75  NekError(const std::string& message) : std::runtime_error(message) {}
76  };
77 
78  inline static void Error(ErrType type, const char *routine, int lineNumber, const char *msg, unsigned int level, bool DoComm = false)
79  {
80  // The user of outStream is primarily for the unit tests.
81  // The unit tests often generate errors on purpose to make sure
82  // invalid usage is flagged appropriately. Printing the error
83  // messages to cerr made the unit test output hard to parse.
84 
85  std::string baseMsg = std::string("Level ") +
86  boost::lexical_cast<std::string>(level) +
87  std::string(" assertion violation\n") +
88 #if defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
89  std::string("Where : ") + boost::lexical_cast<std::string>(routine) + std::string("[") + boost::lexical_cast<std::string>(lineNumber) + std::string("]\n") + std::string("Message : ") +
90 #endif
91  msg;
92 
93  // Default rank is zero. If MPI used and initialised, populate with
94  // the correct rank. Messages are only printed on rank zero.
95  int rank = 0;
96 #if defined(NEKTAR_USE_MPI)
97  int flag = 0;
98  if(DoComm)
99  {
100  MPI_Initialized(&flag);
101  if(flag)
102  {
103  MPI_Comm_rank(MPI_COMM_WORLD,&rank);
104  }
105  }
106 #endif
107 
108  std::string btMessage("");
109 #if defined(NEKTAR_FULLDEBUG)
110 #ifndef _WIN32
111  void *btArray[40];
112  int btSize;
113  char **btStrings;
114 
115  btSize = backtrace(btArray, 40);
116  btStrings = backtrace_symbols(btArray, btSize);
117 
118  for (int i = 0 ; i < btSize ; ++i)
119  {
120  btMessage += std::string(btStrings[i]) + "\n";
121  }
122  free(btStrings);
123 #endif
124 #endif
125 
126  switch (type)
127  {
128  case efatal:
129  if (!rank)
130  {
131  if (outStream)
132  {
133  (*outStream) << btMessage;
134  (*outStream) << "Fatal : " << baseMsg << std::endl;
135  }
136  else
137  {
138  std::cerr << btMessage;
139  std::cerr << std::endl << "Fatal : " << baseMsg
140  << std::endl;
141  }
142  }
143 #if defined(NEKTAR_USE_MPI)
144  if(DoComm)
145  {
146  if (flag)
147  {
148  MPI_Barrier(MPI_COMM_WORLD);
149  }
150  }
151 #endif
152  throw NekError(baseMsg);
153  break;
154  case ewarning:
155  if (!rank)
156  {
157  if (outStream)
158  {
159  (*outStream) << btMessage;
160  (*outStream) << "Warning: " << baseMsg << std::endl;
161  }
162  else
163  {
164  std::cerr << btMessage;
165  std::cerr << "Warning: " << baseMsg << std::endl;
166  }
167  }
168  break;
169  default:
170  std::cerr << "Unknown warning type: " << baseMsg << std::endl;
171  }
172  }
173 
174  inline static void Error(ErrType type, const char *routine, int lineNumber, const std::string& msg, unsigned int level)
175  {
176  Error(type, routine, lineNumber, msg.c_str(), level);
177  }
178 
179  inline static void Error(ErrType type, const char *routine, int lineNumber, const char *msg)
180  {
181  Error(type, routine, lineNumber, msg, 0);
182  }
183 } // end of namespace
184 
185 /// Assert Level 0 -- Fundamental assert which
186 /// is used whether in FULLDEBUG, DEBUG or OPT
187 /// compilation mode. This level assert is
188 /// considered code critical, even under
189 /// optimized compilation.
190 
191 #define NEKERROR(type, msg) \
192  ErrorUtil::Error(type, __FILE__, __LINE__, msg, 0);
193 
194 
195 #define ROOTONLY_NEKERROR(type, msg) \
196  ErrorUtil::Error(type, __FILE__, __LINE__, msg, 0,true);
197 
198 #define ASSERTL0(condition,msg) \
199  if(!(condition)) \
200 { \
201  ErrorUtil::Error(ErrorUtil::efatal, __FILE__, __LINE__, msg, 0); \
202 }
203 
204 #define WARNINGL0(condition,msg) \
205  if(!(condition)) \
206 { \
207  ErrorUtil::Error(ErrorUtil::ewarning, __FILE__, __LINE__, msg, 0); \
208 }
209 
210 
211 /// Assert Level 1 -- Debugging which is used whether in FULLDEBUG or
212 /// DEBUG compilation mode. This level assert is designed for aiding
213 /// in standard debug (-g) mode
214 #if defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
215 
216 #define ASSERTL1(condition,msg) \
217  if(!(condition)) \
218 { \
219  ErrorUtil::Error(ErrorUtil::efatal, __FILE__, __LINE__, msg, 1); \
220 }
221 #define WARNINGL1(condition,msg) \
222  if(!(condition)) \
223 { \
224  ErrorUtil::Error(ErrorUtil::ewarning, __FILE__, __LINE__, msg, 1); \
225 }
226 
227 #else //defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
228 #define ASSERTL1(condition,msg)
229 #define WARNINGL1(condition,msg)
230 #endif //defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
231 
232 
233 /// Assert Level 2 -- Debugging which is used FULLDEBUG compilation
234 /// mode. This level assert is designed to provide addition safety
235 /// checks within the code (such as bounds checking, etc.).
236 #ifdef NEKTAR_FULLDEBUG
237 
238 #define ASSERTL2(condition,msg) \
239  if(!(condition)) \
240 { \
241  ErrorUtil::Error(ErrorUtil::efatal, __FILE__, __LINE__, msg, 2); \
242 }
243 #define WARNINGL2(condition,msg) \
244  if(!(condition)) \
245 { \
246  ErrorUtil::Error(ErrorUtil::ewarning, __FILE__, __LINE__, msg, 2); \
247 }
248 
249 #else //NEKTAR_FULLDEBUG
250 #define ASSERTL2(condition,msg)
251 #define WARNINGL2(condition,msg)
252 #endif //NEKTAR_FULLDEBUG
253 
254 #endif //ERRORUTIL_HPP
255 
NekError(const std::string &message)
Definition: ErrorUtil.hpp:75
STL namespace.
static void Error(ErrType type, const char *routine, int lineNumber, const char *msg, unsigned int level, bool DoComm=false)
Definition: ErrorUtil.hpp:78
static bool HasCustomErrorStream()
Definition: ErrorUtil.hpp:61
static void SetErrorStream(std::ostream &o)
Definition: ErrorUtil.hpp:56
static boost::optional< std::ostream & > outStream
Definition: ErrorUtil.hpp:54
string msg
print "Adding",units.name, hash(units), units.description(), print "(was",id(_u),"now",id(units),")" Ensure referenced units exist
Definition: pycml.py:3834