Add max_depth overloads
This commit is contained in:
parent
3e18bd3c10
commit
dd928b249b
24
README.md
24
README.md
@ -142,7 +142,8 @@ namespace cpptrace {
|
|||||||
std::vector<stacktrace_frame> frames;
|
std::vector<stacktrace_frame> frames;
|
||||||
explicit stacktrace();
|
explicit stacktrace();
|
||||||
explicit stacktrace(std::vector<stacktrace_frame>&& frames);
|
explicit stacktrace(std::vector<stacktrace_frame>&& frames);
|
||||||
static stacktrace current(std::uint32_t skip = 0); // here as a drop-in for std::stacktrace
|
static stacktrace current(std::uint_least32_t skip = 0); // here as a drop-in for std::stacktrace
|
||||||
|
static stacktrace current(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
||||||
void print() const;
|
void print() const;
|
||||||
void print(std::ostream& stream) const;
|
void print(std::ostream& stream) const;
|
||||||
void print(std::ostream& stream, bool color) const;
|
void print(std::ostream& stream, bool color) const;
|
||||||
@ -152,7 +153,8 @@ namespace cpptrace {
|
|||||||
/* operator<<(ostream, ..), std::format support, and iterators exist for this object */
|
/* operator<<(ostream, ..), std::format support, and iterators exist for this object */
|
||||||
};
|
};
|
||||||
|
|
||||||
stacktrace generate_trace(std::uint32_t skip = 0);
|
stacktrace generate_trace(std::uint_least32_t skip = 0);
|
||||||
|
stacktrace generate_trace(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -174,14 +176,16 @@ namespace cpptrace {
|
|||||||
struct object_trace {
|
struct object_trace {
|
||||||
std::vector<object_frame> frames;
|
std::vector<object_frame> frames;
|
||||||
explicit object_trace(std::vector<object_frame>&& frames);
|
explicit object_trace(std::vector<object_frame>&& frames);
|
||||||
static object_trace current(std::uint32_t skip = 0);
|
static object_trace current(std::uint_least32_t skip = 0);
|
||||||
|
static object_trace current(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
||||||
stacktrace resolve() const;
|
stacktrace resolve() const;
|
||||||
void clear();
|
void clear();
|
||||||
bool empty() const noexcept;
|
bool empty() const noexcept;
|
||||||
/* iterators exist for this object */
|
/* iterators exist for this object */
|
||||||
};
|
};
|
||||||
|
|
||||||
object_trace generate_object_trace(std::uint32_t skip = 0);
|
object_trace generate_object_trace(std::uint_least32_t skip = 0);
|
||||||
|
object_trace generate_object_trace(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -197,7 +201,8 @@ namespace cpptrace {
|
|||||||
struct raw_trace {
|
struct raw_trace {
|
||||||
std::vector<uintptr_t> frames;
|
std::vector<uintptr_t> frames;
|
||||||
explicit raw_trace(std::vector<uintptr_t>&& frames);
|
explicit raw_trace(std::vector<uintptr_t>&& frames);
|
||||||
static raw_trace current(std::uint32_t skip = 0);
|
static raw_trace current(std::uint_least32_t skip = 0);
|
||||||
|
static raw_trace current(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
||||||
object_trace resolve_object_trace() const;
|
object_trace resolve_object_trace() const;
|
||||||
stacktrace resolve() const;
|
stacktrace resolve() const;
|
||||||
void clear();
|
void clear();
|
||||||
@ -205,7 +210,8 @@ namespace cpptrace {
|
|||||||
/* iterators exist for this object */
|
/* iterators exist for this object */
|
||||||
};
|
};
|
||||||
|
|
||||||
raw_trace generate_raw_trace(std::uint32_t skip = 0);
|
raw_trace generate_raw_trace(std::uint_least32_t skip = 0);
|
||||||
|
raw_trace generate_raw_trace(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -236,7 +242,8 @@ namespace cpptrace {
|
|||||||
mutable raw_trace trace;
|
mutable raw_trace trace;
|
||||||
mutable stacktrace resolved_trace;
|
mutable stacktrace resolved_trace;
|
||||||
mutable std::string resolved_what;
|
mutable std::string resolved_what;
|
||||||
explicit exception(uint32_t skip) noexcept;
|
explicit exception(std::uint_least32_t skip) noexcept;
|
||||||
|
explicit exception(std::uint_least32_t skip, std::uint_least32_t max_depth) noexcept;
|
||||||
const stacktrace& get_resolved_trace() const noexcept;
|
const stacktrace& get_resolved_trace() const noexcept;
|
||||||
virtual const std::string& get_resolved_what() const noexcept;
|
virtual const std::string& get_resolved_what() const noexcept;
|
||||||
public:
|
public:
|
||||||
@ -249,7 +256,8 @@ namespace cpptrace {
|
|||||||
|
|
||||||
class exception_with_message : public exception {
|
class exception_with_message : public exception {
|
||||||
mutable std::string message;
|
mutable std::string message;
|
||||||
explicit exception_with_message(std::string&& message_arg, uint32_t skip) noexcept;
|
explicit exception_with_message(std::string&& message_arg, std::uint_least32_t skip) noexcept;
|
||||||
|
explicit exception_with_message(std::string&& message_arg, std::uint_least32_t skip, std::uint_least32_t max_depth) noexcept;
|
||||||
const std::string& get_resolved_what() const noexcept override;
|
const std::string& get_resolved_what() const noexcept override;
|
||||||
public:
|
public:
|
||||||
explicit exception_with_message(std::string&& message_arg);
|
explicit exception_with_message(std::string&& message_arg);
|
||||||
|
|||||||
@ -30,7 +30,8 @@ namespace cpptrace {
|
|||||||
struct raw_trace {
|
struct raw_trace {
|
||||||
std::vector<uintptr_t> frames;
|
std::vector<uintptr_t> frames;
|
||||||
explicit raw_trace(std::vector<uintptr_t>&& frames_) : frames(frames_) {}
|
explicit raw_trace(std::vector<uintptr_t>&& frames_) : frames(frames_) {}
|
||||||
CPPTRACE_API static raw_trace current(std::uint32_t skip = 0);
|
CPPTRACE_API static raw_trace current(std::uint_least32_t skip = 0);
|
||||||
|
CPPTRACE_API static raw_trace current(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
||||||
CPPTRACE_API object_trace resolve_object_trace() const;
|
CPPTRACE_API object_trace resolve_object_trace() const;
|
||||||
CPPTRACE_API stacktrace resolve() const;
|
CPPTRACE_API stacktrace resolve() const;
|
||||||
CPPTRACE_API void clear();
|
CPPTRACE_API void clear();
|
||||||
@ -54,7 +55,8 @@ namespace cpptrace {
|
|||||||
struct object_trace {
|
struct object_trace {
|
||||||
std::vector<object_frame> frames;
|
std::vector<object_frame> frames;
|
||||||
explicit object_trace(std::vector<object_frame>&& frames_) : frames(frames_) {}
|
explicit object_trace(std::vector<object_frame>&& frames_) : frames(frames_) {}
|
||||||
CPPTRACE_API static object_trace current(std::uint32_t skip = 0);
|
CPPTRACE_API static object_trace current(std::uint_least32_t skip = 0);
|
||||||
|
CPPTRACE_API static object_trace current(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
||||||
CPPTRACE_API stacktrace resolve() const;
|
CPPTRACE_API stacktrace resolve() const;
|
||||||
CPPTRACE_API void clear();
|
CPPTRACE_API void clear();
|
||||||
CPPTRACE_API bool empty() const noexcept;
|
CPPTRACE_API bool empty() const noexcept;
|
||||||
@ -91,7 +93,8 @@ namespace cpptrace {
|
|||||||
std::vector<stacktrace_frame> frames;
|
std::vector<stacktrace_frame> frames;
|
||||||
explicit stacktrace() {}
|
explicit stacktrace() {}
|
||||||
explicit stacktrace(std::vector<stacktrace_frame>&& frames_) : frames(frames_) {}
|
explicit stacktrace(std::vector<stacktrace_frame>&& frames_) : frames(frames_) {}
|
||||||
CPPTRACE_API static stacktrace current(std::uint32_t skip = 0);
|
CPPTRACE_API static stacktrace current(std::uint_least32_t skip = 0);
|
||||||
|
CPPTRACE_API static stacktrace current(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
||||||
CPPTRACE_API void print() const;
|
CPPTRACE_API void print() const;
|
||||||
CPPTRACE_API void print(std::ostream& stream) const;
|
CPPTRACE_API void print(std::ostream& stream) const;
|
||||||
CPPTRACE_API void print(std::ostream& stream, bool color) const;
|
CPPTRACE_API void print(std::ostream& stream, bool color) const;
|
||||||
@ -110,9 +113,12 @@ namespace cpptrace {
|
|||||||
CPPTRACE_API void print(std::ostream& stream, bool color, bool newline_at_end) const;
|
CPPTRACE_API void print(std::ostream& stream, bool color, bool newline_at_end) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
CPPTRACE_API raw_trace generate_raw_trace(std::uint32_t skip = 0);
|
CPPTRACE_API raw_trace generate_raw_trace(std::uint_least32_t skip = 0);
|
||||||
CPPTRACE_API object_trace generate_object_trace(std::uint32_t skip = 0);
|
CPPTRACE_API raw_trace generate_raw_trace(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
||||||
CPPTRACE_API stacktrace generate_trace(std::uint32_t skip = 0);
|
CPPTRACE_API object_trace generate_object_trace(std::uint_least32_t skip = 0);
|
||||||
|
CPPTRACE_API object_trace generate_object_trace(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
||||||
|
CPPTRACE_API stacktrace generate_trace(std::uint_least32_t skip = 0);
|
||||||
|
CPPTRACE_API stacktrace generate_trace(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
||||||
|
|
||||||
// utilities:
|
// utilities:
|
||||||
CPPTRACE_API std::string demangle(const std::string& name);
|
CPPTRACE_API std::string demangle(const std::string& name);
|
||||||
@ -127,9 +133,10 @@ namespace cpptrace {
|
|||||||
mutable raw_trace trace;
|
mutable raw_trace trace;
|
||||||
mutable stacktrace resolved_trace;
|
mutable stacktrace resolved_trace;
|
||||||
mutable std::string resolved_what;
|
mutable std::string resolved_what;
|
||||||
explicit exception(uint32_t skip) noexcept : trace([skip] () noexcept {
|
explicit exception(std::uint_least32_t skip, std::uint_least32_t max_depth) noexcept
|
||||||
|
: trace([skip, max_depth] () noexcept {
|
||||||
try {
|
try {
|
||||||
return generate_raw_trace(skip + 2);
|
return generate_raw_trace(skip + 2, max_depth);
|
||||||
} catch(const std::exception& e) {
|
} catch(const std::exception& e) {
|
||||||
if(!detail::should_absorb_trace_exceptions()) {
|
if(!detail::should_absorb_trace_exceptions()) {
|
||||||
fprintf(
|
fprintf(
|
||||||
@ -141,6 +148,7 @@ namespace cpptrace {
|
|||||||
return raw_trace({});
|
return raw_trace({});
|
||||||
}
|
}
|
||||||
} ()) {}
|
} ()) {}
|
||||||
|
explicit exception(std::uint_least32_t skip) noexcept : exception(skip + 1, UINT_LEAST32_MAX) {}
|
||||||
const stacktrace& get_resolved_trace() const noexcept {
|
const stacktrace& get_resolved_trace() const noexcept {
|
||||||
// I think a non-empty raw trace can never resolve as empty, so this will accurately prevent resolving more
|
// I think a non-empty raw trace can never resolve as empty, so this will accurately prevent resolving more
|
||||||
// than once. Either way the raw trace is cleared.
|
// than once. Either way the raw trace is cleared.
|
||||||
@ -186,8 +194,15 @@ namespace cpptrace {
|
|||||||
class exception_with_message : public exception {
|
class exception_with_message : public exception {
|
||||||
protected:
|
protected:
|
||||||
mutable std::string message;
|
mutable std::string message;
|
||||||
explicit exception_with_message(std::string&& message_arg, uint32_t skip) noexcept
|
explicit exception_with_message(
|
||||||
: exception(skip + 1), message(std::move(message_arg)) {}
|
std::string&& message_arg,
|
||||||
|
uint32_t skip
|
||||||
|
) noexcept : exception(skip + 1), message(std::move(message_arg)) {}
|
||||||
|
explicit exception_with_message(
|
||||||
|
std::string&& message_arg,
|
||||||
|
uint_least32_t skip,
|
||||||
|
uint_least32_t max_depth
|
||||||
|
) noexcept : exception(skip + 1, max_depth), message(std::move(message_arg)) {}
|
||||||
const std::string& get_resolved_what() const noexcept override {
|
const std::string& get_resolved_what() const noexcept override {
|
||||||
if(resolved_what.empty()) {
|
if(resolved_what.empty()) {
|
||||||
resolved_what = message + "\n" + get_resolved_trace().to_string();
|
resolved_what = message + "\n" + get_resolved_trace().to_string();
|
||||||
|
|||||||
@ -31,10 +31,15 @@ namespace cpptrace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
||||||
raw_trace raw_trace::current(std::uint32_t skip) {
|
raw_trace raw_trace::current(std::uint_least32_t skip) {
|
||||||
return generate_raw_trace(skip + 1);
|
return generate_raw_trace(skip + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
||||||
|
raw_trace raw_trace::current(std::uint_least32_t skip, std::uint_least32_t max_depth) {
|
||||||
|
return generate_raw_trace(skip + 1, max_depth);
|
||||||
|
}
|
||||||
|
|
||||||
CPPTRACE_API
|
CPPTRACE_API
|
||||||
object_trace raw_trace::resolve_object_trace() const {
|
object_trace raw_trace::resolve_object_trace() const {
|
||||||
return object_trace(detail::get_frames_object_info(frames));
|
return object_trace(detail::get_frames_object_info(frames));
|
||||||
@ -60,10 +65,15 @@ namespace cpptrace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
||||||
object_trace object_trace::current(std::uint32_t skip) {
|
object_trace object_trace::current(std::uint_least32_t skip) {
|
||||||
return generate_object_trace(skip + 1);
|
return generate_object_trace(skip + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
||||||
|
object_trace object_trace::current(std::uint_least32_t skip, std::uint_least32_t max_depth) {
|
||||||
|
return generate_object_trace(skip + 1, max_depth);
|
||||||
|
}
|
||||||
|
|
||||||
CPPTRACE_API
|
CPPTRACE_API
|
||||||
stacktrace object_trace::resolve() const {
|
stacktrace object_trace::resolve() const {
|
||||||
return stacktrace(detail::resolve_frames(frames));
|
return stacktrace(detail::resolve_frames(frames));
|
||||||
@ -114,6 +124,11 @@ namespace cpptrace {
|
|||||||
return generate_trace(skip + 1);
|
return generate_trace(skip + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
||||||
|
stacktrace stacktrace::current(std::uint_least32_t skip, std::uint_least32_t max_depth) {
|
||||||
|
return generate_trace(skip + 1, max_depth);
|
||||||
|
}
|
||||||
|
|
||||||
CPPTRACE_API
|
CPPTRACE_API
|
||||||
void stacktrace::print() const {
|
void stacktrace::print() const {
|
||||||
print(std::cerr, true);
|
print(std::cerr, true);
|
||||||
@ -206,18 +221,33 @@ namespace cpptrace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
||||||
raw_trace generate_raw_trace(std::uint32_t skip) {
|
raw_trace generate_raw_trace(std::uint_least32_t skip) {
|
||||||
return raw_trace(detail::capture_frames(skip + 1));
|
return raw_trace(detail::capture_frames(skip + 1, UINT_LEAST32_MAX));
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
||||||
object_trace generate_object_trace(std::uint32_t skip) {
|
raw_trace generate_raw_trace(std::uint_least32_t skip, std::uint_least32_t max_depth) {
|
||||||
return object_trace(detail::get_frames_object_info(detail::capture_frames(skip + 1)));
|
return raw_trace(detail::capture_frames(skip + 1, max_depth));
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
||||||
stacktrace generate_trace(std::uint32_t skip) {
|
object_trace generate_object_trace(std::uint_least32_t skip) {
|
||||||
std::vector<uintptr_t> frames = detail::capture_frames(skip + 1);
|
return object_trace(detail::get_frames_object_info(detail::capture_frames(skip + 1, UINT_LEAST32_MAX)));
|
||||||
|
}
|
||||||
|
|
||||||
|
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
||||||
|
object_trace generate_object_trace(std::uint_least32_t skip, std::uint_least32_t max_depth) {
|
||||||
|
return object_trace(detail::get_frames_object_info(detail::capture_frames(skip + 1, max_depth)));
|
||||||
|
}
|
||||||
|
|
||||||
|
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
||||||
|
stacktrace generate_trace(std::uint_least32_t skip) {
|
||||||
|
return generate_trace(skip + 1, UINT_LEAST32_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
CPPTRACE_FORCE_NO_INLINE CPPTRACE_API
|
||||||
|
stacktrace generate_trace(std::uint32_t skip, std::uint_least32_t max_depth) {
|
||||||
|
std::vector<uintptr_t> frames = detail::capture_frames(skip + 1, max_depth);
|
||||||
std::vector<stacktrace_frame> trace = detail::resolve_frames(frames);
|
std::vector<stacktrace_frame> trace = detail::resolve_frames(frames);
|
||||||
for(auto& frame : trace) {
|
for(auto& frame : trace) {
|
||||||
frame.symbol = detail::demangle(frame.symbol);
|
frame.symbol = detail::demangle(frame.symbol);
|
||||||
|
|||||||
@ -15,7 +15,7 @@ namespace detail {
|
|||||||
constexpr size_t hard_max_frames = 100;
|
constexpr size_t hard_max_frames = 100;
|
||||||
#endif
|
#endif
|
||||||
CPPTRACE_FORCE_NO_INLINE
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
std::vector<uintptr_t> capture_frames(size_t skip);
|
std::vector<uintptr_t> capture_frames(size_t skip, size_t max_depth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -13,15 +13,13 @@
|
|||||||
namespace cpptrace {
|
namespace cpptrace {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
CPPTRACE_FORCE_NO_INLINE
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
std::vector<uintptr_t> capture_frames(size_t skip) {
|
std::vector<uintptr_t> capture_frames(size_t skip, size_t max_depth) {
|
||||||
std::vector<void*> addrs(hard_max_frames + skip, nullptr);
|
skip += 2; // TODO: Not sure where the other 1 comes from
|
||||||
const int n_frames = backtrace(addrs.data(), int(hard_max_frames + skip)); // thread safe
|
std::vector<void*> addrs(std::min(hard_max_frames, skip + max_depth), nullptr);
|
||||||
addrs.resize(n_frames);
|
const int n_frames = backtrace(addrs.data(), static_cast<int>(addrs.size())); // thread safe
|
||||||
addrs.erase(addrs.begin(), addrs.begin() + ptrdiff_t(std::min(skip + 1, addrs.size())));
|
std::vector<uintptr_t> frames(n_frames - skip, 0);
|
||||||
addrs.shrink_to_fit();
|
for(int i = skip; i < n_frames; i++) {
|
||||||
std::vector<uintptr_t> frames(addrs.size(), 0);
|
frames[i - skip] = reinterpret_cast<uintptr_t>(addrs[i]);
|
||||||
for(std::size_t i = 0; i < addrs.size(); i++) {
|
|
||||||
frames[i] = reinterpret_cast<uintptr_t>(addrs[i]);
|
|
||||||
}
|
}
|
||||||
return frames;
|
return frames;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
namespace cpptrace {
|
namespace cpptrace {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
std::vector<uintptr_t> capture_frames(size_t) {
|
std::vector<uintptr_t> capture_frames(size_t skip, size_t max_depth) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,18 +40,22 @@ namespace detail {
|
|||||||
if(!is_before_instruction && ip != uintptr_t(0)) {
|
if(!is_before_instruction && ip != uintptr_t(0)) {
|
||||||
ip--;
|
ip--;
|
||||||
}
|
}
|
||||||
if (ip == uintptr_t(0) || state.count == state.vec.size()) {
|
if (ip == uintptr_t(0)) {
|
||||||
return _URC_END_OF_STACK;
|
return _URC_END_OF_STACK;
|
||||||
} else {
|
} else {
|
||||||
// TODO: push_back?...
|
// TODO: push_back?...
|
||||||
state.vec[state.count++] = ip;
|
state.vec[state.count++] = ip;
|
||||||
|
if(state.count == state.vec.size()) {
|
||||||
|
return _URC_END_OF_STACK;
|
||||||
|
} else {
|
||||||
return _URC_NO_REASON;
|
return _URC_NO_REASON;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
std::vector<uintptr_t> capture_frames(size_t skip) {
|
std::vector<uintptr_t> capture_frames(size_t skip, size_t max_depth) {
|
||||||
std::vector<uintptr_t> frames(hard_max_frames, 0);
|
std::vector<uintptr_t> frames(std::min(hard_max_frames, max_depth), 0);
|
||||||
unwind_state state{skip + 1, 0, frames};
|
unwind_state state{skip + 1, 0, frames};
|
||||||
_Unwind_Backtrace(unwind_callback, &state); // presumably thread-safe
|
_Unwind_Backtrace(unwind_callback, &state); // presumably thread-safe
|
||||||
frames.resize(state.count);
|
frames.resize(state.count);
|
||||||
|
|||||||
@ -5,20 +5,30 @@
|
|||||||
#include "../platform/common.hpp"
|
#include "../platform/common.hpp"
|
||||||
#include "../platform/utils.hpp"
|
#include "../platform/utils.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
|
// Fucking windows headers
|
||||||
|
#ifdef min
|
||||||
|
#undef min
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace cpptrace {
|
namespace cpptrace {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
CPPTRACE_FORCE_NO_INLINE
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
std::vector<uintptr_t> capture_frames(size_t skip) {
|
std::vector<uintptr_t> capture_frames(size_t skip, size_t max_depth) {
|
||||||
std::vector<void*> addrs(hard_max_frames, nullptr);
|
std::vector<void*> addrs(std::min(hard_max_frames, max_depth), nullptr);
|
||||||
int n_frames = CaptureStackBackTrace(static_cast<DWORD>(skip + 1), hard_max_frames, addrs.data(), NULL);
|
int n_frames = CaptureStackBackTrace(
|
||||||
addrs.resize(n_frames);
|
static_cast<ULONG>(skip + 1),
|
||||||
std::vector<uintptr_t> frames(addrs.size(), 0);
|
static_cast<ULONG>(addrs.size()),
|
||||||
for(std::size_t i = 0; i < addrs.size(); i++) {
|
addrs.data(),
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
std::vector<uintptr_t> frames(n_frames, 0);
|
||||||
|
for(std::size_t i = 0; i < n_frames; i++) {
|
||||||
frames[i] = reinterpret_cast<uintptr_t>(addrs[i]);
|
frames[i] = reinterpret_cast<uintptr_t>(addrs[i]);
|
||||||
}
|
}
|
||||||
return frames;
|
return frames;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user