From c9cc89cd8e6dbc7a1965c23eb11aa1b7e5ae569a Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sat, 30 Nov 2024 11:34:28 +0100 Subject: [PATCH] Support --enable-sanitizer for MSVC builds While it is already possible to enable ASan for MSVC (assuming Visual Studio 2019 16.10 or later) by passing `/fsanitizer=address` in the `CFLAGS`, it is only usable if `ZEND_DEBUG` is also enabled; otherwise there are `STATUS_BACK_STACK` errors all the time. Since it makes some sense to combine ASan instrumentation with debug assertions enabled anyway (typical for fuzzing), we support the configure option `--enable-sanitizer`, which is already supported for Clang builds, also for MSVC builds. Note that MSVC supports only ASan for now; contrary to Clang which additionally supports UBSan on Windows. Since ASan reports can be pretty useless without debug symbol information, we require such builds to also produce PDBs (i.e. `--enable-debug-pack`), but forbid actual debug builds (for performance reasons, and because the way it is implemented it would not make sense; that was already an issue with Clang builds with sanitizers enabled). Closes GH-16999. --- UPGRADING | 3 +++ win32/build/config.w32 | 16 ++++++++++++++-- win32/build/confutils.js | 10 ++++++++-- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/UPGRADING b/UPGRADING index c319d7299a4..4891bee45fb 100644 --- a/UPGRADING +++ b/UPGRADING @@ -166,6 +166,9 @@ PHP 8.5 UPGRADE NOTES PHP_RELEASE_VERSION are now always numbers. Previously, they have been strings for buildconf builds. +* --enable-sanitzer is now supported for MSVC builds. This enables ASan and + debug assertions, and is supported as of MSVC 16.9 and Windows 10. + * COM: . The extension is now build shared by default; previously it defaulted to a static extension, although the official Windows binaries built a shared diff --git a/win32/build/config.w32 b/win32/build/config.w32 index 2214b7341af..70e50891964 100644 --- a/win32/build/config.w32 +++ b/win32/build/config.w32 @@ -356,8 +356,20 @@ if (PHP_SECURITY_FLAGS == "yes") { } ARG_WITH("uncritical-warn-choke", "Disable some uncritical warnings", "yes"); -ARG_ENABLE("sanitizer", "Enable ASan and UBSan extensions", "no"); -if (CLANG_TOOLSET) { +ARG_ENABLE("sanitizer", "Enable ASan (and UBSan) extensions", "no"); +if (PHP_SANITIZER == "yes" && PHP_DEBUG == "yes") { + ERROR("Use of both --enable-sanitizer and --enable-debug not allowed."); +} +if (PHP_SANITIZER == "yes" && PHP_DEBUG_PACK == "no") { + ERROR("--enable-sanitizer requires --enable-debug-pack"); +} +if (VS_TOOLSET) { + if (PHP_SANITIZER == "yes") { + if (COMPILER_NUMERIC_VERSION < 1929) { + ERROR("MSVC at least 16.10 required for sanitation plugins"); + } + } +} else if (CLANG_TOOLSET) { if (PHP_UNCRITICAL_WARN_CHOKE != "no") { ADD_FLAG("CFLAGS", "-Wno-ignored-attributes -Wno-deprecated-declarations -Wno-missing-braces " + "-Wno-logical-op-parentheses -Wno-msvc-include -Wno-invalid-source-encoding -Wno-unknown-pragmas " + diff --git a/win32/build/confutils.js b/win32/build/confutils.js index e2b3f5dcb04..c44a607af1c 100644 --- a/win32/build/confutils.js +++ b/win32/build/confutils.js @@ -1246,6 +1246,8 @@ function SAPI(sapiname, file_list, makefiletarget, cflags, obj_dir) if (PHP_SANITIZER == "yes") { if (CLANG_TOOLSET) { add_asan_opts("CFLAGS_" + SAPI, "LIBS_" + SAPI, (is_lib ? "ARFLAGS_" : "LDFLAGS_") + SAPI); + } else if (VS_TOOLSET) { + ADD_FLAG("CFLAGS", "/fsanitize=address"); } } @@ -3442,8 +3444,12 @@ function toolset_setup_build_mode() ADD_FLAG("LDFLAGS", "/incremental:no /debug /opt:ref,icf"); } ADD_FLAG("CFLAGS", "/LD /MD"); - if (PHP_SANITIZER == "yes" && CLANG_TOOLSET) { - ADD_FLAG("CFLAGS", "/Od /D NDebug /D NDEBUG /D ZEND_WIN32_NEVER_INLINE /D ZEND_DEBUG=0"); + if (PHP_SANITIZER == "yes") { + if (VS_TOOLSET) { + ADD_FLAG("CFLAGS", "/Ox /U NDebug /U NDEBUG /D ZEND_DEBUG=1"); + } else if (CLANG_TOOLSET) { + ADD_FLAG("CFLAGS", "/Od /D NDebug /D NDEBUG /D ZEND_WIN32_NEVER_INLINE /D ZEND_DEBUG=0"); + } } else { // Equivalent to Release_TSInline build -> best optimization ADD_FLAG("CFLAGS", "/Ox /D NDebug /D NDEBUG /GF /D ZEND_DEBUG=0");