45 #include "libmesh/libmesh_config.h"
46 #include "libmesh/print_trace.h"
47 #include "libmesh/libmesh.h"
49 #ifdef LIBMESH_HAVE_UNISTD_H
50 #include <sys/types.h>
54 #ifdef LIBMESH_HAVE_PROCESS_H
63 #ifndef LIBMESH_HAVE_MKSTEMP
67 #if defined(LIBMESH_HAVE_GLIBC_BACKTRACE)
71 #if defined(LIBMESH_HAVE_GCC_ABI_DEMANGLE)
83 #if defined(LIBMESH_HAVE_GLIBC_BACKTRACE)
84 std::string process_trace(
const char * name)
86 std::string fullname = name;
87 std::string saved_begin, saved_end;
88 size_t namestart, nameend;
96 namestart = fullname.find(
"0x");
97 if (namestart != std::string::npos)
99 namestart = fullname.find(
' ', namestart) + 1;
100 saved_begin = fullname.substr(0, namestart);
104 nameend = fullname.find(
'+');
105 if (nameend == std::string::npos ||
106 nameend <= namestart)
107 nameend = fullname.size();
111 saved_end = fullname.substr(nameend, fullname.length());
114 namestart = fullname.find(
'(');
115 if (namestart == std::string::npos)
119 nameend = fullname.find(
'+');
120 if (nameend == std::string::npos ||
121 nameend <= namestart)
125 std::string type_name = fullname.substr(namestart, nameend - namestart);
138 bool gdb_backtrace(std::ostream & out_stream)
140 #ifdef LIBMESH_GDB_COMMAND
147 char temp_file[] =
"temp_print_trace.XXXXXX";
157 auto this_pid = getpid();
163 std::string gdb_command =
166 std::ostringstream command;
167 command << gdb_command
170 <<
" -batch -ex bt -ex detach 2>/dev/null 1>"
172 exit_status = std::system(command.str().c_str());
176 std::cerr <<
"Unable to run gdb" << std::endl;
184 std::ifstream fin(temp_file);
185 if (fin && (fin.peek() != std::ifstream::traits_type::eof()) && (exit_status == 0))
186 out_stream << fin.rdbuf();
192 std::remove(temp_file);
213 bool gdb_worked =
false;
217 if ((std::string(LIBMESH_GDB_COMMAND) != std::string(
"no") &&
220 gdb_worked = gdb_backtrace(out_stream);
225 #if defined(LIBMESH_HAVE_GLIBC_BACKTRACE)
228 void * addresses[40];
231 int size = backtrace(addresses, 40);
232 strings = backtrace_symbols(addresses, size);
233 out_stream <<
"Stack frames: " << size << std::endl;
234 for (
int i = 0; i < size; i++)
235 out_stream << i <<
": " << process_trace(strings[i]) << std::endl;
246 #ifdef LIBMESH_ENABLE_TRACEFILES
247 std::stringstream outname;
249 std::ofstream traceout(outname.str().c_str(), std::ofstream::app);
260 #if defined(LIBMESH_HAVE_GCC_ABI_DEMANGLE)
264 std::string ret = name;
267 char * demangled_name = abi::__cxa_demangle(name, 0, 0, &status);
271 ret = demangled_name;
275 std::free(demangled_name);
280 std::string
demangle(
const char * name) {
return std::string(name); }
void write_traceout()
Writes a stack trace to a uniquely named file if –enable-tracefiles has been set by configure...
T command_line_value(const std::string &name, T value)
std::string demangle(const char *name)
Mostly system independent demangler.
void print_trace(std::ostream &out_stream)
Print a stack trace (for code compiled with gcc)
processor_id_type global_processor_id()
bool on_command_line(std::string arg)