OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
print_stack.hpp
1/*
2 * print_stack.hpp
3 *
4 * Created on: Feb 12, 2017
5 * Author: i-bird
6 */
7
8#ifndef OPENFPM_DATA_SRC_UTIL_PRINT_STACK_HPP_
9#define OPENFPM_DATA_SRC_UTIL_PRINT_STACK_HPP_
10
11#include <sstream>
12#include <cstdio>
13#include <iostream>
14#include <memory>
15#include <stdexcept>
16#include <string>
17#include <array>
18#ifndef __CYGWIN__
19#include <execinfo.h>
20#endif
21
22extern std::string program_name;
23
28static inline std::string exec(const char* cmd)
29{
30 std::array<char, 128> buffer;
31 std::string result;
32 std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
33 if (!pipe) throw std::runtime_error("popen() failed!");
34 while (!feof(pipe.get()))
35 {
36 if (fgets(buffer.data(), 128, pipe.get()) != NULL)
37 result += buffer.data();
38 }
39 return result;
40}
41
46static inline void print_stack()
47{
48#if defined(PRINT_STACKTRACE) && !defined(__CYGWIN__)
49
50 void *trace[256];
51
52 int ncall = backtrace(trace,256);
53 char ** messages = backtrace_symbols(trace, ncall);
54
55 std::stringstream str;
56
57 str << "\033[1;31m*******************************************\033[0m" << std::endl;
58 str << "\033[1;31m*********** STACK TRACE *******************\033[0m" << std::endl;
59 str << "\033[1;31m*******************************************\033[0m" << std::endl;
60
61 str << "\033[1mThe stack trace indicate where in the code happened the error the error " <<
62 "is in general detected inside the library. In order to find the position " <<
63 "in your code, follow from top to bottom the list of calls until you find " <<
64 "a source code familiar to you.\033[0m" << std::endl;
65
66 std::string translators[]={"eu-addr2line","addr2line"};
67 std::string translator;
68
69 for (size_t i = 0 ; i < sizeof(translators)/sizeof(std::string) ; i++)
70 {
71 // for for the best address to source code translator
72 char syscom[256];
73 sprintf(syscom,"%s --version",translators[i].c_str());
74
75 std::string ss = exec(syscom);
76 size_t found = ss.find("command not found");
77 if (found == std::string::npos)
78 {
79 // command exist
80 translator = translators[i];
81 str << "Using translator: " << translator << std::endl;
82 break;
83 }
84 }
85
86 if (translator.size() == 0)
87 {
88 str << "In order to have a more detailed stack-trace with function name and precise location in the source code" <<
89 "Please install one of the following utils: ";
90
91 str << translators[0];
92
93 for (size_t i = 1 ; i < sizeof(translators)/sizeof(std::string) ; i++)
94 str << "," << translators[i];
95 }
96
97 for (int i = 0 ; i < ncall ; i++)
98 {
99 str << "\033[1m" << "CALL(" << i << ")" << "\033[0m" << " Address: " << trace[i] << " " << messages[i] << " ";
100
101 if (translator.size() != 0)
102 {
103 char syscom[256];
104 sprintf(syscom,"%s %p -f --demangle -e %s",translator.c_str(), trace[i],program_name.c_str()); //last parameter is the name of this app
105
106 std::string ss = exec(syscom);
107 std::stringstream sss(ss);
108 std::string sfunc;
109 std::string sloc;
110 std::getline(sss,sfunc,'\n');
111 std::getline(sss,sloc,'\n');
112 str << std::endl;
113 str << "\033[35m" << "Function:" << std::endl << sfunc << "\033[0m" << std::endl;
114 str << "\033[1;31m" << "Location:" << std::endl << sloc << "\033[0m" << std::endl;
115 }
116 else
117 {
118 str << std::endl;
119 }
120 }
121
122 std::cerr << str.str() << std::endl;
123
124#else
125
126 std::cerr << "Stack trace deactivated, use #define PRINT_STACKTRACE to activate" << std::endl;
127
128#endif
129}
130
131
132
133#endif /* OPENFPM_DATA_SRC_UTIL_PRINT_STACK_HPP_ */