Flow123d  release_2.2.0-20-gb8056ca
stack_trace.cc
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file stack_trace.cc
15  * @brief
16  */
17 
18 #include "system/stack_trace.hh"
19 #include <cstring>
20 #include "config.h"
21 #include <boost/exception/diagnostic_information.hpp>
22 
23 #ifdef FLOW123D_HAVE_EXEC_INFO
24 #include <execinfo.h>
25 #endif
26 
27 
28 #ifdef FLOW123D_HAVE_DEMAGLER
29 #include <cxxabi.h>
30 #endif
31 
32 
34 : frames_(NULL),n_frames_(0)
35 {
36 #ifdef FLOW123D_HAVE_EXEC_INFO
37  if (! frames_ && ! n_frames_) {
38  void * array[25];
39  n_frames_ = backtrace(array, 25);
40  frames_ = backtrace_symbols(array, n_frames_);
41  }
42 #endif
43 }
44 
45 
47 : frames_(NULL), n_frames_( other.n_frames_)
48 {
49  int size=0;
50  for(int i=0; i<n_frames_; i++) size+=strlen(other.frames_[i])+1;
51  frames_ = (char **) malloc(size*sizeof(char) +( n_frames_+1)*sizeof(frames_) );
52  char *ptr_dest = (char *)(frames_ + n_frames_);
53  for(int i=0; i<n_frames_; i++) {
54  frames_[i]=ptr_dest;
55  char * ptr_src = other.frames_[i];
56  while(*ptr_src!=0) *(ptr_dest++) = *(ptr_src++);
57  *(ptr_dest++)=0;
58  }
59 }
60 
61 
63 {
64  if (frames_) {
65  free(frames_);
66  frames_=NULL;
67  n_frames_=0;
68  }
69 }
70 
71 
72 void StackTrace::print(std::ostream &out, std::vector<std::string> frames_to_cut) const
73 {
74  using namespace std;
75 
76  out << std::endl;
77  out << "** Stacktrace **" << std::endl;
78 
79  int i_frame;
80  for(i_frame=0; i_frame < n_frames_; i_frame++) {
81  string frame(frames_[i_frame]);
82  bool is_to_cut = true; // check if frame is intended to cut
83  for (auto to_cut : frames_to_cut) {
84  if ( frame.find(to_cut) == string::npos ) is_to_cut = false;
85  }
86  if (is_to_cut) break;
87  }
88  i_frame++;
89 
90  unsigned int out_i_frame=0;
91  for(;i_frame< n_frames_; i_frame++, out_i_frame++) {
92  string frame(frames_[i_frame]);
93 
94  unsigned int start_pos = frame.find("(")+1,
95  end_pos = frame.find("+");
96  string magled_fname = frame.substr( start_pos, end_pos-start_pos );
97 
98  int status=-1;
99  char *demagled_f_name = {0};
100 
101 #ifdef FLOW123D_HAVE_DEMAGLER
102  demagled_f_name = abi::__cxa_demangle(magled_fname.c_str(), 0, 0, &status);
103 #endif
104  if (status == 0) {
105  out << setw(3) << out_i_frame << " " << demagled_f_name << std::endl;
106  free(demagled_f_name);
107  } else {
108  out << setw(3) << out_i_frame << " " << magled_fname << std::endl;
109  }
110 
111  if (magled_fname == "main") break;
112  }
113 
114 }
Class representing stacktrace of exceptions.
Definition: stack_trace.hh:34
void print(std::ostream &out, std::vector< std::string > frames_to_cut=std::vector< std::string >()) const
Prints formated stacktrace into given stream out.
Definition: stack_trace.cc:72
int n_frames_
Size of stacktrace table - number of frames.
Definition: stack_trace.hh:55
char ** frames_
Array of backtrace frames returned by glibc backtrace_symbols.
Definition: stack_trace.hh:52
~StackTrace()
Destructor.
Definition: stack_trace.cc:62
StackTrace()
Default constructor, fill stacktrace.
Definition: stack_trace.cc:33