[FarGroup/FarManager] master: Exception handling improvements (327e2016b)

0 views
Skip to first unread message

farg...@farmanager.com

unread,
Jan 9, 2026, 4:45:53 PM (7 days ago) Jan 9
to farco...@googlegroups.com
Repository : https://github.com/FarGroup/FarManager
On branch : master
Link : https://github.com/FarGroup/FarManager/commit/327e2016b6059f4e23870d4bdfa0efc50d05b158

>---------------------------------------------------------------

commit 327e2016b6059f4e23870d4bdfa0efc50d05b158
Author: Alex Alabuzhev <alab...@gmail.com>
Date: Fri Jan 9 20:52:28 2026 +0000

Exception handling improvements


>---------------------------------------------------------------

327e2016b6059f4e23870d4bdfa0efc50d05b158
far/cddrv.cpp | 2 +-
far/changelog | 5 +++
far/common/compiler.hpp | 8 -----
far/common/library.hpp | 25 +++++++++++----
far/common/shims_post.hpp | 50 +++++++++++++++++++++++------
far/common/shims_pre.hpp | 71 ++++++++++++++++++++++++++++++++++--------
far/exception_handler.cpp | 59 ++++++++++++++++-------------------
far/exception_handler_test.cpp | 4 +--
far/new_handler.cpp | 2 +-
far/platform.debug.cpp | 10 +++---
far/platform.headers.hpp | 5 +--
far/platform.sdk.hpp | 3 +-
far/vbuild.m4 | 2 +-
13 files changed, 164 insertions(+), 82 deletions(-)

