Line data Source code
1 : // The libMesh Finite Element Library. 2 : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 3 : 4 : // This library is free software; you can redistribute it and/or 5 : // modify it under the terms of the GNU Lesser General Public 6 : // License as published by the Free Software Foundation; either 7 : // version 2.1 of the License, or (at your option) any later version. 8 : 9 : // This library is distributed in the hope that it will be useful, 10 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 : // Lesser General Public License for more details. 13 : 14 : // You should have received a copy of the GNU Lesser General Public 15 : // License along with this library; if not, write to the Free Software 16 : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 : 18 : 19 : // libmesh includes 20 : #include "libmesh/libmesh.h" 21 : #include "libmesh/libmesh_common.h" 22 : #include "libmesh/print_trace.h" 23 : #include "libmesh/threads.h" 24 : 25 : // C/C++ includes 26 : #ifdef LIBMESH_HAVE_SYS_TYPES_H 27 : #include <sys/types.h> 28 : #endif 29 : #ifdef LIBMESH_HAVE_UNISTD_H 30 : #include <unistd.h> // needed for getpid() 31 : #endif 32 : 33 : #ifdef LIBMESH_HAVE_CSIGNAL 34 : #include <csignal> 35 : #endif 36 : 37 : #if defined(LIBMESH_HAVE_GCC_ABI_DEMANGLE) 38 : #include <cxxabi.h> 39 : #include <cstdlib> 40 : #endif 41 : 42 : namespace libMesh 43 : { 44 : 45 : namespace MacroFunctions 46 : { 47 2024 : void here(const char * file, int line, const char * date, const char * time, std::ostream & os) 48 : { 49 2024 : os << "[" << static_cast<std::size_t>(libMesh::global_processor_id()) << "] " 50 : << file 51 2024 : << ", line " << line 52 : << ", compiled " << date 53 2154 : << " at " << time 54 69 : << std::endl; 55 2024 : } 56 : 57 : 58 : 59 0 : void stop(const char * file, int line, const char * date, const char * time) 60 : { 61 0 : if (libMesh::global_n_processors() == 1) 62 : { 63 0 : libMesh::MacroFunctions::here(file, line, date, time); 64 : #if defined(LIBMESH_HAVE_CSIGNAL) && defined(SIGSTOP) 65 0 : libMesh::out << "Stopping process " << getpid() << "..." << std::endl; 66 0 : std::raise(SIGSTOP); 67 0 : libMesh::out << "Continuing process " << getpid() << "..." << std::endl; 68 : #else 69 : libMesh::out << "WARNING: libmesh_stop() does not work; no operating system support." << std::endl; 70 : #endif 71 : } 72 0 : } 73 : 74 : 75 : Threads::spin_mutex report_error_spin_mtx; 76 : 77 1752 : void report_error(const char * file, int line, const char * date, const char * time, std::ostream & os) 78 : { 79 : // Avoid a race condition on that static bool 80 59 : Threads::spin_mutex::scoped_lock lock(report_error_spin_mtx); 81 : 82 : // It is possible to have an error *inside* report_error; e.g. from 83 : // print_trace. We don't want to infinitely recurse. 84 : static bool reporting_error = false; 85 1752 : if (reporting_error) 86 : { 87 : // I heard you like error reporting, so we put an error report 88 : // in report_error() so you can report errors from the report. 89 0 : os << "libMesh encountered an error while attempting to report_error." << std::endl; 90 0 : return; 91 : } 92 1752 : reporting_error = true; 93 : 94 1866 : if (libMesh::global_n_processors() == 1 || 95 3502 : libMesh::on_command_line("--print-trace")) 96 57 : libMesh::print_trace(os); 97 : else 98 1695 : libMesh::write_traceout(); 99 1752 : libMesh::MacroFunctions::here(file, line, date, time, os); 100 : 101 1752 : reporting_error = false; 102 : } 103 : 104 : } // namespace MacroFunctions 105 : 106 : // demangle() is used by the process_trace() helper function. It is 107 : // also used by the Parameters class and cast_xxx functions for demangling typeid's. If 108 : // configure determined that your compiler does not support 109 : // demangling, it simply returns the input string. 110 : #if defined(LIBMESH_HAVE_GCC_ABI_DEMANGLE) 111 2947 : std::string demangle(const char * name) 112 : { 113 2947 : int status = 0; 114 2947 : std::string ret = name; 115 : 116 : // Actually do the demangling 117 2947 : char * demangled_name = abi::__cxa_demangle(name, 0, 0, &status); 118 : 119 : // If demangling returns non-nullptr, save the result in a string. 120 2947 : if (demangled_name) 121 989 : ret = demangled_name; 122 : 123 : // According to cxxabi.h docs, the caller is responsible for 124 : // deallocating memory. 125 2947 : std::free(demangled_name); 126 : 127 3995 : return ret; 128 : } 129 : #else 130 : std::string demangle(const char * name) { return std::string(name); } 131 : #endif 132 : 133 : } // namespace libMesh