Flow123d  release_2.1.0-87-gfbc1563
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 "config.h"
20 #include <boost/exception/diagnostic_information.hpp>
21 
22 #ifdef FLOW123D_HAVE_EXEC_INFO
23 #include <execinfo.h>
24 #endif
25 
26 
27 #ifdef FLOW123D_HAVE_DEMAGLER
28 #include <cxxabi.h>
29 #endif
30 
31 
33 : frames_(NULL),n_frames_(0)
34 {
35 #ifdef FLOW123D_HAVE_EXEC_INFO
36  if (! frames_ && ! n_frames_) {
37  void * array[25];
38  n_frames_ = backtrace(array, 25);
39  frames_ = backtrace_symbols(array, n_frames_);
40  }
41 #endif
42 }
43 
44 
46 : frames_(NULL), n_frames_( other.n_frames_)
47 {
48  int size=0;
49  for(int i=0; i<n_frames_; i++) size+=strlen(other.frames_[i])+1;
50  frames_ = (char **) malloc(size*sizeof(char) +( n_frames_+1)*sizeof(frames_) );
51  char *ptr_dest = (char *)(frames_ + n_frames_);
52  for(int i=0; i<n_frames_; i++) {
53  frames_[i]=ptr_dest;
54  char * ptr_src = other.frames_[i];
55  while(*ptr_src!=0) *(ptr_dest++) = *(ptr_src++);
56  *(ptr_dest++)=0;
57  }
58 }
59 
60 
62 {
63  if (frames_) {
64  free(frames_);
65  frames_=NULL;
66  n_frames_=0;
67  }
68 }
69 
70 
71 void StackTrace::print(std::ostream &out, std::vector<std::string> frames_to_cut) const
72 {
73  using namespace std;
74 
75  out << std::endl;
76  out << "** Stacktrace **" << std::endl;
77 
78  int i_frame;
79  for(i_frame=0; i_frame < n_frames_; i_frame++) {
80  string frame(frames_[i_frame]);
81  bool is_to_cut = true; // check if frame is intended to cut
82  for (auto to_cut : frames_to_cut) {
83  if ( frame.find(to_cut) == string::npos ) is_to_cut = false;
84  }
85  if (is_to_cut) break;
86  }
87  i_frame++;
88 
89  unsigned int out_i_frame=0;
90  for(;i_frame< n_frames_; i_frame++, out_i_frame++) {
91  string frame(frames_[i_frame]);
92 
93  unsigned int start_pos = frame.find("(")+1,
94  end_pos = frame.find("+");
95  string magled_fname = frame.substr( start_pos, end_pos-start_pos );
96 
97  int status=-1;
98  char *demagled_f_name = {0};
99 
100 #ifdef FLOW123D_HAVE_DEMAGLER
101  demagled_f_name = abi::__cxa_demangle(magled_fname.c_str(), 0, 0, &status);
102 #endif
103  if (status == 0) {
104  out << setw(3) << out_i_frame << " " << demagled_f_name << std::endl;
105  free(demagled_f_name);
106  } else {
107  out << setw(3) << out_i_frame << " " << magled_fname << std::endl;
108  }
109 
110  if (magled_fname == "main") break;
111  }
112 
113 }
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:71
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:61
StackTrace()
Default constructor, fill stacktrace.
Definition: stack_trace.cc:32