Dune Core Modules (2.9.0)

duneassert.hh
1#ifndef DUNE_ASSERT_HH
2#define DUNE_ASSERT_HH
3
4#include <cstdlib>
5#include <unistd.h>
6#include <iostream>
7#if HAVE_MPI
8#include <mpi.h>
9#endif
10
11// combination of suggestions made in
12// http://cnicholson.net/2009/02/stupid-c-tricks-adventures-in-assert/
13// and
14// http://www.open-mpi.de/faq/?category=debugging
15
16namespace
17{
18 // Call to stop a program so that it is possible to attach a debugger.
19 // The process id (PID) and calling host are printed to the error stream
20 // If the parameter p is added in a parallel code only the process with
21 // that rank will wait to allow a debugger to attach.
22 //
23 // To attach for example gdb simply call (on the correct host):
24 // gdb -pid PID
25 // you can continue the program by calling at the gdb prompt:
26 // > set var cont = 1
27 // > continue
28 int attach(int p=-1);
29 //
30 // dune_assert( bool ) or dune_assert( bool, p )
31 // This is a special assert like macro that allows a bit more flexibility
32 // then the standard assert. There are three different available
33 // behaviors of a failed dune_assert call:
34 // - If ASSERTATTACH is defined then attach is called with the optional
35 // process rank p, i.e., the assert is ignored except on the process
36 // with rank p.
37 // - If ASSERTATTACH is not defined but ASSERTCONTINUE then the assert
38 // message is printed but the program tries to continue regardless. This
39 // can be usefull for some unit tests
40 // - If neither ASSERTATTACH nor ASSERTCONTINUE is defined then the program
41 // will be aborted.
42 int attach(int p)
43 {
44 int cont = 0;
45 char hostname[256];
46 gethostname(hostname, sizeof(hostname));
47#if HAVE_MPI
48 int mpirank = -1;
49 MPI_Comm_rank(MPI_COMM_WORLD,&mpirank);
50 if (p >= 0 && p != mpirank)
51 {
52 std::cout << "[" << mpirank << "] has PID " << getpid() << " on " << hostname << " continuing" << std::endl;
53 return 1;
54 }
55 else
56 std::cout << "[" << mpirank << "] has PID " << getpid() << " on " << hostname << " ready to attach" << std::endl;
57#else
58 std::cout << "PID " << getpid() << " on " << hostname << " ready to attach" << std::endl;
59#endif
60 while (0 == cont)
61 sleep(5);
62 return 1;
63 }
64
65 // a handle for the dune_assert macro.
66 // The usual output from the C assert (including the mpi rank on a
67 // parallel run) is printed to std::cerr.
68 typedef int (*AssertHandler)(char const*, char const*, int);
69 int default_assert_handler(char const* expr, char const* file, int line)
70 {
71#if HAVE_MPI
72 int mpirank = -1;
73 MPI_Comm_rank(MPI_COMM_WORLD,&mpirank);
74 std::cout << "[" << mpirank << "]: ";
75#endif
76 std::cerr << "Assertion " << expr << " failed in " << file << ":" << line << std::endl;
77 return 1;
78 }
79 AssertHandler assert_handler = default_assert_handler;
80}
81
82
83// the ASSERT_HALT macro is available in three flavours depending on some
84// defines:
85#if defined(ASSERTATTACH)
86#define ASSERT_HALT(p) attach(p)
87#elif defined(ASSERTCONTINUE)
88#define ASSERT_HALT(p) ((void)sizeof(p)), std::cout << "... trying to continue ..." << std::endl
89#else
90#define ASSERT_HALT(p) ((void)sizeof(p)), abort()
91#endif
92
93// The actual implementation fo the dune_assert macro
94#ifndef NDEBUG
95#define dune_assert_(x,p) ((void)(!(x) && assert_handler(#x, __FILE__, __LINE__) && (ASSERT_HALT(p), 1)))
96#else
97#define dune_assert_(x,p) ((void)sizeof(x),sizeof(p))
98#endif
99
100// Allow for calling dune_assert with one or two arguments
101#define dune_assert0_(x) dune_assert_(x,-1)
102#define dune_assert1_(x,p) dune_assert_(x,p)
103#define GET_ASSERT_MACRO(_1,_2,NAME,...) NAME
104#define dune_assert(...) GET_ASSERT_MACRO(__VA_ARGS__, dune_assert1_, dune_assert0_)(__VA_ARGS__)
105
106#endif
constexpr GeometryType line
GeometryType representing a line.
Definition: type.hh:512
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Dec 21, 23:30, 2024)