print_trace.C
Go to the documentation of this file.
1 // Code partially copyright Edd Dawson 2007
2 //
3 // Boost Software License - Version 1.0 - August 17th, 2003
4 //
5 // Permission is hereby granted, free of charge, to any person or organization
6 // obtaining a copy of the software and accompanying documentation covered by
7 // this license (the "Software") to use, reproduce, display, distribute,
8 // execute, and transmit the Software, and to prepare derivative works of the
9 // Software, and to permit third-parties to whom the Software is furnished to
10 // do so, all subject to the following:
11 //
12 // The copyright notices in the Software and this entire statement, including
13 // the above license grant, this restriction and the following disclaimer,
14 // must be included in all copies of the Software, in whole or in part, and
15 // all derivative works of the Software, unless such copies or derivative
16 // works are solely in the form of machine-executable object code generated by
17 // a source language processor.
18 //
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
22 // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
23 // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
24 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 // DEALINGS IN THE SOFTWARE.
26 
27 
28 #include "libmesh/libmesh_config.h"
29 #include "libmesh/print_trace.h"
30 #include "libmesh/libmesh.h"
31 
32 #include <unistd.h> // needed for getpid()
33 #include <fstream>
34 #include <sstream>
35 
36 #if defined(LIBMESH_HAVE_GCC_ABI_DEMANGLE) && defined(LIBMESH_HAVE_GLIBC_BACKTRACE)
37 
38 #include <iostream>
39 #include <string>
40 #include <execinfo.h>
41 #include <cxxabi.h>
42 #include <cstdlib>
43 
44 namespace libMesh
45 {
46 
47 std::string process_trace(const char *name)
48 {
49  std::string fullname = name;
50  std::string saved_begin, saved_end;
51  size_t namestart, nameend;
52 
60 #ifdef __APPLE__
61  namestart = fullname.find("0x");
62  if (namestart != std::string::npos)
63  {
64  namestart = fullname.find(' ', namestart) + 1;
65  saved_begin = fullname.substr(0, namestart);
66  }
67  else
68  namestart = 0;
69  nameend = fullname.find('+');
70  if (nameend == std::string::npos ||
71  nameend <= namestart)
72  nameend = fullname.size();
73  else
74  {
75  nameend -= 1;
76  saved_end = fullname.substr(nameend, fullname.length());
77  }
78 #else
79  namestart = fullname.find('(');
80  if (namestart == std::string::npos)
81  return fullname;
82  else
83  namestart++;
84  nameend = fullname.find('+');
85  if (nameend == std::string::npos ||
86  nameend <= namestart)
87  return fullname;
88 #endif
89 
90  std::string type_name = fullname.substr(namestart, nameend - namestart);
91 
92  // Try to demangle now
93  return saved_begin + demangle(type_name.c_str()) + saved_end;
94 }
95 
96 
97 std::string demangle(const char *name)
98 {
99  int status = 0;
100  char *d = 0;
101  std::string ret = name;
102  try { if ( (d = abi::__cxa_demangle(name, 0, 0, &status)) ) ret = d; }
103  catch(...) { }
104  std::free(d);
105  return ret;
106 }
107 
108 void print_trace(std::ostream &out)
109 {
110  void *addresses[40];
111  char **strings;
112 
113  int size = backtrace(addresses, 40);
114  strings = backtrace_symbols(addresses, size);
115  out << "Stack frames: " << size << std::endl;
116  for(int i = 0; i < size; i++)
117  out << i << ": " << process_trace(strings[i]) << std::endl;
118  std::free(strings);
119 }
120 
121 } // namespace libMesh
122 
123 #else
124 
125 namespace libMesh
126 {
127 void print_trace(std::ostream &) {}
128 
129 std::string demangle(const char *name) { return std::string(name); }
130 }
131 
132 #endif
133 
134 
135 namespace libMesh
136 {
138  {
139 #ifdef LIBMESH_ENABLE_TRACEFILES
140  std::stringstream outname;
141  outname << "traceout_" << static_cast<std::size_t>(libMesh::processor_id()) << '_' << getpid() << ".txt";
142  std::ofstream traceout(outname.str().c_str(), std::ofstream::app);
143  libMesh::print_trace(traceout);
144 #endif
145  }
146 }

Site Created By: libMesh Developers
Last modified: February 07 2014 16:57:06 UTC

Hosted By:
SourceForge.net Logo