14#include "arcane/utils/PlatformUtils.h"
15#include "arcane/utils/IStackTraceService.h"
16#include "arcane/utils/StringBuilder.h"
17#include "arcane/utils/Convert.h"
20#include "arcane/core/AbstractService.h"
22#include "arcane_packages.h"
23#include "arccore/base/internal/DependencyInjection.h"
26#define BACKWARD_HAS_DW 1
28#if defined(ARCANE_HAS_PACKAGE_LIBUNWIND)
29#define BACKWARD_HAS_LIBUNWIND 1
32#include "arcane/std/internal/backwardcpp/backward.hpp"
43class BackwardCppStackTraceService
53 , m_human_readable(
true)
56 explicit BackwardCppStackTraceService(
ITraceMng* tm)
59 , m_human_readable(
true)
61 BackwardCppStackTraceService::build();
74 if (v.value() < 0 || v.value() > 4) {
77 m_verbose_level = v.value();
86 m_human_readable = (v.value() != 0);
97 Int32 m_verbose_level;
98 bool m_human_readable;
109 constexpr size_t hexa_buf_size = 100;
110 char hexa[hexa_buf_size + 1];
112 backward::StackTrace st;
113 st.skip_n_firsts(first_function);
116 backward::TraceResolver tr;
117 tr.load_stacktrace(st);
119 backward::SnippetFactory sf;
121 for (
size_t i = 0; i < st.size(); ++i) {
122 backward::ResolvedTrace trace = tr.resolve(st[i]);
124 snprintf(hexa, hexa_buf_size,
"%14p", trace.addr);
127 message += trace.object_function;
129 UInt32 src_line = trace.source.line;
131 if (m_verbose_level > 0 && src_line > 0) {
133 if (m_verbose_level > 1 || !arcane_function) {
134 auto lines = sf.get_snippet(trace.source.filename, src_line, 5);
135 if (m_human_readable) {
136 message +=
"\n Line: ";
138 message +=
" -- File: ";
139 message += trace.source.filename;
143 message += trace.source.filename;
147 if (m_verbose_level > 3 || (m_verbose_level > 2 && !arcane_function)) {
148 for (
const auto& [line_num, line] : lines) {
149 message += (line_num == src_line ?
"\n >>> " :
"\n ");
158 if (m_human_readable)
166 return { stack_frames, message };
175 backward::StackTrace st;
176 st.skip_n_firsts(function_index);
182 backward::TraceResolver tr;
183 tr.load_stacktrace(st);
185 backward::ResolvedTrace trace = tr.resolve(st[0]);
187 return { trace.object_function };
198 DependencyInjection::ProviderProperty(
"BackwardCppStackTraceService"),
This file contains the various service factories and macros for registering services.
#define ARCANE_SERVICE_INTERFACE(ainterface)
Macro to declare an interface when registering a service.
StackTrace stackTrace(int first_function) override
Character string indicating the call stack.
StackTrace stackTraceFunction(int function_index) override
Name of a function in the call stack.
Template class for converting a type.
Stores a fixed maximum size list of StackFrame.
void addFrame(const StackFrame &frame)
Adds a frame to the list of frames. If nbFrame() is greater than or equal to MAX_FRAME,...
virtual ITraceMng * traceMng() const =0
Trace manager.
Interface of a function call tracing service.
IApplication * application() const
Access to the associated IApplication.
Structure containing the information to create a service.
Service creation properties.
Stores the addresses corresponding to a call stack. This class is internal and should not be used out...
Information about function call stacks.
Unicode character string constructor.
Unicode character string.
bool startsWith(const String &s) const
Indicates if the string starts with the characters of s.
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
#define ARCANE_REGISTER_SERVICE(aclass, a_service_property,...)
Macro for registering a service.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
std::uint32_t UInt32
Unsigned integer type of 32 bits.
@ ST_Application
The service is used at the application level.
std::int32_t Int32
Signed integer type of 32 bits.