Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Drop simgrid::xbt::demangle and use boost::core::demangle instead.
[simgrid.git] / src / xbt / backtrace.cpp
1 /* Copyright (c) 2005-2021. The SimGrid Team. All rights reserved.          */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #include "src/internal_config.h"
7
8 #include <xbt/backtrace.hpp>
9 #include <xbt/string.hpp>
10 #include <xbt/sysdep.h>
11 #include <xbt/virtu.h>
12
13 #include <boost/algorithm/string/predicate.hpp>
14 #include <cstdio>
15 #include <cstdlib>
16 #include <sstream>
17
18 #if HAVE_BOOST_STACKTRACE_BACKTRACE
19 #define BOOST_STACKTRACE_USE_BACKTRACE
20 #include <boost/stacktrace.hpp>
21 #include <boost/stacktrace/detail/frame_decl.hpp>
22 #elif HAVE_BOOST_STACKTRACE_ADDR2LINE
23 #define BOOST_STACKTRACE_USE_ADDR2LINE
24 #include <boost/stacktrace.hpp>
25 #include <boost/stacktrace/detail/frame_decl.hpp>
26 #endif
27
28 /** @brief show the backtrace of the current point (lovely while debugging) */
29 void xbt_backtrace_display_current()
30 {
31   simgrid::xbt::Backtrace().display();
32 }
33
34 namespace simgrid {
35 namespace xbt {
36
37 class BacktraceImpl {
38 #if HAVE_BOOST_STACKTRACE_BACKTRACE || HAVE_BOOST_STACKTRACE_ADDR2LINE
39   const boost::stacktrace::stacktrace st;
40
41 public:
42   std::string resolve() const
43   {
44     std::stringstream ss;
45
46     int frame_count = 0;
47     int state       = 0;
48
49     for (boost::stacktrace::frame frame : st) {
50       if (state == 1) {
51         if (boost::starts_with(frame.name(), "simgrid::xbt::MainFunction") ||
52             boost::starts_with(frame.name(), "simgrid::kernel::context::Context::operator()()"))
53           break;
54         ss << "  ->  " << frame_count++ << "# " << frame.name() << " at " << frame.source_file() << ":"
55            << frame.source_line() << std::endl;
56         if (frame.name() == "main")
57           break;
58       } else {
59         if (frame.name() == "simgrid::xbt::Backtrace::Backtrace()")
60           state = 1;
61       }
62     }
63
64     return ss.str();
65   }
66 #else
67
68 public:
69   std::string resolve() const { return ""; } // fallback value
70 #endif
71 };
72
73 Backtrace::Backtrace() : impl_(std::make_shared<BacktraceImpl>()) {}
74
75 std::string Backtrace::resolve() const
76 {
77   return impl_->resolve();
78 }
79
80 void Backtrace::display() const
81 {
82   std::string backtrace = resolve();
83   std::fprintf(stderr, "Backtrace (displayed in actor %s):\n%s\n", xbt_procname(),
84                backtrace.empty() ? "(backtrace not set -- did you install Boost.Stacktrace?)" : backtrace.c_str());
85 }
86
87 } // namespace xbt
88 } // namespace simgrid