diff --git a/far/changelog b/far/changelog index 496c4cb025..768d9878e9 100644 --- a/far/changelog +++ b/far/changelog @@ -1,3 +1,8 @@ +-------------------------------------------------------------------------------- +drkns 09.05.2021 00:20:43 +0100 - build 5796 + +1. Exception handling improvements. + -------------------------------------------------------------------------------- drkns 08.05.2021 14:53:05 +0100 - build 5795 diff --git a/far/exception_handler.cpp b/far/exception_handler.cpp index dd38543f0f..fe37be21e1 100644 --- a/far/exception_handler.cpp +++ b/far/exception_handler.cpp @@ -1075,14 +1075,13 @@ static string exception_name(EXCEPTION_RECORD const& ExceptionRecord, string_vie return WithType(format(FSTR(L"0x{:0>8X} - {}"sv), ExceptionRecord.ExceptionCode, Name)); } -static string exception_details(EXCEPTION_RECORD const& ExceptionRecord, string_view const Message) +static string exception_details(string_view const Module, EXCEPTION_RECORD const& ExceptionRecord, string_view const Message) { switch (static_cast(ExceptionRecord.ExceptionCode)) { case EXCEPTION_ACCESS_VIOLATION: case EXCEPTION_IN_PAGE_ERROR: { - const auto AccessedAddress = to_hex_wstring(ExceptionRecord.ExceptionInformation[1]); const auto Mode = [](ULONG_PTR Code) { switch (Code) @@ -1094,7 +1093,16 @@ static string exception_details(EXCEPTION_RECORD const& ExceptionRecord, string_ } }(ExceptionRecord.ExceptionInformation[0]); - return format(FSTR(L"Memory at {} could not be {}"sv), AccessedAddress, Mode); + string Symbol; + tracer.get_symbols(Module, { ExceptionRecord.ExceptionInformation[1] }, [&](string&& Line) + { + Symbol = std::move(Line); + }); + + if (Symbol.empty()) + Symbol = to_hex_wstring(ExceptionRecord.ExceptionInformation[1]); + + return format(FSTR(L"Memory at {} could not be {}"sv), Symbol, Mode); } case EXCEPTION_MICROSOFT_CPLUSPLUS: @@ -1153,7 +1161,7 @@ static bool handle_generic_exception( } const auto Exception = exception_name(Context.exception_record(), Type); - const auto Details = exception_details(Context.exception_record(), Message); + const auto Details = exception_details(strFileName, Context.exception_record(), Message); const auto PluginInformation = PluginModule? format(FSTR(L"{} {} ({}, {})"sv), PluginModule->Title(), @@ -1659,7 +1667,18 @@ namespace detail return EXCEPTION_CONTINUE_SEARCH; } - Ptr = std::make_exception_ptr(MAKE_EXCEPTION(seh_exception, *Info, true, concat(exception_name(*Info->ExceptionRecord, {}), L" - "sv, exception_details(*Info->ExceptionRecord, {})))); + Ptr = std::make_exception_ptr( + MAKE_EXCEPTION( + seh_exception, + *Info, + true, + concat( + exception_name(*Info->ExceptionRecord, {}), + L" - "sv, + exception_details({}, *Info->ExceptionRecord, {}) + ) + ) + ); return EXCEPTION_EXECUTE_HANDLER; } diff --git a/far/exception_handler_test.cpp b/far/exception_handler_test.cpp index 5bd63baa20..c781afc7a3 100644 --- a/far/exception_handler_test.cpp +++ b/far/exception_handler_test.cpp @@ -256,15 +256,26 @@ namespace tests volatile const auto Result = *InvalidAddress; } + static volatile const int ReadOnly = 0; static void seh_access_violation_write() { + // Try something real first to see the address + const_cast(ReadOnly) = 42; + + // Fallback volatile int* InvalidAddress = nullptr; *InvalidAddress = 42; } + static volatile const int NotExecutable = 42; static void seh_access_violation_execute() { using func_t = void(*)(); + + // Try something real first to see the address + reinterpret_cast(const_cast(&NotExecutable))(); + + // Fallback volatile const func_t InvalidAddress = nullptr; InvalidAddress(); } diff --git a/far/flink.cpp b/far/flink.cpp index a03e377710..7c0759044a 100644 --- a/far/flink.cpp +++ b/far/flink.cpp @@ -726,56 +726,65 @@ static string_view reparse_tag_to_string(DWORD ReparseTag) { switch (ReparseTag) { + default: return {}; + + // Localised case IO_REPARSE_TAG_MOUNT_POINT: return msg(lng::MListJunction); case IO_REPARSE_TAG_SYMLINK: return msg(lng::MListSymlink); - case IO_REPARSE_TAG_HSM: return L"HSM"sv; - case IO_REPARSE_TAG_HSM2: return L"HSM2"sv; - case IO_REPARSE_TAG_SIS: return L"SIS"sv; - case IO_REPARSE_TAG_WIM: return L"WIM"sv; - case IO_REPARSE_TAG_CSV: return L"CSV"sv; - case IO_REPARSE_TAG_DFS: return L"DFS"sv; - case IO_REPARSE_TAG_DFSR: return L"DFSR"sv; - case IO_REPARSE_TAG_DEDUP: return L"DEDUP"sv; - case IO_REPARSE_TAG_NFS: return L"NFS"sv; - case IO_REPARSE_TAG_FILE_PLACEHOLDER: return L"FILE PLACEHOLDER"sv; - case IO_REPARSE_TAG_WOF: return L"WOF"sv; - case IO_REPARSE_TAG_WCI: return L"WCI"sv; - case IO_REPARSE_TAG_WCI_1: return L"WCI 1"sv; - case IO_REPARSE_TAG_GLOBAL_REPARSE: return L"GLOBAL_REPARSE"sv; - case IO_REPARSE_TAG_CLOUD: return L"CLOUD"sv; - case IO_REPARSE_TAG_CLOUD_1: return L"CLOUD 1"sv; - case IO_REPARSE_TAG_CLOUD_2: return L"CLOUD 2"sv; - case IO_REPARSE_TAG_CLOUD_3: return L"CLOUD 3"sv; - case IO_REPARSE_TAG_CLOUD_4: return L"CLOUD 4"sv; - case IO_REPARSE_TAG_CLOUD_5: return L"CLOUD 5"sv; - case IO_REPARSE_TAG_CLOUD_6: return L"CLOUD 6"sv; - case IO_REPARSE_TAG_CLOUD_7: return L"CLOUD 7"sv; - case IO_REPARSE_TAG_CLOUD_8: return L"CLOUD 8"sv; - case IO_REPARSE_TAG_CLOUD_9: return L"CLOUD 9"sv; - case IO_REPARSE_TAG_CLOUD_A: return L"CLOUD A"sv; - case IO_REPARSE_TAG_CLOUD_B: return L"CLOUD B"sv; - case IO_REPARSE_TAG_CLOUD_C: return L"CLOUD C"sv; - case IO_REPARSE_TAG_CLOUD_D: return L"CLOUD D"sv; - case IO_REPARSE_TAG_CLOUD_E: return L"CLOUD E"sv; - case IO_REPARSE_TAG_CLOUD_F: return L"CLOUD F"sv; - case IO_REPARSE_TAG_APPEXECLINK: return L"APPEXECLINK"sv; - case IO_REPARSE_TAG_PROJFS: return L"PROJFS"sv; - case IO_REPARSE_TAG_STORAGE_SYNC: return L"STORAGE SYNC"sv; - case IO_REPARSE_TAG_WCI_TOMBSTONE: return L"WCI TOMBSTONE"sv; - case IO_REPARSE_TAG_UNHANDLED: return L"UNHANDLED"sv; - case IO_REPARSE_TAG_ONEDRIVE: return L"ONEDRIVE"sv; - case IO_REPARSE_TAG_PROJFS_TOMBSTONE: return L"PROJFS TOMBSTONE"sv; - case IO_REPARSE_TAG_AF_UNIX: return L"AF UNIX"sv; - case IO_REPARSE_TAG_LX_SYMLINK: return L"LX SYMLINK"sv; - case IO_REPARSE_TAG_LX_FIFO: return L"LX FIFO"sv; - case IO_REPARSE_TAG_LX_CHR: return L"LX CHR"sv; - case IO_REPARSE_TAG_LX_BLK: return L"LX BLK"sv; - case IO_REPARSE_TAG_DRIVE_EXTENDER: return L"DRIVE EXTENDER"sv; - case IO_REPARSE_TAG_FILTER_MANAGER: return L"FILTER MANAGER"sv; - case IO_REPARSE_TAG_IIS_CACHE: return L"IIS CACHE"sv; - case IO_REPARSE_TAG_APPXSTRM: return L"APPXSTRM"sv; - case IO_REPARSE_TAG_DFM: return L"DFM"sv; - default: return {}; + + // Generated +#define TAG_STR(name) case IO_REPARSE_TAG_ ## name: return WSTRVIEW(name); + // MS tags: + TAG_STR(HSM) + TAG_STR(HSM2) + TAG_STR(SIS) + TAG_STR(WIM) + TAG_STR(CSV) + TAG_STR(DFS) + TAG_STR(DFSR) + TAG_STR(DEDUP) + TAG_STR(NFS) + TAG_STR(FILE_PLACEHOLDER) + TAG_STR(WOF) + TAG_STR(WCI) + TAG_STR(WCI_1) + TAG_STR(GLOBAL_REPARSE) + TAG_STR(CLOUD) + TAG_STR(CLOUD_1) + TAG_STR(CLOUD_2) + TAG_STR(CLOUD_3) + TAG_STR(CLOUD_4) + TAG_STR(CLOUD_5) + TAG_STR(CLOUD_6) + TAG_STR(CLOUD_7) + TAG_STR(CLOUD_8) + TAG_STR(CLOUD_9) + TAG_STR(CLOUD_A) + TAG_STR(CLOUD_B) + TAG_STR(CLOUD_C) + TAG_STR(CLOUD_D) + TAG_STR(CLOUD_E) + TAG_STR(CLOUD_F) + TAG_STR(APPEXECLINK) + TAG_STR(PROJFS) + TAG_STR(STORAGE_SYNC) + TAG_STR(WCI_TOMBSTONE) + TAG_STR(UNHANDLED) + TAG_STR(ONEDRIVE) + TAG_STR(PROJFS_TOMBSTONE) + TAG_STR(AF_UNIX) + TAG_STR(LX_SYMLINK) + TAG_STR(LX_FIFO) + TAG_STR(LX_CHR) + TAG_STR(LX_BLK) + TAG_STR(DRIVE_EXTENDER) + TAG_STR(FILTER_MANAGER) + TAG_STR(IIS_CACHE) + TAG_STR(APPXSTRM) + TAG_STR(DFM) + + // TODO: there's almost a hundred of non-MS tags +#undef TAG_STR } } diff --git a/far/vbuild.m4 b/far/vbuild.m4 index dc85b9d66a..2f43629ca0 100644 --- a/far/vbuild.m4 +++ b/far/vbuild.m4 @@ -1 +1 @@ -5795 +5796