labplot  2.8.2
About: LabPlot is an application for plotting and analysis of 2D and 3D functions and data. It is a complete rewrite of LabPlot1 and lacks in the first release a lot of features available in the predecessor. On the other hand, the GUI and the usability is more superior.
  Fossies Dox: labplot-2.8.2.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

trace.h
Go to the documentation of this file.
1 /***************************************************************************
2  File : trace.h
3  Project : LabPlot
4  Description : Function and macros related to performance and debugging tracing
5  --------------------------------------------------------------------
6  Copyright : (C) 2017 Alexander Semke (alexander.semke@web.de)
7 
8  ***************************************************************************/
9 
10 /***************************************************************************
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * *
17  * This program is distributed in the hope that it will be useful, *
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
20  * GNU General Public License for more details. *
21  * *
22  * You should have received a copy of the GNU General Public License *
23  * along with this program; if not, write to the Free Software *
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
25  * Boston, MA 02110-1301 USA *
26  * *
27  ***************************************************************************/
28 #ifndef TRACE_H
29 #define TRACE_H
30 
31 #include "backend/lib/macros.h"
32 #include <chrono>
33 
34 class PerfTracer {
35 public:
36  explicit PerfTracer(const char* m) {
37  msg = m;
38  start = std::chrono::high_resolution_clock::now();
39  };
41  auto end = std::chrono::high_resolution_clock::now();
42  auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
43  std::cout << msg << ": " << diff << " ms" << std::endl;
44  }
45 
46 private:
47  std::chrono::high_resolution_clock::time_point start;
48  std::string msg;
49 };
50 
51 #define PERFTRACE_ENABLED 1
52 
53 #define PERFTRACE_CURVES 1
54 #define PERFTRACE_LIVE_IMPORT 1
55 
56 #ifdef PERFTRACE_ENABLED
57 #define PERFTRACE(msg) PerfTracer tracer(msg)
58 #else
59 #define PERFTRACE(msg) DEBUG(msg)
60 #endif
61 
62 
63 #ifndef HAVE_WINDOWS
64 
65 #include <execinfo.h> //backtrace
66 #include <dlfcn.h> //dladdr
67 #include <cxxabi.h> //__cxa_demangle
68 
69 #include <cstdio>
70 #include <cstdlib>
71 #include <string>
72 #include <sstream>
73 
74 /*!
75  * this function prints the current call stack and helps to figure out why a certain (e.g. performance critical) function
76  * is called multiple times and from where without involving the debugger.
77  * To get the callstack, simple include \c print_callstack() in the function of interest.
78  */
79 static inline void print_callstack() {
80  //get the current call stack
81  const int max_frames_count = 10 + 1; //print the last 10 frames (+1 because of this function frame)
82  void* callstack[max_frames_count];
83  const int frames_count = backtrace(callstack, max_frames_count);
84 
85  //get the symbols
86  char **symbols = backtrace_symbols(callstack, frames_count);
87 
88  std::ostringstream out;
89  char buf[1024];
90 
91  // iterate over the frames, skip the first one (frame of this function call)
92  for (int i = 1; i < frames_count; i++) {
93  Dl_info info;
94  if (dladdr(callstack[i], &info) && info.dli_sname) {
95  char* demangled_name = nullptr;
96  const char* name_to_print = nullptr;
97  int status = -1;
98  if (info.dli_sname[0] == '_')
99  demangled_name = abi::__cxa_demangle(info.dli_sname, nullptr, nullptr, &status);
100 
101  if (status == 0)
102  name_to_print = demangled_name;
103  else {
104  if (info.dli_sname == nullptr)
105  name_to_print = symbols[i];
106  else
107  name_to_print = info.dli_sname;
108  }
109 
110  snprintf(buf, sizeof(buf), "%-3d %*p %s + %zd\n",
111  i,
112  int(2 + sizeof(void*) * 2),
113  callstack[i],
114  name_to_print,
115  (char*)callstack[i] - (char*)info.dli_saddr);
116 
117  free(demangled_name);
118  } else {
119  snprintf(buf, sizeof(buf), "%-3d %*p %s\n",
120  i, int(2 + sizeof(void*) * 2), callstack[i], symbols[i]);
121  }
122  out << buf;
123  }
124  free(symbols);
125 
126  std::cout << "stack trace:\n" << out.str();
127 }
128 #endif // #ifndef HAVE_WINDOWS
129 
130 #endif //TRACE_H
std::string msg
Definition: trace.h:48
std::chrono::high_resolution_clock::time_point start
Definition: trace.h:47
PerfTracer(const char *m)
Definition: trace.h:36
~PerfTracer()
Definition: trace.h:40
static void print_callstack()
Definition: trace.h:79