Skip to content

Commit

Permalink
Add stack_frame::get_native_offset method
Browse files Browse the repository at this point in the history
  • Loading branch information
gammasoft71 committed Oct 18, 2024
1 parent 82a5edb commit 54b1978
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ using namespace std;
using namespace xtd::native;

namespace {
constexpr size_t native_offset = 1;

string demangle_string(const string& method) {
auto result = method;
auto status = 0;
Expand All @@ -19,6 +21,11 @@ namespace {
}
}


size_t stack_trace::get_native_offset() {
return native_offset;
}

#if __ANDROID__ | __CYGWIN__ | __MINGW32__
stack_trace::frames stack_trace::get_frames(size_t skip_frames, size_t max_frames) {
return {};
Expand All @@ -31,7 +38,7 @@ stack_trace::frames stack_trace::get_frames(size_t skip_frames) {
traces.resize(max_frames);
auto nb_frames = static_cast<size_t>(backtrace(traces.data(), static_cast<int>(max_frames)));

for (auto index = skip_frames + 1; index < nb_frames; ++index) {
for (auto index = skip_frames + native_offset; index < nb_frames; ++index) {
auto dl_info = Dl_info {};
if (!dladdr(traces[index], &dl_info) || !dl_info.dli_sname) break;
frames.push_back(std::make_tuple(dl_info.dli_fname, 0, 0, demangle_string(dl_info.dli_sname), reinterpret_cast<size_t>(dl_info.dli_saddr) - reinterpret_cast<size_t>(dl_info.dli_fbase)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
using namespace xtd::native;

namespace {
constexpr size_t native_offset = 1;

std::string demangle_string(const std::string& method) {
auto result = method;
auto status = 0;
Expand All @@ -19,6 +21,10 @@
}
}

size_t stack_trace::get_native_offset() {
return native_offset;
}

stack_trace::frames stack_trace::get_frames(size_t skip_frames) {
//NSLog(@"%@", NSThread.callStackSymbols);
static constexpr auto max_frames = size_t {1024};
Expand All @@ -27,7 +33,7 @@
traces.resize(max_frames);
auto nb_frames = static_cast<size_t>(backtrace(traces.data(), static_cast<int>(max_frames)));

for (auto index = skip_frames + 1; index < nb_frames; ++index) {
for (auto index = skip_frames + native_offset; index < nb_frames; ++index) {
auto dl_info = Dl_info {};
if (!dladdr(traces[index], &dl_info) || !dl_info.dli_sname) break;
frames.push_back(std::make_tuple(dl_info.dli_fname, 0, 0, demangle_string(dl_info.dli_sname), reinterpret_cast<size_t>(dl_info.dli_saddr) - reinterpret_cast<size_t>(dl_info.dli_fbase)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ using namespace std;
using namespace xtd::native;

namespace {
constexpr size_t native_offset = 1;

string demangle_string(const string& method) {
auto result = method;
auto status = 0;
Expand All @@ -19,14 +21,18 @@ namespace {
}
}

size_t stack_trace::get_native_offset() {
return native_offset;
}

stack_trace::frames stack_trace::get_frames(size_t skip_frames) {
static constexpr size_t max_frames = 1024;
stack_trace::frames frames;
std::vector<void*> traces;
traces.resize(max_frames);
size_t nb_frames = backtrace(traces.data(), static_cast<int>(max_frames));

for (size_t index = skip_frames + 1; index < nb_frames; ++index) {
for (size_t index = skip_frames + native_offset; index < nb_frames; ++index) {
Dl_info dl_info;
if (!dladdr(traces[index], &dl_info) || !dl_info.dli_sname) break;
frames.push_back(std::make_tuple(dl_info.dli_fname, 0, 0, demangle_string(dl_info.dli_sname), reinterpret_cast<size_t>(dl_info.dli_saddr) - reinterpret_cast<size_t>(dl_info.dli_fbase)));
Expand Down
8 changes: 7 additions & 1 deletion src/xtd.core.native.unix/src/xtd/native/unix/stack_trace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ using namespace std;
using namespace xtd::native;

namespace {
constexpr size_t native_offset = 1;

string demangle_string(const string& method) {
auto result = method;
auto status = 0;
Expand All @@ -19,14 +21,18 @@ namespace {
}
}

size_t stack_trace::get_native_offset() {
return native_offset;
}

stack_trace::frames stack_trace::get_frames(size_t skip_frames) {
static constexpr size_t max_frames = 1024;
stack_trace::frames frames;
std::vector<void*> traces;
traces.resize(max_frames);
size_t nb_frames = backtrace(traces.data(), static_cast<int>(max_frames));

for (size_t index = skip_frames + 1; index < nb_frames; ++index) {
for (size_t index = skip_frames + native_offset; index < nb_frames; ++index) {
Dl_info dl_info;
if (!dladdr(traces[index], &dl_info) || !dl_info.dli_sname) break;
frames.push_back(std::make_tuple(dl_info.dli_fname, 0, 0, demangle_string(dl_info.dli_sname), reinterpret_cast<size_t>(dl_info.dli_saddr) - reinterpret_cast<size_t>(dl_info.dli_fbase)));
Expand Down
44 changes: 26 additions & 18 deletions src/xtd.core.native.win32/src/xtd/native/win32/stack_trace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,40 @@
using namespace std;
using namespace xtd::native;

class stack_walker final : public StackWalker {
public:
using frame = std::tuple<std::string, size_t, size_t, std::string, size_t>;
using frames = std::vector<frame>;
namespace {
constexpr size_t native_offset = 1;

stack_walker() : StackWalker(StackWalker::RetrieveVerbose | StackWalker::SymBuildPath) {}

const frames& get_frames() const noexcept {return frames_;}

private:
void OnCallstackEntry(CallstackEntryType type, CallstackEntry& entry) override {
StackWalker::OnCallstackEntry(type, entry);
frames_.push_back(make_tuple(entry.lineFileName, entry.lineNumber, entry.offsetFromLine, entry.name, static_cast<size_t>(entry.offsetFromSmybol)));
}

private:
frames frames_;
};
class stack_walker final : public StackWalker {
public:
using frame = std::tuple<std::string, size_t, size_t, std::string, size_t>;
using frames = std::vector<frame>;

stack_walker() : StackWalker(StackWalker::RetrieveVerbose | StackWalker::SymBuildPath) {}

const frames& get_frames() const noexcept {return frames_;}

private:
void OnCallstackEntry(CallstackEntryType type, CallstackEntry& entry) override {
StackWalker::OnCallstackEntry(type, entry);
frames_.push_back(make_tuple(entry.lineFileName, entry.lineNumber, entry.offsetFromLine, entry.name, static_cast<size_t>(entry.offsetFromSmybol)));
}

private:
frames frames_;
};
}

size_t stack_trace::get_native_offset() {
return native_offset;
}

stack_trace::frames stack_trace::get_frames(size_t skip_frames) {
auto sw = stack_walker {};
if (!sw.ShowCallstack()) return {};

auto result = stack_trace::frames {};
auto frames = sw.get_frames();
for (auto index = skip_frames + 1; index < frames.size(); ++index) {
for (auto index = skip_frames + native_offset; index < frames.size(); ++index) {
result.push_back(frames[index]);
if (get<3>(frames[index]) == "main") break;
}
Expand Down
5 changes: 5 additions & 0 deletions src/xtd.core.native/include/xtd/native/stack_trace.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ namespace xtd {
/// @name Protected Static Methods

/// @{
/// @brief Gets the offset from the start of the native code for the method that is being executed.
/// @return The offset from the start of the native code for the method that is being executed.
/// @warning Internal use only
static size_t get_native_offset();

/// @brief Play system sound.
/// @param sound The sound to play (see souund.h).
/// @warning Internal use only
Expand Down
17 changes: 17 additions & 0 deletions src/xtd.core/include/xtd/diagnostics/stack_frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,23 @@ namespace xtd {
/// ```
virtual const xtd::string& get_method() const noexcept;

/// @brief Gets the offset from the start of the native code for the method that is being executed.
/// @return The offset from the start of the native code for the method that is being executed.
/// @par Examples
/// The following example demonstrates the use of the get_offset() method. This code example is part of a larger example provided for the xtd::diagnostics::stack_frame class.
/// ```cpp
/// // Display the stack frame properties.
/// stack_frame sf = st.get_frame(i);
/// console::write_line(" File: {}", sf.get_file_name());
/// console::write_line(" Line Number: {}", sf.get_file_line_number());
/// // Note that the column number defaults to zero when not initialized.
/// console::write_line(" Column Number: {}", sf.get_file_column_number());
/// console::write_line(" Method: {}", sf.get_method());
/// if (sf.get_offset() != stack_frame::OFFSET_UNKNOWN)
/// console::write_line(" Native Offset: {}", sf.get_native_offset());
/// ```
virtual xtd::size get_native_offset() const noexcept;

/// @brief Gets the offset from the start of the code for the method that is being executed.
/// @return The offset from the code for the method that is being executed.
/// @par Examples
Expand Down
4 changes: 4 additions & 0 deletions src/xtd.core/src/xtd/diagnostics/stack_frame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ const string& stack_frame::get_method() const noexcept {
return data_->method_name;
}

xtd::size stack_frame::get_native_offset() const noexcept {
return native::stack_trace::get_native_offset();
}

xtd::size stack_frame::get_offset() const noexcept {
return data_->offset;
}
Expand Down

0 comments on commit 54b1978

Please sign in to comment.