From 650f24af28488e7f3428a4ada6bedc5e89c7bb89 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). --- win32/build/config.w32 | 16 ++++++++++++++-- win32/build/confutils.js | 10 ++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/win32/build/config.w32 b/win32/build/config.w32 index dd33e595a2ee9..b0aa35ca3295f 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.0 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 e847417bc77b0..da89f0e68b67d 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");