diff --git a/far/cddrv.cpp b/far/cddrv.cpp
index 0edf37a15..f3a2f0e82 100644
--- a/far/cddrv.cpp
+++ b/far/cddrv.cpp
@@ -195,7 +195,7 @@ static auto capatibilities_from_scsi_configuration(const os::fs::file& Device)
{
auto Spt = InitSCSIPassThrough();

-#if !IS_MICROSOFT_SDK()
+#if LIBRARY(GNU)
// Old GCC headers incorrectly reserve only one bit for RequestType
static_assert(decltype(CDB::GET_CONFIGURATION){.RequestType = 0b11 }.RequestType == 0b11);
#endif
diff --git a/far/changelog b/far/changelog
index c5511a313..97e2587c5 100644
--- a/far/changelog
+++ b/far/changelog
@@ -1,3 +1,8 @@
+--------------------------------------------------------------------------------
+drkns 2026-01-09 20:52:21+00:00 - build 6627
+
+1. Exception handling improvements.
+
--------------------------------------------------------------------------------
drkns 2026-01-08 23:31:21+00:00 - build 6626

diff --git a/far/common/compiler.hpp b/far/common/compiler.hpp
index 5a6deb05d..fa9e82867 100644
--- a/far/common/compiler.hpp
+++ b/far/common/compiler.hpp
@@ -41,8 +41,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// both Intel and Clang preserve this macro.

// Use #if COMPILER(%NAME%) to check for a specific compiler.
-// Use IS_MICROSOFT_SDK() to check for Microsoft standard library / Windows SDK
-// Use _MSC_VER only to find out its specific version.


// Known compilers
@@ -65,12 +63,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#define COMPILER(Name) (DETAIL_COMPILER_CURRENT() == DETAIL_COMPILER_##Name())

-#ifdef _MSC_VER
-#define IS_MICROSOFT_SDK() 1
-#else
-#define IS_MICROSOFT_SDK() 0
-#endif
-
#if COMPILER(CL) || COMPILER(INTEL)
#define STR_PRAGMA(...) __pragma(__VA_ARGS__)
#elif COMPILER(GCC) || COMPILER(CLANG)
diff --git a/far/common/library.hpp b/far/common/library.hpp
index 678ce0649..3dbec8cf2 100644
--- a/far/common/library.hpp
+++ b/far/common/library.hpp
@@ -36,26 +36,39 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <version>

+// WARNING
+// Naive #ifdef _MSC_VER is a BAD WAY to check for Microsoft standard library:
+// both Intel and Clang preserve this macro.
+
+// Use #if LIBRARY(%NAME%) to check for a specific standard library.
+
+// Known standard libraries
+#define DETAIL_LIBRARY_MSVC() 0
+#define DETAIL_LIBRARY_GNU() 1
+#define DETAIL_LIBRARY_LLVM() 2
+
#if defined(_MSVC_STL_VERSION) && defined(_MSVC_STL_UPDATE)
+#define DETAIL_LIBRARY_CURRENT() DETAIL_LIBRARY_MSVC()
#define STANDARD_LIBRARY_NAME L"Microsoft STL"
#define STANDARD_LIBRARY_VERSION_MAJOR (_MSVC_STL_VERSION / 10)
#define STANDARD_LIBRARY_VERSION_MINOR (_MSVC_STL_VERSION % 10)
#define STANDARD_LIBRARY_VERSION_PATCH _MSVC_STL_UPDATE
#elif defined(_GLIBCXX_RELEASE) and defined(__GLIBCXX__)
-#define STANDARD_LIBRARY_NAME L"libstdc++"
+#define DETAIL_LIBRARY_CURRENT() DETAIL_LIBRARY_GNU()
+#define STANDARD_LIBRARY_NAME L"GNU libstdc++"
#define STANDARD_LIBRARY_VERSION_MAJOR _GLIBCXX_RELEASE
#define STANDARD_LIBRARY_VERSION_MINOR 0
#define STANDARD_LIBRARY_VERSION_PATCH __GLIBCXX__
#elif defined(_LIBCPP_VERSION)
-#define STANDARD_LIBRARY_NAME L"libc++"
+#define DETAIL_LIBRARY_CURRENT() DETAIL_LIBRARY_LLVM()
+#define STANDARD_LIBRARY_NAME L"LLVM libc++"
#define STANDARD_LIBRARY_VERSION_MAJOR (_LIBCPP_VERSION / 10000)
#define STANDARD_LIBRARY_VERSION_MINOR ((_LIBCPP_VERSION % 10000) / 100)
#define STANDARD_LIBRARY_VERSION_PATCH (_LIBCPP_VERSION % 100)
#else
-#define STANDARD_LIBRARY_NAME L"Unknown standard library"
-#define STANDARD_LIBRARY_VERSION_MAJOR 0
-#define STANDARD_LIBRARY_VERSION_MINOR 0
-#define STANDARD_LIBRARY_VERSION_PATCH 0
+#error Unknown standard library
#endif

+#define LIBRARY(Name) (DETAIL_LIBRARY_CURRENT() == DETAIL_LIBRARY_##Name())
+
#endif // LIBRARY_HPP_3C1EF122_E9E8_4F3D_8E2F_C5E2829E2E32
diff --git a/far/common/shims_post.hpp b/far/common/shims_post.hpp
index 1a2639896..6ca8cd750 100644
--- a/far/common/shims_post.hpp
+++ b/far/common/shims_post.hpp
@@ -52,7 +52,47 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#if COMPILER(GCC)

-// These inline implementations in gcc/cwchar are wrong and non-compilable if _CONST_RETURN is defined.
+
+
+#endif
+
+//----------------------------------------------------------------------------
+
+#if COMPILER(CLANG)
+
+
+
+#endif
+
+//----------------------------------------------------------------------------
+
+#if LIBRARY(MSVC)
+
+
+
+#endif
+
+//----------------------------------------------------------------------------
+
+#if LIBRARY(GNU)
+
+
+
+#endif
+
+//----------------------------------------------------------------------------
+
+#if LIBRARY(LLVM)
+
+
+
+#endif
+
+//----------------------------------------------------------------------------
+
+#if LIBRARY(GNU) || LIBRARY(LLVM)
+
+// These inline implementations in cwchar are wrong and non-compilable if _CONST_RETURN is defined.
namespace std
{
inline wchar_t* wcschr(wchar_t* p, wchar_t c)
@@ -87,14 +127,6 @@ using std::wcsrchr;
using std::wcsstr;
using std::wmemchr;

-#endif
-
-//----------------------------------------------------------------------------
-
-#if COMPILER(CLANG)
-
-
-
#endif

//----------------------------------------------------------------------------
diff --git a/far/common/shims_pre.hpp b/far/common/shims_pre.hpp
index 0222b7ff3..732e18929 100644
--- a/far/common/shims_pre.hpp
+++ b/far/common/shims_pre.hpp
@@ -37,8 +37,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "compiler.hpp"
-
-#include <version>
+#include "library.hpp"

//----------------------------------------------------------------------------

@@ -52,18 +51,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#if COMPILER(GCC)

-// Disable incompatible _wassert in assert.h and redeclare, so that we can override it
-#define __ASSERT_H_
-extern "C" void _wassert(wchar_t const* Message, wchar_t const* File, unsigned Line);

-// Current implementation of wcschr etc. in gcc removes const from the returned pointer. The issue has been opened since 2007.
-// These semi-magical defines and appropriate inline overloads in shims_post.hpp are intended to fix this madness.
-
-// Force C version to return const
-#undef _CONST_RETURN
-#define _CONST_RETURN const
-// Disable broken inline overloads
-#define __CORRECT_ISO_CPP_WCHAR_H_PROTO

#endif

@@ -81,4 +69,61 @@ WARNING_POP()

//----------------------------------------------------------------------------

+#if LIBRARY(MSVC)
+
+
+
+#endif
+
+//----------------------------------------------------------------------------
+
+#if LIBRARY(GNU)
+
+
+
+#endif
+
+//----------------------------------------------------------------------------
+
+#if LIBRARY(LLVM)
+
+
+
+#endif
+
+//----------------------------------------------------------------------------
+
+#if LIBRARY(GNU) || LIBRARY(LLVM)
+
+// Disable _wassert (redefined to far_assert) in cassert
+#define __ASSERT_H_
+void far_assert(wchar_t const* Message, wchar_t const* File, unsigned Line);
+
+// Declared without extern "C" in corecrt.h 🤦
+#ifdef _DEBUG
+#define _invalid_parameter _invalid_parameter_wrong_signature
+#endif
+#define _invalid_parameter_noinfo _invalid_parameter_noinfo_wrong_signature
+#include <corecrt.h>
+#ifdef _DEBUG
+#undef _invalid_parameter
+extern "C" _CRTIMP void _invalid_parameter(wchar_t const*, wchar_t const*, wchar_t const*, unsigned int, uintptr_t);
+#endif
+#undef _invalid_parameter_noinfo
+extern "C" _CRTIMP void _invalid_parameter_noinfo();
+
+
+// Current implementation of wcschr etc. in gcc removes const from the returned pointer. The issue has been opened since 2007.
+// These semi-magical defines and appropriate inline overloads in shims_post.hpp are intended to fix this madness.
+
+// Force C version to return const
+#undef _CONST_RETURN
+#define _CONST_RETURN const
+// Disable broken inline overloads
+#define __CORRECT_ISO_CPP_WCHAR_H_PROTO
+
+#endif
+
+//----------------------------------------------------------------------------
+
#endif // SHIMS_PRE_HPP_A18E0B5A_ECE5_4B78_96AA_55FE47AB1DEC
diff --git a/far/exception_handler.cpp b/far/exception_handler.cpp
index 9f5506608..85563802d 100644
--- a/far/exception_handler.cpp
+++ b/far/exception_handler.cpp
@@ -78,7 +78,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <crtdbg.h>

-#if !IS_MICROSOFT_SDK()
+#if !LIBRARY(MSVC)
#include <cxxabi.h>
#endif

@@ -1378,7 +1378,7 @@ static std::pair<string, string> extract_object_type_and_value(EXCEPTION_RECORD
return { TypeName, extract_object_value(TypeName, Iterator->object_ptr, Iterator->object_size) };
}

-#if !IS_MICROSOFT_SDK()
+#if !LIBRARY(MSVC)
if (const auto TypeInfo = abi::__cxa_current_exception_type(); TypeInfo)
{
const auto ExceptionPtr = std::current_exception();
@@ -2223,7 +2223,7 @@ unhandled_exception_filter::~unhandled_exception_filter()
}


-#if !IS_MICROSOFT_SDK()
+#if !LIBRARY(MSVC)
// For GCC. For some reason the default one works in Debug, but not in Release.
#ifndef _DEBUG
extern "C"
@@ -2264,23 +2264,10 @@ signal_handler::~signal_handler()
std::signal(SIGABRT, m_PreviousHandler);
}

-#if IS_MICROSOFT_SDK() && !defined _DEBUG // 🤦
-extern "C" void _invalid_parameter(wchar_t const*, wchar_t const*, wchar_t const*, unsigned int, uintptr_t);
-#endif
-
-[[noreturn]]
-static void default_invalid_parameter_handler(const wchar_t* const Expression, const wchar_t* const Function, const wchar_t* const File, unsigned int const Line, uintptr_t const Reserved)
-{
-#if IS_MICROSOFT_SDK()
- _invalid_parameter(Expression, Function, File, Line, Reserved);
-#endif
- os::process::terminate(STATUS_INVALID_CRUNTIME_PARAMETER);
-}
-
-static void invalid_parameter_handler_impl(const wchar_t* const Expression, const wchar_t* const Function, const wchar_t* const File, unsigned int const Line, uintptr_t const Reserved)
+static handler_result invalid_parameter_handler_impl(const wchar_t* const Expression, const wchar_t* const Function, const wchar_t* const File, unsigned int const Line)
{
if (!HandleCppExceptions)
- std::abort();
+ return handler_result::continue_search;

static auto InsideHandler = false;
if (InsideHandler)
@@ -2293,27 +2280,33 @@ static void invalid_parameter_handler_impl(const wchar_t* const Expression, cons
error_state_ex const LastError{ os::last_error(), {}, errno };
constexpr auto Location = source_location::current();

- switch (handle_generic_exception(
+ return handle_generic_exception(
Context,
Function && File?
- source_location(encoding::utf8::get_bytes(Function).c_str(), encoding::utf8::get_bytes(File).c_str(), Line) :
- Location,
+ source_location(encoding::utf8::get_bytes(Function).c_str(), encoding::utf8::get_bytes(File).c_str(), Line) :
+ Location,
{},
{},
NullToEmpty(Expression),
LastError
- ))
- {
- case handler_result::execute_handler:
- break;
-
- case handler_result::continue_execution:
- return;
+ );
+}

- case handler_result::continue_search:
+static void invalid_parameter_handler_impl(const wchar_t* const Expression, const wchar_t* const Function, const wchar_t* const File, unsigned int const Line, uintptr_t const Reserved)
+{
+ if (invalid_parameter_handler_impl(Expression, Function, File, Line) == handler_result::continue_search)
+ {
restore_system_exception_handler();
_set_invalid_parameter_handler({});
- default_invalid_parameter_handler(Expression, Function, File, Line, Reserved);
+#ifdef _UCRT
+#ifdef _DEBUG
+ _invalid_parameter(Expression, Function, File, Line, Reserved);
+#else
+ _invalid_parameter_noinfo();
+#endif
+#else
+ os::process::terminate(STATUS_INVALID_CRUNTIME_PARAMETER);
+#endif
}
}

@@ -2348,7 +2341,7 @@ static handler_result assert_handler_impl(string_view const Message, source_loca
}

#ifdef _DEBUG
-#if IS_MICROSOFT_SDK()
+#ifdef _UCRT
static int crt_report_hook_impl(int const ReportType, wchar_t* const Message, int*)
{
const auto MessageStr = trim_right(string_view{ Message });
@@ -2387,7 +2380,7 @@ static int crt_report_hook_impl(int const ReportType, wchar_t* const Message, in
crt_report_hook::crt_report_hook()
{
#ifdef _DEBUG
-#if IS_MICROSOFT_SDK()
+#ifdef _UCRT
_CrtSetReportHookW2(_CRT_RPTHOOK_INSTALL, crt_report_hook_impl);
#endif
#endif
@@ -2396,7 +2389,7 @@ crt_report_hook::crt_report_hook()
crt_report_hook::~crt_report_hook()
{
#ifdef _DEBUG
-#if IS_MICROSOFT_SDK()
+#ifdef _UCRT
_CrtSetReportHookW2(_CRT_RPTHOOK_REMOVE, crt_report_hook_impl);
#endif
#endif
diff --git a/far/exception_handler_test.cpp b/far/exception_handler_test.cpp
index 44b9ea44b..351cf993e 100644
--- a/far/exception_handler_test.cpp
+++ b/far/exception_handler_test.cpp
@@ -353,8 +353,8 @@ namespace tests

static void cpp_invalid_parameter()
{
-#if IS_MICROSOFT_SDK()
- const auto Func = printf;
+#ifdef _UCRT
+ const auto Func = _atoi64;
Func({});
#endif
}
diff --git a/far/new_handler.cpp b/far/new_handler.cpp
index a512eddb7..0fa186748 100644
--- a/far/new_handler.cpp
+++ b/far/new_handler.cpp
@@ -63,7 +63,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
static new_handler* NewHandler;

#if SET_CRT_NEW_HANDLER
-#if IS_MICROSOFT_SDK()
+#if LIBRARY(MSVC)
// New.h pollutes global namespace and causes name conflicts
extern "C"
{
diff --git a/far/platform.debug.cpp b/far/platform.debug.cpp
index 048dbf5b1..86b905c8a 100644
--- a/far/platform.debug.cpp
+++ b/far/platform.debug.cpp
@@ -58,7 +58,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <crtdbg.h>

-#if !IS_MICROSOFT_SDK()
+#if !LIBRARY(MSVC)
#include <cxxabi.h>
#endif

@@ -144,7 +144,7 @@ namespace os::debug
return &DummyContextPtr;
}

-#if IS_MICROSOFT_SDK()
+#if LIBRARY(MSVC)
extern "C" void** __current_exception();
extern "C" void** __current_exception_context();
#else
@@ -321,7 +321,7 @@ namespace os::debug
return (frameContext.FrameType & STACK_FRAME_TYPE_INLINE) != 0;
}

-#if !IS_MICROSOFT_SDK()
+#if !LIBRARY(MSVC)
static bool demangle_abi(const char* const SymbolName, string& Dest)
{
auto Status = -1;
@@ -366,7 +366,7 @@ namespace os::debug

// Empty or the same or failed to demangle
// For non-MSVC builds try to demangle it using ABI
-#if !IS_MICROSOFT_SDK()
+#if !LIBRARY(MSVC)
return demangle_abi(SymbolName, Dest);
#else
return false;
@@ -403,7 +403,7 @@ namespace os::debug

// Empty or the same or failed to demangle
// For non-MSVC builds try to demangle it using ABI
-#if !IS_MICROSOFT_SDK()
+#if !LIBRARY(MSVC)
demangle_abi(encoding::ansi::get_bytes(SymbolName).c_str(), SymbolName);
#endif
}
diff --git a/far/platform.headers.hpp b/far/platform.headers.hpp
index 96cfe2228..ed63a0f48 100644
--- a/far/platform.headers.hpp
+++ b/far/platform.headers.hpp
@@ -35,11 +35,12 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "common/compiler.hpp"
+#include "common/library.hpp"

#include "disable_warnings_in_std_begin.hpp"
//----------------------------------------------------------------------------

-#if !IS_MICROSOFT_SDK()
+#if !LIBRARY(MSVC)
#include <w32api.h>

#if (100*(__W32API_MAJOR_VERSION) + (__W32API_MINOR_VERSION)) < 314
@@ -101,7 +102,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#define _NTSCSI_USER_MODE_

-#if IS_MICROSOFT_SDK()
+#if LIBRARY(MSVC)
#include <scsi.h>
#else
#include <ntdef.h>
diff --git a/far/platform.sdk.hpp b/far/platform.sdk.hpp
index c9643ddb9..00dcb67a4 100644
--- a/far/platform.sdk.hpp
+++ b/far/platform.sdk.hpp
@@ -39,6 +39,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Common:
#include "common/preprocessor.hpp"
+#include "common/library.hpp"

// External:

@@ -49,7 +50,7 @@ WARNING_DISABLE_CLANG("-Wenum-constexpr-conversion")

#include "platform.sdk/sdk_common.h"

-#if IS_MICROSOFT_SDK()
+#if LIBRARY(MSVC)
#include "platform.sdk/sdk_vc.h"
#else
#include "platform.sdk/sdk_gcc.h"
diff --git a/far/vbuild.m4 b/far/vbuild.m4
index 3dbed1da1..47202c4a1 100644
--- a/far/vbuild.m4
+++ b/far/vbuild.m4
@@ -1 +1 @@
-6626
+6627


Reply all
Reply to author
Forward
0 new messages