MFEM  v3.3
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
error.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
2 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
3 // reserved. See file COPYRIGHT for details.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability see http://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the GNU Lesser General Public License (as published by the Free
10 // Software Foundation) version 2.1 dated February 1999.
11 
12 #include "error.hpp"
13 #include "array.hpp"
14 #include <cstdlib>
15 #include <iostream>
16 
17 #ifdef MFEM_USE_LIBUNWIND
18 #define UNW_LOCAL_ONLY
19 #define UNW_NAME_LEN 512
20 #include <libunwind.h>
21 #include <cxxabi.h>
22 #if defined(__APPLE__) || defined(__linux__)
23 #ifndef _GNU_SOURCE
24 #define _GNU_SOURCE
25 #endif
26 #include <dlfcn.h>
27 #endif
28 #endif // MFEM_USE_LIBUNWIND
29 
30 #ifdef MFEM_USE_MPI
31 #include <mpi.h>
32 #endif
33 
34 namespace mfem
35 {
36 
37 void mfem_backtrace(int mode, int depth)
38 {
39 #ifdef MFEM_USE_LIBUNWIND
40  char name[UNW_NAME_LEN];
41  unw_cursor_t cursor;
42  unw_context_t uc;
43  unw_word_t ip, offp;
44 
45  int err = unw_getcontext(&uc);
46  err = err ? err : unw_init_local(&cursor, &uc);
47 
48  Array<unw_word_t> addrs;
49  while (unw_step(&cursor) > 0 && addrs.Size() != depth)
50  {
51  err = err ? err : unw_get_proc_name(&cursor, name, UNW_NAME_LEN, &offp);
52  err = err ? err : unw_get_reg(&cursor, UNW_REG_IP, &ip);
53  if (err) { break; }
54  char *name_p = name;
55  int demangle_status;
56 
57  // __cxa_demangle is not standard, but works with GCC, Intel, PGI, Clang
58  char *name_demangle =
59  abi::__cxa_demangle(name, NULL, NULL, &demangle_status);
60  if (demangle_status == 0) // use mangled name if something goes wrong
61  {
62  name_p = name_demangle;
63  }
64 
65  std::cerr << addrs.Size() << ") [0x" << std::hex << ip - 1 << std::dec
66  << "]: " << name_p << std::endl;
67  addrs.Append(ip - 1);
68 
69  if (demangle_status == 0)
70  {
71  free(name_demangle);
72  }
73  }
74 #if defined(__APPLE__) || defined(__linux__)
75  if (addrs.Size() > 0 && (mode & 1))
76  {
77  std::cerr << "\nLookup backtrace source lines:";
78  const char *fname = NULL;
79  for (int i = 0; i < addrs.Size(); i++)
80  {
81  Dl_info info;
82  err = !dladdr((void*)addrs[i], &info);
83  if (err)
84  {
85  fname = "<exe>";
86  }
87  else if (fname != info.dli_fname)
88  {
89  fname = info.dli_fname;
90  std::cerr << '\n';
91 #ifdef __linux__
92  std::cerr << "addr2line -C -e " << fname;
93 #else
94  std::cerr << "atos -o " << fname << " -l "
95  << (err ? 0 : info.dli_fbase);
96 #endif
97  }
98  std::cerr << " 0x" << addrs[i];
99  }
100  std::cerr << '\n';
101  }
102 #endif
103 #endif // MFEM_USE_LIBUNWIND
104 }
105 
106 void mfem_error(const char *msg)
107 {
108  if (msg)
109  {
110  // NOTE: By default, each call of the "operator <<" method of the
111  // std::cerr object results in flushing the I/O stream, which can be a
112  // very bad thing if all your processors try to do it at the same time.
113  std::cerr << "\n\n" << msg << "\n";
114  }
115 
116 #ifdef MFEM_USE_LIBUNWIND
117  std::cerr << "Backtrace:" << std::endl;
118  mfem_backtrace(1, -1);
119  std::cerr << std::endl;
120 #endif
121 
122 #ifdef MFEM_USE_MPI
123  int flag;
124  MPI_Initialized(&flag);
125  if (flag) { MPI_Abort(MPI_COMM_WORLD, 1); }
126 #endif
127  std::abort(); // force crash by calling abort
128 }
129 
130 void mfem_warning(const char *msg)
131 {
132  if (msg)
133  {
134  std::cout << "\n\n" << msg << std::endl;
135  }
136 }
137 
138 }
int Size() const
Logical size of the array.
Definition: array.hpp:109
void mfem_warning(const char *msg)
Definition: error.cpp:130
int Append(const T &el)
Append element to array, resize if necessary.
Definition: array.hpp:394
void mfem_error(const char *msg)
Definition: error.cpp:106
void mfem_backtrace(int mode, int depth)
Definition: error.cpp:37