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.
This commit is contained in:
Christoph M. Becker 2024-11-30 11:34:28 +01:00
parent d18b7220a1
commit c9cc89cd8e
No known key found for this signature in database
GPG key ID: D66C9593118BCCB6
3 changed files with 25 additions and 4 deletions

View file

@ -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

View file

@ -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 " +

View file

@ -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) {
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");