TRIQS/TRIQS 4.0.0
Researching Interacting Quantum Systems
Loading...
Searching...
No Matches
stack_trace.cpp
1// Copyright (c) 2013-2017 Commissariat à l'énergie atomique et aux énergies alternatives (CEA)
2// Copyright (c) 2013-2017 Centre national de la recherche scientifique (CNRS)
3// Copyright (c) 2019-2020 Simons Foundation
4//
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You may obtain a copy of the License at
16// https://www.gnu.org/licenses/gpl-3.0.txt
17//
18// Authors: Olivier Parcollet, Nils Wentzell
19
20#include "./stack_trace.hpp"
21
22#include <string>
23
24#ifndef __APPLE__
25#include <array>
26#include <cstdio>
27#include <sstream>
28
29#include <sys/types.h>
30#include <unistd.h>
31#endif // __APPLE__
32
33namespace 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
std::string stack_trace()
Capture the current call stack and return it as a demangled, human-readable string.
string to_string(string const &str)
Identity overload for std::string.
Provides a function to capture the current C++ stack trace as a string.