| 1801 | } |
| 1802 | |
| 1803 | static LONG exception_filter(PEXCEPTION_POINTERS pExp) noexcept |
| 1804 | { |
| 1805 | std::string msg = fmt::format("Unhandled Win32 exception 0x%08X.\n", pExp->ExceptionRecord->ExceptionCode); |
| 1806 | |
| 1807 | if (pExp->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) |
| 1808 | { |
| 1809 | const auto cause = |
| 1810 | pExp->ExceptionRecord->ExceptionInformation[0] == 8 ? "executing" : |
| 1811 | pExp->ExceptionRecord->ExceptionInformation[0] == 1 ? "writing" : |
| 1812 | "reading"; |
| 1813 | |
| 1814 | fmt::append(msg, "Segfault %s location %p at %p.\n", cause, pExp->ExceptionRecord->ExceptionInformation[1], pExp->ExceptionRecord->ExceptionAddress); |
| 1815 | |
| 1816 | if (vm::try_get_addr(reinterpret_cast<u8*>(pExp->ExceptionRecord->ExceptionInformation[1])).second) |
| 1817 | { |
| 1818 | fmt::append(msg, "Sudo Addr: %p, VM Addr: %p\n", vm::g_sudo_addr, vm::g_base_addr); |
| 1819 | } |
| 1820 | } |
| 1821 | else |
| 1822 | { |
| 1823 | fmt::append(msg, "Exception address: %p.\n", pExp->ExceptionRecord->ExceptionAddress); |
| 1824 | |
| 1825 | for (DWORD i = 0; i < pExp->ExceptionRecord->NumberParameters; i++) |
| 1826 | { |
| 1827 | fmt::append(msg, "ExceptionInformation[0x%x]: %p.\n", i, pExp->ExceptionRecord->ExceptionInformation[i]); |
| 1828 | } |
| 1829 | } |
| 1830 | |
| 1831 | append_thread_name(msg); |
| 1832 | |
| 1833 | std::vector<HMODULE> modules; |
| 1834 | for (DWORD size = 256; modules.size() != size; size /= sizeof(HMODULE)) |
| 1835 | { |
| 1836 | modules.resize(size); |
| 1837 | if (!EnumProcessModules(GetCurrentProcess(), modules.data(), size * sizeof(HMODULE), &size)) |
| 1838 | { |
| 1839 | modules.clear(); |
| 1840 | break; |
| 1841 | } |
| 1842 | } |
| 1843 | |
| 1844 | #if defined(ARCH_X64) |
| 1845 | const auto exec_addr = pExp->ContextRecord->Rip; |
| 1846 | #elif defined(ARCH_ARM64) |
| 1847 | const auto exec_addr = pExp->ContextRecord->Pc; |
| 1848 | #else |
| 1849 | #error "Unimplemented exception handling for this architecture" |
| 1850 | #endif |
| 1851 | |
| 1852 | fmt::append(msg, "Instruction address: %p.\n", exec_addr); |
| 1853 | |
| 1854 | DWORD64 unwind_base; |
| 1855 | if (const auto rtf = RtlLookupFunctionEntry(exec_addr, &unwind_base, nullptr)) |
| 1856 | { |
| 1857 | // Get function address |
| 1858 | const DWORD64 func_addr = rtf->BeginAddress + unwind_base; |
| 1859 | fmt::append(msg, "Function address: %p (base+0x%x).\n", func_addr, rtf->BeginAddress); |
| 1860 |
nothing calls this directly
no test coverage detected