|
9 | 9 | #include <format> |
10 | 10 |
|
11 | 11 | #include "runtime-common/core/runtime-core.h" |
| 12 | +#include "runtime-light/k2-platform/k2-api.h" |
12 | 13 | #include "runtime-light/stdlib/diagnostics/backtrace.h" |
13 | 14 | #include "runtime-light/utils/logs.h" |
14 | 15 |
|
15 | | -inline array<array<string>> f$debug_backtrace() noexcept { |
16 | | - static constexpr size_t MAX_STACKTRACE_DEPTH = 64; |
| 16 | +namespace error_handling_impl_ { |
| 17 | + |
| 18 | +inline array<array<string>> format_backtrace_symbols(std::span<void* const> backtrace) noexcept { |
| 19 | + auto resolved_backtrace{kphp::diagnostic::backtrace_symbols(backtrace)}; |
| 20 | + if (resolved_backtrace.empty()) { |
| 21 | + return {}; |
| 22 | + } |
| 23 | + |
| 24 | + array<array<string>> backtrace_symbols{array_size{static_cast<int64_t>(backtrace.size()), true}}; |
| 25 | + const string function_key{"function"}; |
| 26 | + const string filename_key{"file"}; |
| 27 | + const string line_key{"line"}; |
| 28 | + |
| 29 | + for (const k2::SymbolInfo& symbol_info : resolved_backtrace) { |
| 30 | + array<string> frame_info{array_size{3, false}}; |
| 31 | + frame_info.set_value(function_key, string{symbol_info.name.get()}); |
| 32 | + frame_info.set_value(filename_key, string{symbol_info.filename.get()}); |
| 33 | + frame_info.set_value(line_key, string{static_cast<int64_t>(symbol_info.lineno)}); |
| 34 | + |
| 35 | + backtrace_symbols.emplace_back(std::move(frame_info)); |
| 36 | + } |
| 37 | + |
| 38 | + return backtrace_symbols; |
| 39 | +} |
| 40 | + |
| 41 | +inline array<array<string>> format_backtrace_addresses(std::span<void* const> backtrace) noexcept { |
17 | 42 | static constexpr size_t LOG_BUFFER_SIZE = 32; |
18 | 43 |
|
19 | | - std::array<void*, MAX_STACKTRACE_DEPTH> raw_trace{}; |
20 | | - size_t num_frames{kphp::diagnostic::backtrace(raw_trace)}; |
21 | | - auto resolved_backtrace{kphp::diagnostic::backtrace_code_addresses(std::span<void*>(raw_trace.data(), num_frames))}; |
22 | | - if (resolved_backtrace.empty()) [[unlikely]] { |
23 | | - kphp::log::warning("cannot resolve virtual addresses to static offsets"); |
| 44 | + auto resolved_backtrace{kphp::diagnostic::backtrace_addresses(backtrace)}; |
| 45 | + if (resolved_backtrace.empty()) { |
24 | 46 | return {}; |
25 | 47 | } |
26 | 48 |
|
27 | | - array<array<string>> backtrace{array_size{static_cast<int64_t>(num_frames), true}}; |
| 49 | + array<array<string>> backtrace_addresses{array_size{static_cast<int64_t>(backtrace.size()), true}}; |
28 | 50 | const string function_key{"function"}; |
29 | 51 |
|
30 | 52 | for (const auto& address : resolved_backtrace) { |
31 | 53 | std::array<char, LOG_BUFFER_SIZE> log_buffer{}; |
32 | 54 | const auto [_, recorded]{std::format_to_n(log_buffer.data(), log_buffer.size() - 1, "{}", address)}; |
33 | 55 | array<string> frame_info{array_size{1, false}}; |
34 | 56 | frame_info.set_value(function_key, string{log_buffer.data(), static_cast<string::size_type>(recorded)}); |
35 | | - backtrace.emplace_back(std::move(frame_info)); |
| 57 | + |
| 58 | + backtrace_addresses.emplace_back(std::move(frame_info)); |
36 | 59 | } |
37 | 60 |
|
38 | | - return backtrace; |
| 61 | + return backtrace_addresses; |
| 62 | +} |
| 63 | +} // namespace error_handling_impl_ |
| 64 | + |
| 65 | +inline array<array<string>> f$debug_backtrace() noexcept { |
| 66 | + static constexpr size_t MAX_STACKTRACE_DEPTH = 64; |
| 67 | + |
| 68 | + std::array<void*, MAX_STACKTRACE_DEPTH> backtrace{}; |
| 69 | + size_t num_frames{kphp::diagnostic::backtrace(backtrace)}; |
| 70 | + std::span<void*> backtrace_view{backtrace.data(), num_frames}; |
| 71 | + auto backtrace_symbols{error_handling_impl_::format_backtrace_symbols(backtrace_view)}; |
| 72 | + if (!backtrace_symbols.empty()) { |
| 73 | + return backtrace_symbols; |
| 74 | + } |
| 75 | + auto backtrace_code_addresses{error_handling_impl_::format_backtrace_addresses(backtrace_view)}; |
| 76 | + if (!backtrace_code_addresses.empty()) { |
| 77 | + return backtrace_code_addresses; |
| 78 | + } |
| 79 | + kphp::log::warning("cannot resolve virtual addresses to debug information"); |
| 80 | + return {}; |
39 | 81 | } |
0 commit comments