Handle null lines / columns better
This commit is contained in:
parent
37a3ea7978
commit
aed456bc63
@ -3,8 +3,11 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
#include <limits>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "cpptrace/cpptrace_export.hpp"
|
#include "cpptrace/cpptrace_export.hpp"
|
||||||
@ -27,8 +30,8 @@ namespace cpptrace {
|
|||||||
struct CPPTRACE_EXPORT raw_trace {
|
struct CPPTRACE_EXPORT raw_trace {
|
||||||
std::vector<frame_ptr> frames;
|
std::vector<frame_ptr> frames;
|
||||||
static raw_trace from_buffer(frame_ptr* buffer, std::size_t size);
|
static raw_trace from_buffer(frame_ptr* buffer, std::size_t size);
|
||||||
static raw_trace current(std::uint_least32_t skip = 0);
|
static raw_trace current(std::size_t skip = 0);
|
||||||
static raw_trace current(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
static raw_trace current(std::size_t skip, std::size_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();
|
||||||
@ -53,8 +56,8 @@ namespace cpptrace {
|
|||||||
|
|
||||||
struct CPPTRACE_EXPORT object_trace {
|
struct CPPTRACE_EXPORT object_trace {
|
||||||
std::vector<object_frame> frames;
|
std::vector<object_frame> frames;
|
||||||
static object_trace current(std::uint_least32_t skip = 0);
|
static object_trace current(std::size_t skip = 0);
|
||||||
static object_trace current(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
static object_trace current(std::size_t skip, std::size_t max_depth);
|
||||||
stacktrace resolve() const;
|
stacktrace resolve() const;
|
||||||
void clear();
|
void clear();
|
||||||
bool empty() const noexcept;
|
bool empty() const noexcept;
|
||||||
@ -69,10 +72,50 @@ namespace cpptrace {
|
|||||||
inline const_iterator cend() const noexcept { return frames.cend(); }
|
inline const_iterator cend() const noexcept { return frames.cend(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This represents a nullable integer type
|
||||||
|
// The max value of the type is used as a sentinel
|
||||||
|
// This is used over std::optional because the library is C++11 and also std::optional is a bit heavy-duty for this
|
||||||
|
// use.
|
||||||
|
template<typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
|
||||||
|
struct CPPTRACE_EXPORT nullable {
|
||||||
|
T raw_value;
|
||||||
|
nullable& operator=(T value) {
|
||||||
|
raw_value = value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
bool has_value() const noexcept {
|
||||||
|
return raw_value != std::numeric_limits<T>::max();
|
||||||
|
}
|
||||||
|
T& value() noexcept {
|
||||||
|
return raw_value;
|
||||||
|
}
|
||||||
|
const T& value() const noexcept {
|
||||||
|
return raw_value;
|
||||||
|
}
|
||||||
|
T value_or(T alternative) const noexcept {
|
||||||
|
return has_value() ? raw_value : alternative;
|
||||||
|
}
|
||||||
|
void swap(nullable& other) noexcept {
|
||||||
|
std::swap(raw_value, other.raw_value);
|
||||||
|
}
|
||||||
|
void reset() noexcept {
|
||||||
|
raw_value = std::numeric_limits<T>::max();
|
||||||
|
}
|
||||||
|
bool operator==(const nullable& other) const noexcept {
|
||||||
|
return raw_value == other.raw_value;
|
||||||
|
}
|
||||||
|
bool operator!=(const nullable& other) const noexcept {
|
||||||
|
return raw_value != other.raw_value;
|
||||||
|
}
|
||||||
|
constexpr static nullable null() noexcept {
|
||||||
|
return { std::numeric_limits<T>::max() };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct CPPTRACE_EXPORT stacktrace_frame {
|
struct CPPTRACE_EXPORT stacktrace_frame {
|
||||||
frame_ptr address;
|
frame_ptr address;
|
||||||
std::uint_least32_t line; // TODO: This should use UINT_LEAST32_MAX as a sentinel
|
nullable<std::uint32_t> line;
|
||||||
std::uint_least32_t column; // UINT_LEAST32_MAX if not present
|
nullable<std::uint32_t> column;
|
||||||
std::string filename;
|
std::string filename;
|
||||||
std::string symbol;
|
std::string symbol;
|
||||||
bool is_inline;
|
bool is_inline;
|
||||||
@ -95,8 +138,8 @@ namespace cpptrace {
|
|||||||
|
|
||||||
struct CPPTRACE_EXPORT stacktrace {
|
struct CPPTRACE_EXPORT stacktrace {
|
||||||
std::vector<stacktrace_frame> frames;
|
std::vector<stacktrace_frame> frames;
|
||||||
static stacktrace current(std::uint_least32_t skip = 0);
|
static stacktrace current(std::size_t skip = 0);
|
||||||
static stacktrace current(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
static stacktrace current(std::size_t skip, std::size_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;
|
||||||
@ -118,23 +161,23 @@ namespace cpptrace {
|
|||||||
friend void print_terminate_trace();
|
friend void print_terminate_trace();
|
||||||
};
|
};
|
||||||
|
|
||||||
CPPTRACE_EXPORT raw_trace generate_raw_trace(std::uint_least32_t skip = 0);
|
CPPTRACE_EXPORT raw_trace generate_raw_trace(std::size_t skip = 0);
|
||||||
CPPTRACE_EXPORT raw_trace generate_raw_trace(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
CPPTRACE_EXPORT raw_trace generate_raw_trace(std::size_t skip, std::size_t max_depth);
|
||||||
CPPTRACE_EXPORT object_trace generate_object_trace(std::uint_least32_t skip = 0);
|
CPPTRACE_EXPORT object_trace generate_object_trace(std::size_t skip = 0);
|
||||||
CPPTRACE_EXPORT object_trace generate_object_trace(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
CPPTRACE_EXPORT object_trace generate_object_trace(std::size_t skip, std::size_t max_depth);
|
||||||
CPPTRACE_EXPORT stacktrace generate_trace(std::uint_least32_t skip = 0);
|
CPPTRACE_EXPORT stacktrace generate_trace(std::size_t skip = 0);
|
||||||
CPPTRACE_EXPORT stacktrace generate_trace(std::uint_least32_t skip, std::uint_least32_t max_depth);
|
CPPTRACE_EXPORT stacktrace generate_trace(std::size_t skip, std::size_t max_depth);
|
||||||
|
|
||||||
CPPTRACE_EXPORT std::size_t safe_generate_raw_trace(
|
CPPTRACE_EXPORT std::size_t safe_generate_raw_trace(
|
||||||
frame_ptr* buffer,
|
frame_ptr* buffer,
|
||||||
std::size_t size,
|
std::size_t size,
|
||||||
std::uint_least32_t skip = 0
|
std::size_t skip = 0
|
||||||
);
|
);
|
||||||
CPPTRACE_EXPORT std::size_t safe_generate_raw_trace(
|
CPPTRACE_EXPORT std::size_t safe_generate_raw_trace(
|
||||||
frame_ptr* buffer,
|
frame_ptr* buffer,
|
||||||
std::size_t size,
|
std::size_t size,
|
||||||
std::uint_least32_t skip,
|
std::size_t skip,
|
||||||
std::uint_least32_t max_depth
|
std::size_t max_depth
|
||||||
);
|
);
|
||||||
|
|
||||||
// utilities:
|
// utilities:
|
||||||
@ -172,8 +215,8 @@ namespace cpptrace {
|
|||||||
mutable std::string what_string;
|
mutable std::string what_string;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit exception(std::uint_least32_t skip, std::uint_least32_t max_depth) noexcept;
|
explicit exception(std::size_t skip, std::size_t max_depth) noexcept;
|
||||||
explicit exception(std::uint_least32_t skip) noexcept : exception(skip + 1, UINT_LEAST32_MAX) {}
|
explicit exception(std::size_t skip) noexcept : exception(skip + 1, SIZE_MAX) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit exception() noexcept : exception(1) {}
|
explicit exception() noexcept : exception(1) {}
|
||||||
@ -200,8 +243,8 @@ namespace cpptrace {
|
|||||||
|
|
||||||
explicit exception_with_message(
|
explicit exception_with_message(
|
||||||
std::string&& message_arg,
|
std::string&& message_arg,
|
||||||
std::uint_least32_t skip,
|
std::size_t skip,
|
||||||
std::uint_least32_t max_depth
|
std::size_t max_depth
|
||||||
) noexcept : exception(skip + 1, max_depth), message(std::move(message_arg)) {}
|
) noexcept : exception(skip + 1, max_depth), message(std::move(message_arg)) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@ -34,12 +34,12 @@ namespace cpptrace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
raw_trace raw_trace::current(std::uint_least32_t skip) {
|
raw_trace raw_trace::current(std::size_t skip) {
|
||||||
return generate_raw_trace(skip + 1);
|
return generate_raw_trace(skip + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
raw_trace raw_trace::current(std::uint_least32_t skip, std::uint_least32_t max_depth) {
|
raw_trace raw_trace::current(std::size_t skip, std::size_t max_depth) {
|
||||||
return generate_raw_trace(skip + 1, max_depth);
|
return generate_raw_trace(skip + 1, max_depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,12 +78,12 @@ namespace cpptrace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
object_trace object_trace::current(std::uint_least32_t skip) {
|
object_trace object_trace::current(std::size_t skip) {
|
||||||
return generate_object_trace(skip + 1);
|
return generate_object_trace(skip + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
object_trace object_trace::current(std::uint_least32_t skip, std::uint_least32_t max_depth) {
|
object_trace object_trace::current(std::size_t skip, std::size_t max_depth) {
|
||||||
return generate_object_trace(skip + 1, max_depth);
|
return generate_object_trace(skip + 1, max_depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,24 +125,24 @@ namespace cpptrace {
|
|||||||
<< frame.symbol
|
<< frame.symbol
|
||||||
<< " at "
|
<< " at "
|
||||||
<< frame.filename;
|
<< frame.filename;
|
||||||
if(frame.line != 0) {
|
if(frame.line.has_value()) {
|
||||||
stream
|
stream
|
||||||
<< ":"
|
<< ":"
|
||||||
<< frame.line;
|
<< frame.line.value();
|
||||||
if(frame.column != UINT_LEAST32_MAX) {
|
if(frame.column.has_value()) {
|
||||||
stream << frame.column;
|
stream << frame.column.value();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
stacktrace stacktrace::current(std::uint32_t skip) {
|
stacktrace stacktrace::current(std::size_t skip) {
|
||||||
return generate_trace(skip + 1);
|
return generate_trace(skip + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
stacktrace stacktrace::current(std::uint_least32_t skip, std::uint_least32_t max_depth) {
|
stacktrace stacktrace::current(std::size_t skip, std::size_t max_depth) {
|
||||||
return generate_trace(skip + 1, max_depth);
|
return generate_trace(skip + 1, max_depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,16 +206,16 @@ namespace cpptrace {
|
|||||||
<< green
|
<< green
|
||||||
<< frame.filename
|
<< frame.filename
|
||||||
<< reset;
|
<< reset;
|
||||||
if(frame.line != 0) {
|
if(frame.line.has_value()) {
|
||||||
stream
|
stream
|
||||||
<< ":"
|
<< ":"
|
||||||
<< blue
|
<< blue
|
||||||
<< frame.line
|
<< frame.line.value()
|
||||||
<< reset;
|
<< reset;
|
||||||
if(frame.column != UINT_LEAST32_MAX) {
|
if(frame.column.has_value()) {
|
||||||
stream << ':'
|
stream << ':'
|
||||||
<< blue
|
<< blue
|
||||||
<< std::to_string(frame.column)
|
<< std::to_string(frame.column.value())
|
||||||
<< reset;
|
<< reset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -245,9 +245,9 @@ namespace cpptrace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
raw_trace generate_raw_trace(std::uint_least32_t skip) {
|
raw_trace generate_raw_trace(std::size_t skip) {
|
||||||
try {
|
try {
|
||||||
return raw_trace{detail::capture_frames(skip + 1, UINT_LEAST32_MAX)};
|
return raw_trace{detail::capture_frames(skip + 1, SIZE_MAX)};
|
||||||
} catch(...) { // NOSONAR
|
} catch(...) { // NOSONAR
|
||||||
if(!detail::should_absorb_trace_exceptions()) {
|
if(!detail::should_absorb_trace_exceptions()) {
|
||||||
throw;
|
throw;
|
||||||
@ -257,7 +257,7 @@ namespace cpptrace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
raw_trace generate_raw_trace(std::uint_least32_t skip, std::uint_least32_t max_depth) {
|
raw_trace generate_raw_trace(std::size_t skip, std::size_t max_depth) {
|
||||||
try {
|
try {
|
||||||
return raw_trace{detail::capture_frames(skip + 1, max_depth)};
|
return raw_trace{detail::capture_frames(skip + 1, max_depth)};
|
||||||
} catch(...) { // NOSONAR
|
} catch(...) { // NOSONAR
|
||||||
@ -269,24 +269,24 @@ namespace cpptrace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
std::size_t safe_generate_raw_trace(frame_ptr* buffer, std::size_t size, std::uint_least32_t skip) {
|
std::size_t safe_generate_raw_trace(frame_ptr* buffer, std::size_t size, std::size_t skip) {
|
||||||
return detail::safe_capture_frames(buffer, size, skip + 1, UINT_LEAST32_MAX);
|
return detail::safe_capture_frames(buffer, size, skip + 1, SIZE_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
std::size_t safe_generate_raw_trace(
|
std::size_t safe_generate_raw_trace(
|
||||||
frame_ptr* buffer,
|
frame_ptr* buffer,
|
||||||
std::size_t size,
|
std::size_t size,
|
||||||
std::uint_least32_t skip,
|
std::size_t skip,
|
||||||
std::uint_least32_t max_depth
|
std::size_t max_depth
|
||||||
) {
|
) {
|
||||||
return detail::safe_capture_frames(buffer, size, skip + 1, max_depth);
|
return detail::safe_capture_frames(buffer, size, skip + 1, max_depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
object_trace generate_object_trace(std::uint_least32_t skip) {
|
object_trace generate_object_trace(std::size_t skip) {
|
||||||
try {
|
try {
|
||||||
return object_trace{detail::get_frames_object_info(detail::capture_frames(skip + 1, UINT_LEAST32_MAX))};
|
return object_trace{detail::get_frames_object_info(detail::capture_frames(skip + 1, SIZE_MAX))};
|
||||||
} catch(...) { // NOSONAR
|
} catch(...) { // NOSONAR
|
||||||
if(!detail::should_absorb_trace_exceptions()) {
|
if(!detail::should_absorb_trace_exceptions()) {
|
||||||
throw;
|
throw;
|
||||||
@ -296,7 +296,7 @@ namespace cpptrace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
object_trace generate_object_trace(std::uint_least32_t skip, std::uint_least32_t max_depth) {
|
object_trace generate_object_trace(std::size_t skip, std::size_t max_depth) {
|
||||||
try {
|
try {
|
||||||
return object_trace{detail::get_frames_object_info(detail::capture_frames(skip + 1, max_depth))};
|
return object_trace{detail::get_frames_object_info(detail::capture_frames(skip + 1, max_depth))};
|
||||||
} catch(...) { // NOSONAR
|
} catch(...) { // NOSONAR
|
||||||
@ -308,12 +308,12 @@ namespace cpptrace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
stacktrace generate_trace(std::uint_least32_t skip) {
|
stacktrace generate_trace(std::size_t skip) {
|
||||||
return generate_trace(skip + 1, UINT_LEAST32_MAX);
|
return generate_trace(skip + 1, SIZE_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
stacktrace generate_trace(std::uint32_t skip, std::uint_least32_t max_depth) {
|
stacktrace generate_trace(std::size_t skip, std::size_t max_depth) {
|
||||||
try {
|
try {
|
||||||
std::vector<frame_ptr> frames = detail::capture_frames(skip + 1, max_depth);
|
std::vector<frame_ptr> 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);
|
||||||
@ -412,7 +412,7 @@ namespace cpptrace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CPPTRACE_FORCE_NO_INLINE
|
CPPTRACE_FORCE_NO_INLINE
|
||||||
raw_trace get_raw_trace_and_absorb(std::uint_least32_t skip, std::uint_least32_t max_depth) noexcept {
|
raw_trace get_raw_trace_and_absorb(std::size_t skip, std::size_t max_depth) noexcept {
|
||||||
try {
|
try {
|
||||||
return generate_raw_trace(skip + 1, max_depth);
|
return generate_raw_trace(skip + 1, max_depth);
|
||||||
} catch(const std::exception& e) {
|
} catch(const std::exception& e) {
|
||||||
@ -429,7 +429,7 @@ namespace cpptrace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exception::exception(std::uint_least32_t skip, std::uint_least32_t max_depth) noexcept
|
exception::exception(std::size_t skip, std::size_t max_depth) noexcept
|
||||||
: trace(detail::get_raw_trace_and_absorb(skip + 1, max_depth)) {}
|
: trace(detail::get_raw_trace_and_absorb(skip + 1, max_depth)) {}
|
||||||
|
|
||||||
const char* exception::what() const noexcept {
|
const char* exception::what() const noexcept {
|
||||||
|
|||||||
@ -61,7 +61,7 @@ namespace detail {
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const stacktrace_frame null_frame {0, 0, UINT_LEAST32_MAX, "", "", false};
|
static const stacktrace_frame null_frame {0, nullable<uint32_t>::null(), nullable<uint32_t>::null(), "", "", false};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -63,10 +63,10 @@ namespace detail {
|
|||||||
if(result[i].address == 0) {
|
if(result[i].address == 0) {
|
||||||
result[i].address = trace[i].address;
|
result[i].address = trace[i].address;
|
||||||
}
|
}
|
||||||
if(result[i].line == 0) {
|
if(!result[i].line.has_value()) {
|
||||||
result[i].line = trace[i].line;
|
result[i].line = trace[i].line;
|
||||||
}
|
}
|
||||||
if(result[i].column == UINT_LEAST32_MAX) {
|
if(!result[i].column.has_value()) {
|
||||||
result[i].column = trace[i].column;
|
result[i].column = trace[i].column;
|
||||||
}
|
}
|
||||||
if(result[i].filename.empty()) {
|
if(result[i].filename.empty()) {
|
||||||
|
|||||||
@ -346,8 +346,8 @@ namespace dbghelp {
|
|||||||
std::fprintf(stderr, "Stack trace: Internal error while calling SymSetContext\n");
|
std::fprintf(stderr, "Stack trace: Internal error while calling SymSetContext\n");
|
||||||
return {
|
return {
|
||||||
addr,
|
addr,
|
||||||
static_cast<std::uint_least32_t>(line.LineNumber),
|
static_cast<std::uint32_t>(line.LineNumber),
|
||||||
UINT_LEAST32_MAX,
|
nullable<std::uint32_t>::null(),
|
||||||
line.FileName,
|
line.FileName,
|
||||||
symbol->Name,
|
symbol->Name,
|
||||||
false
|
false
|
||||||
@ -378,17 +378,24 @@ namespace dbghelp {
|
|||||||
signature = std::regex_replace(signature, comma_re, ", ");
|
signature = std::regex_replace(signature, comma_re, ", ");
|
||||||
return {
|
return {
|
||||||
addr,
|
addr,
|
||||||
static_cast<std::uint_least32_t>(line.LineNumber),
|
static_cast<std::int32_t>(line.LineNumber),
|
||||||
UINT_LEAST32_MAX,
|
nullable<std::uint32_t>::null(),
|
||||||
line.FileName,
|
line.FileName,
|
||||||
signature,
|
signature,
|
||||||
false,
|
false,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return { addr, 0, UINT_LEAST32_MAX, "", symbol->Name, false };
|
return {
|
||||||
|
addr,
|
||||||
|
nullable<std::uint32_t>::null(),
|
||||||
|
nullable<std::uint32_t>::null(),
|
||||||
|
"",
|
||||||
|
symbol->Name,
|
||||||
|
false
|
||||||
|
};
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return { addr, 0, UINT_LEAST32_MAX, "", "", false };
|
return { addr, nullable<std::uint32_t>::null(), nullable<std::uint32_t>::null(), "", "", false };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,16 +17,16 @@ namespace libdl {
|
|||||||
if(dladdr(reinterpret_cast<void*>(addr), &info)) { // thread-safe
|
if(dladdr(reinterpret_cast<void*>(addr), &info)) { // thread-safe
|
||||||
return {
|
return {
|
||||||
addr,
|
addr,
|
||||||
0,
|
nullable<std::uint32_t>::null(),
|
||||||
UINT_LEAST32_MAX,
|
nullable<std::uint32_t>::null(),
|
||||||
info.dli_fname ? info.dli_fname : "",
|
info.dli_fname ? info.dli_fname : "",
|
||||||
info.dli_sname ? info.dli_sname : ""
|
info.dli_sname ? info.dli_sname : ""
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
addr,
|
addr,
|
||||||
0,
|
nullable<std::uint32_t>::null(),
|
||||||
UINT_LEAST32_MAX,
|
nullable<std::uint32_t>::null(),
|
||||||
"",
|
"",
|
||||||
""
|
""
|
||||||
};
|
};
|
||||||
|
|||||||
@ -58,7 +58,7 @@ namespace libbacktrace {
|
|||||||
stacktrace_frame resolve_frame(const frame_ptr addr) {
|
stacktrace_frame resolve_frame(const frame_ptr addr) {
|
||||||
try {
|
try {
|
||||||
stacktrace_frame frame;
|
stacktrace_frame frame;
|
||||||
frame.column = UINT_LEAST32_MAX;
|
frame.column = nullable<std::uint32_t>::null();
|
||||||
backtrace_pcinfo(
|
backtrace_pcinfo(
|
||||||
get_backtrace_state(),
|
get_backtrace_state(),
|
||||||
addr,
|
addr,
|
||||||
|
|||||||
@ -606,7 +606,7 @@ namespace libdwarf {
|
|||||||
// {
|
// {
|
||||||
// Dwarf_Unsigned line_number = 0;
|
// Dwarf_Unsigned line_number = 0;
|
||||||
// VERIFY(wrap(dwarf_lineno, line, &line_number) == DW_DLV_OK);
|
// VERIFY(wrap(dwarf_lineno, line, &line_number) == DW_DLV_OK);
|
||||||
// frame.line = static_cast<std::uint_least32_t>(line_number);
|
// frame.line = static_cast<std::uint32_t>(line_number);
|
||||||
// char* filename = nullptr;
|
// char* filename = nullptr;
|
||||||
// VERIFY(wrap(dwarf_linesrc, line, &filename) == DW_DLV_OK);
|
// VERIFY(wrap(dwarf_linesrc, line, &filename) == DW_DLV_OK);
|
||||||
// auto wrapper = raii_wrap(
|
// auto wrapper = raii_wrap(
|
||||||
@ -660,7 +660,7 @@ namespace libdwarf {
|
|||||||
if(!table_it->line_number) {
|
if(!table_it->line_number) {
|
||||||
Dwarf_Unsigned line_number = 0;
|
Dwarf_Unsigned line_number = 0;
|
||||||
VERIFY(wrap(dwarf_lineno, line, &line_number) == DW_DLV_OK);
|
VERIFY(wrap(dwarf_lineno, line, &line_number) == DW_DLV_OK);
|
||||||
table_it->line_number = static_cast<std::uint_least32_t>(line_number);
|
table_it->line_number = static_cast<std::uint32_t>(line_number);
|
||||||
}
|
}
|
||||||
frame.line = table_it->line_number.unwrap();
|
frame.line = table_it->line_number.unwrap();
|
||||||
if(!table_it->path) {
|
if(!table_it->path) {
|
||||||
@ -716,7 +716,7 @@ namespace libdwarf {
|
|||||||
if(found_line) {
|
if(found_line) {
|
||||||
Dwarf_Unsigned line_number = 0;
|
Dwarf_Unsigned line_number = 0;
|
||||||
VERIFY(wrap(dwarf_lineno, found_line, &line_number) == DW_DLV_OK);
|
VERIFY(wrap(dwarf_lineno, found_line, &line_number) == DW_DLV_OK);
|
||||||
frame.line = static_cast<std::uint_least32_t>(line_number);
|
frame.line = static_cast<std::uint32_t>(line_number);
|
||||||
char* filename = nullptr;
|
char* filename = nullptr;
|
||||||
VERIFY(wrap(dwarf_linesrc, found_line, &filename) == DW_DLV_OK);
|
VERIFY(wrap(dwarf_linesrc, found_line, &filename) == DW_DLV_OK);
|
||||||
auto wrapper = raii_wrap(
|
auto wrapper = raii_wrap(
|
||||||
@ -912,8 +912,8 @@ namespace libdwarf {
|
|||||||
// inclusive range
|
// inclusive range
|
||||||
auto begin = final_trace.end() - (1 + entry.inlines.size());
|
auto begin = final_trace.end() - (1 + entry.inlines.size());
|
||||||
auto end = final_trace.end() - 1;
|
auto end = final_trace.end() - 1;
|
||||||
std::uint_least32_t carry_line = end->line;
|
auto carry_line = end->line;
|
||||||
std::uint_least32_t carry_column = end->column;
|
auto carry_column = end->column;
|
||||||
std::string carry_filename = std::move(end->filename);
|
std::string carry_filename = std::move(end->filename);
|
||||||
for(auto it = end; it != begin; it--) {
|
for(auto it = end; it != begin; it--) {
|
||||||
it->line = (it - 1)->line;
|
it->line = (it - 1)->line;
|
||||||
|
|||||||
@ -131,7 +131,7 @@ void custom_print(const cpptrace::stacktrace& trace) {
|
|||||||
std::cout
|
std::cout
|
||||||
<< normalize_filename(frame.filename)
|
<< normalize_filename(frame.filename)
|
||||||
<< "||"
|
<< "||"
|
||||||
<< frame.line
|
<< frame.line.value()
|
||||||
<< "||"
|
<< "||"
|
||||||
<< frame.symbol
|
<< frame.symbol
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user