| 18 | using namespace std::literals; |
| 19 | |
| 20 | Span<void *const> stackTrace(Span<void *> Buffer) noexcept { |
| 21 | #if WASMEDGE_OS_WINDOWS |
| 22 | struct DbgHelp { |
| 23 | DbgHelp() noexcept : Process(winapi::GetCurrentProcess()) { |
| 24 | winapi::SymSetOptions(winapi::SYMOPT_DEFERRED_LOADS_); |
| 25 | winapi::SymInitializeW(Process, nullptr, true); |
| 26 | SelfBase = winapi::SymGetModuleBase64( |
| 27 | Process, reinterpret_cast<winapi::DWORD64_>(&stackTrace)); |
| 28 | NtDllBase = winapi::SymGetModuleBase64( |
| 29 | Process, reinterpret_cast<winapi::DWORD64_>( |
| 30 | &winapi::RtlCaptureStackBackTrace)); |
| 31 | Kernel32Base = winapi::SymGetModuleBase64( |
| 32 | Process, reinterpret_cast<winapi::DWORD64_>(&winapi::CloseHandle)); |
| 33 | } |
| 34 | ~DbgHelp() noexcept { winapi::SymCleanup(Process); } |
| 35 | void refresh() noexcept { winapi::SymRefreshModuleList(Process); } |
| 36 | winapi::HANDLE_ Process; |
| 37 | winapi::DWORD64_ SelfBase, NtDllBase, Kernel32Base; |
| 38 | }; |
| 39 | static DbgHelp Helper; |
| 40 | Helper.refresh(); |
| 41 | auto Depth = static_cast<size_t>(winapi::RtlCaptureStackBackTrace( |
| 42 | 1u, static_cast<winapi::ULONG_>(Buffer.size()), Buffer.data(), nullptr)); |
| 43 | size_t NewDepth = 0; |
| 44 | for (size_t I = 0; I < Depth; ++I) { |
| 45 | auto Base = winapi::SymGetModuleBase64( |
| 46 | Helper.Process, reinterpret_cast<winapi::DWORD64_>(Buffer[I])); |
| 47 | if (Base == 0 || (Base != Helper.SelfBase && Base != Helper.NtDllBase && |
| 48 | Base != Helper.Kernel32Base)) { |
| 49 | Buffer[NewDepth++] = Buffer[I]; |
| 50 | } |
| 51 | } |
| 52 | return Buffer.first(static_cast<size_t>(NewDepth)); |
| 53 | #elif WASMEDGE_OS_LINUX |
| 54 | struct BacktraceState { |
| 55 | Span<void *> Buffer; |
| 56 | size_t Index; |
| 57 | }; |
| 58 | BacktraceState State{Buffer, 0}; |
| 59 | _Unwind_Backtrace( |
| 60 | [](struct _Unwind_Context *Ctx, void *Arg) noexcept { |
| 61 | auto &State = *static_cast<BacktraceState *>(Arg); |
| 62 | if (State.Index >= State.Buffer.size()) { |
| 63 | return _URC_END_OF_STACK; |
| 64 | } |
| 65 | State.Buffer[State.Index++] = |
| 66 | reinterpret_cast<void *>(_Unwind_GetIP(Ctx)); |
| 67 | return _URC_NO_REASON; |
| 68 | }, |
| 69 | &State); |
| 70 | return Buffer.first(State.Index); |
| 71 | #elif WASMEDGE_OS_MACOS |
| 72 | const auto Depth = backtrace(Buffer.data(), Buffer.size()); |
| 73 | return Buffer.first(Depth); |
| 74 | #endif |
| 75 | } |
| 76 | |
| 77 | Span<const uint32_t> |
no test coverage detected