Skip to content

Commit 8ac7eb2

Browse files
committedDec 28, 2024
Documented the new translation methods
1 parent a69e54a commit 8ac7eb2

File tree

1 file changed

+146
-130
lines changed

1 file changed

+146
-130
lines changed
 

‎include/callstack.hpp

+146-130
Original file line numberDiff line numberDiff line change
@@ -42,158 +42,174 @@
4242
* It is needed to avoid name conflicts between the structure and the wrapper class.
4343
*/
4444
namespace lcs {
45+
/**
46+
* @brief A wrapper class around the `struct callstack`.
47+
*
48+
* It provides the usual constructors and operator overloads. Additionally, it contains the
49+
* possibility to implicitly cast an object of this class to a pointer to the C structure.
50+
*/
51+
class callstack {
52+
/** A `typedef` for convenience. */
53+
typedef ::callstack struct_callstack;
54+
/** The original C structure. */
55+
struct_callstack self;
56+
4557
/**
46-
* @brief A wrapper class around the `struct callstack`.
58+
* @brief Helper function to throw the appropriate exception.
4759
*
48-
* It provides the usual constructors and operator overloads. Additionally, it contains the
49-
* possibility to implicitly cast an object of this class to a pointer to the C structure.
60+
* @throws A `system_error` if compiled using C++11 or newer, a runtime error otherwise.
5061
*/
51-
class callstack {
52-
/** A `typedef` for convenience. */
53-
typedef ::callstack struct_callstack;
54-
/** The original C structure. */
55-
struct_callstack self;
56-
57-
/**
58-
* @brief Helper function to throw the appropriate exception.
59-
*
60-
* @throws A `system_error` if compiled using C++11 or newer, a runtime error otherwise.
61-
*/
62-
inline static void error() {
62+
inline static void error() {
6363
#if __cplusplus >= 201103
64-
throw std::system_error(errno, std::generic_category());
64+
throw std::system_error(errno, std::generic_category());
6565
#else
66-
throw std::runtime_error("Backtrace invalid");
66+
throw std::runtime_error("Backtrace invalid");
6767
#endif
68-
}
69-
70-
public:
71-
/**
72-
* @brief A trivial default constructor.
73-
*
74-
* Zero-initializes the underlying C structure. If the given boolean value is `true`,
75-
* it is initialized using the function `callstack_emplace()`.
76-
* Throws a `runtime_error` or a `system_error` if compiled using C++11 or newer if
77-
* `emplace` is set to `true` and the backtrace could not be created.
78-
*
79-
* @param emplace Whether to call `callstack_emplace()`.
80-
*/
81-
inline explicit callstack(bool emplace = true) {
82-
if (emplace) {
83-
if (!callstack_emplace(*this)) {
84-
error();
85-
}
86-
} else {
87-
callstack_create(*this);
88-
}
89-
}
90-
91-
/**
92-
* @brief Constructs this object using the given stack address.
93-
*
94-
* Initializes the underlying C structure using the function `callstack_emplaceWithAddress()`.
95-
* Throws a `runtime_error` or a `system_error` if compiled using C++11 or newer if
96-
* the backtrace could not be created.
97-
*
98-
* @param address The stack address after which frames are ignored.
99-
*/
100-
inline explicit callstack(void* address) {
101-
if (!callstack_emplaceWithAddress(*this, address)) {
102-
error();
103-
}
104-
}
105-
106-
/**
107-
* @brief Constructs the underlying C structure with the given backtrace.
108-
*
109-
* if the given trace length is smaller than zero, a `runtime_error` or a `system_error`
110-
* if compiled using C++11 or newer is thrown.
111-
*
112-
* @param trace The backtrace.
113-
* @param length The length of the given backtrace.
114-
*/
115-
inline callstack(void** trace, int length) {
116-
if (!callstack_emplaceWithBacktrace(*this, trace, length)) {
68+
}
69+
70+
public:
71+
/**
72+
* @brief A trivial default constructor.
73+
*
74+
* Zero-initializes the underlying C structure. If the given boolean value is `true`,
75+
* it is initialized using the function `callstack_emplace()`.
76+
* Throws a `runtime_error` or a `system_error` if compiled using C++11 or newer if
77+
* `emplace` is set to `true` and the backtrace could not be created.
78+
*
79+
* @param emplace Whether to call `callstack_emplace()`.
80+
*/
81+
inline explicit callstack(bool emplace = true) {
82+
if (emplace) {
83+
if (!callstack_emplace(*this)) {
11784
error();
11885
}
119-
}
120-
121-
inline callstack(const callstack& other) LCS_NOEXCEPT {
122-
callstack_create(*this);
123-
callstack_copy(*this, other);
124-
}
125-
126-
/**
127-
* @brief Constructs a callstack object from the given C structure.
128-
*
129-
* @param cCallstack The C structure to be copied.
130-
*/
131-
inline explicit callstack(const struct_callstack* cCallstack) LCS_NOEXCEPT {
86+
} else {
13287
callstack_create(*this);
133-
callstack_copy(*this, cCallstack);
134-
}
135-
136-
inline ~callstack() LCS_NOEXCEPT {
137-
callstack_destroy(*this);
138-
}
139-
140-
inline callstack& operator=(const callstack& other) LCS_NOEXCEPT {
141-
if (&other != this) {
142-
callstack_copy(*this, other);
143-
}
144-
return *this;
14588
}
146-
147-
#if __cplusplus >= 201103
148-
inline callstack(callstack&& other) noexcept
149-
: self(std::move(other.self)) {
150-
callstack_create(other);
89+
}
90+
91+
/**
92+
* @brief Constructs this object using the given stack address.
93+
*
94+
* Initializes the underlying C structure using the function `callstack_emplaceWithAddress()`.
95+
* Throws a `runtime_error` or a `system_error` if compiled using C++11 or newer if
96+
* the backtrace could not be created.
97+
*
98+
* @param address The stack address after which frames are ignored.
99+
*/
100+
inline explicit callstack(void* address) {
101+
if (!callstack_emplaceWithAddress(*this, address)) {
102+
error();
151103
}
152-
153-
inline auto operator=(callstack&& other) noexcept -> callstack& {
154-
callstack_destroy(*this);
155-
self = std::move(other.self);
156-
callstack_create(other);
157-
return *this;
104+
}
105+
106+
/**
107+
* @brief Constructs the underlying C structure with the given backtrace.
108+
*
109+
* if the given trace length is smaller than zero, a `runtime_error` or a `system_error`
110+
* if compiled using C++11 or newer is thrown.
111+
*
112+
* @param trace The backtrace.
113+
* @param length The length of the given backtrace.
114+
*/
115+
inline callstack(void** trace, int length) {
116+
if (!callstack_emplaceWithBacktrace(*this, trace, length)) {
117+
error();
158118
}
159-
#endif
119+
}
160120

161-
inline callstack& translate(bool onlyBinaries = false) {
162-
if (onlyBinaries) {
163-
if (callstack_getBinaries(*this) == LCS_NULL) {
164-
throw std::runtime_error("LCS: Failed to translate the callstack (binaries only)");
165-
}
166-
} else {
167-
if (callstack_toArray(*this) == LCS_NULL) {
168-
throw std::runtime_error("LCS: Failed to translate the callstack");
169-
}
170-
}
171-
return *this;
121+
inline callstack(const callstack& other) LCS_NOEXCEPT {
122+
callstack_create(*this);
123+
callstack_copy(*this, other);
124+
}
125+
126+
/**
127+
* @brief Constructs a callstack object from the given C structure.
128+
*
129+
* @param cCallstack The C structure to be copied.
130+
*/
131+
inline explicit callstack(const struct_callstack* cCallstack) LCS_NOEXCEPT {
132+
callstack_create(*this);
133+
callstack_copy(*this, cCallstack);
134+
}
135+
136+
inline ~callstack() LCS_NOEXCEPT {
137+
callstack_destroy(*this);
138+
}
139+
140+
inline callstack& operator=(const callstack& other) LCS_NOEXCEPT {
141+
if (&other != this) {
142+
callstack_copy(*this, other);
172143
}
144+
return *this;
145+
}
146+
147+
#if __cplusplus >= 201103
148+
inline callstack(callstack&& other) noexcept
149+
: self(std::move(other.self)) {
150+
callstack_create(other);
151+
}
173152

174-
#ifdef LCS_USE_UNSAFE_OPTIMIZATION
175-
inline callstack& translateBinariesCached() {
176-
if (callstack_getBinariesCached(*this) == LCS_NULL) {
177-
throw std::runtime_error("LCS: Failed to translate the callstack (cached binaries)");
153+
inline auto operator=(callstack&& other) noexcept -> callstack& {
154+
callstack_destroy(*this);
155+
self = std::move(other.self);
156+
callstack_create(other);
157+
return *this;
158+
}
159+
#endif
160+
161+
/**
162+
* Translates this callstack object.
163+
*
164+
* @param onlyBinaries whether to only deduct the names of the runtime images
165+
* @return @c this
166+
* @throws an exception when the translation failed
167+
*/
168+
inline callstack& translate(bool onlyBinaries = false) {
169+
if (onlyBinaries) {
170+
if (callstack_getBinaries(*this) == LCS_NULL) {
171+
throw std::runtime_error("LCS: Failed to translate the callstack (binaries only)");
172+
}
173+
} else {
174+
if (callstack_toArray(*this) == LCS_NULL) {
175+
throw std::runtime_error("LCS: Failed to translate the callstack");
178176
}
179-
return *this;
180177
}
181-
#endif
178+
return *this;
179+
}
182180

183-
LCS_CONSTEXPR inline const callstack_frame* begin() const LCS_NOEXCEPT {
184-
return self.frames;
181+
#ifdef LCS_USE_UNSAFE_OPTIMIZATION
182+
/**
183+
* @brief Translates this callstack object.
184+
*
185+
* Only the names of the runtime images are deducted. They are backed by
186+
* the cache of the library and only valid as long as the cache is.
187+
*
188+
* @return @c this
189+
* @throws an exception if the translation failed
190+
*/
191+
inline callstack& translateBinariesCached() {
192+
if (callstack_getBinariesCached(*this) == LCS_NULL) {
193+
throw std::runtime_error("LCS: Failed to translate the callstack (cached binaries)");
185194
}
195+
return *this;
196+
}
197+
#endif
186198

187-
LCS_CONSTEXPR inline const callstack_frame* end() const LCS_NOEXCEPT {
188-
return self.frames + self.frameCount;
189-
}
199+
LCS_CONSTEXPR inline const callstack_frame* begin() const LCS_NOEXCEPT {
200+
return self.frames;
201+
}
202+
203+
LCS_CONSTEXPR inline const callstack_frame* end() const LCS_NOEXCEPT {
204+
return self.frames + self.frameCount;
205+
}
190206

191-
inline operator struct_callstack*() LCS_NOEXCEPT { return &self; }
192-
inline operator const struct_callstack*() const LCS_NOEXCEPT { return &self; }
207+
inline operator struct_callstack*() LCS_NOEXCEPT { return &self; }
208+
inline operator const struct_callstack*() const LCS_NOEXCEPT { return &self; }
193209

194-
inline struct_callstack* operator->() LCS_NOEXCEPT { return &self; }
195-
inline const struct_callstack* operator->() const LCS_NOEXCEPT { return &self; }
196-
};
210+
inline struct_callstack* operator->() LCS_NOEXCEPT { return &self; }
211+
inline const struct_callstack* operator->() const LCS_NOEXCEPT { return &self; }
212+
};
197213
}
198214

199215
#endif /* __lcs_callstack_hpp */

0 commit comments

Comments
 (0)
Please sign in to comment.