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