| 33 | namespace triqs::utility { |
| 34 | |
| 35 | std::string stack_trace() { |
| 36 | #ifdef __APPLE__ |
| 37 | // The lldb solution used on Linux (see below) no longer works on Mac OS 10.15 (Catalina). |
| 38 | // The lldb command was: "lldb -p " + std::to_string(getpid()) + " --batch -o \"bt\" 2>&1" |
| 39 | // TODO Replace by implementation of stacktrace standardization proposal (e.g. https://github.com/boostorg/stacktrace) |
| 40 | return "Stack-trace currently not available on Mac OS"; |
| 41 | #else |
| 42 | // On Linux we use gdb to decipher the call stack for us. |
| 43 | // We launch it with a pipe and read back the output. |
| 44 | std::string const cmd = "gdb --batch -n -ex bt -p " + std::to_string(getpid()) + " 2>&1"; |
| 45 | std::string const py_sentinel = "libpython"; |
| 46 | |
| 47 | constexpr int max_buffer = 256; |
| 48 | std::array<char, max_buffer> buffer{}; |
| 49 | std::string pipe_output; |
| 50 | if (FILE *stream = popen(cmd.c_str(), "r"); stream != nullptr) { |
| 51 | while (fgets(buffer.data(), max_buffer, stream) != nullptr) pipe_output.append(buffer.data()); |
| 52 | pclose(stream); |
| 53 | } |
| 54 | |
| 55 | std::stringstream ss(pipe_output); |
| 56 | std::string to; |
| 57 | std::string r = "\n"; |
| 58 | |
| 59 | while (std::getline(ss, to, '\n') and (to.find("triqs::exception::exception") == std::string::npos)) {} |
| 60 | |
| 61 | while (std::getline(ss, to, '\n')) { |
| 62 | if (to.find(py_sentinel) != std::string::npos) break; |
| 63 | r += to + '\n'; |
| 64 | } |
| 65 | |
| 66 | return r; |
| 67 | #endif |
| 68 | } |
| 69 | |
| 70 | } // namespace triqs::utility |