8#ifndef OPENFPM_DATA_SRC_UTIL_PRINT_STACK_HPP_
9#define OPENFPM_DATA_SRC_UTIL_PRINT_STACK_HPP_
22extern std::string program_name;
28static inline std::string exec(
const char* cmd)
30 std::array<char, 128> buffer;
32 std::shared_ptr<FILE> pipe(popen(cmd,
"r"), pclose);
33 if (!pipe)
throw std::runtime_error(
"popen() failed!");
34 while (!feof(pipe.get()))
36 if (fgets(buffer.data(), 128, pipe.get()) != NULL)
37 result += buffer.data();
46static inline void print_stack()
48#if defined(PRINT_STACKTRACE) && !defined(__CYGWIN__)
52 int ncall = backtrace(trace,256);
53 char ** messages = backtrace_symbols(trace, ncall);
55 std::stringstream str;
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;
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;
66 std::string translators[]={
"eu-addr2line",
"addr2line"};
67 std::string translator;
69 for (
size_t i = 0 ; i <
sizeof(translators)/
sizeof(std::string) ; i++)
73 sprintf(syscom,
"%s --version",translators[i].c_str());
75 std::string ss = exec(syscom);
76 size_t found = ss.find(
"command not found");
77 if (found == std::string::npos)
80 translator = translators[i];
81 str <<
"Using translator: " << translator << std::endl;
86 if (translator.size() == 0)
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: ";
91 str << translators[0];
93 for (
size_t i = 1 ; i <
sizeof(translators)/
sizeof(std::string) ; i++)
94 str <<
"," << translators[i];
97 for (
int i = 0 ; i < ncall ; i++)
99 str <<
"\033[1m" <<
"CALL(" << i <<
")" <<
"\033[0m" <<
" Address: " << trace[i] <<
" " << messages[i] <<
" ";
101 if (translator.size() != 0)
104 sprintf(syscom,
"%s %p -f --demangle -e %s",translator.c_str(), trace[i],program_name.c_str());
106 std::string ss = exec(syscom);
107 std::stringstream sss(ss);
110 std::getline(sss,sfunc,
'\n');
111 std::getline(sss,sloc,
'\n');
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;
122 std::cerr << str.str() << std::endl;
126 std::cerr <<
"Stack trace deactivated, use #define PRINT_STACKTRACE to activate" << std::endl;