From be3e20cfa2139ee140ff37427bb60d0b5f70af2a Mon Sep 17 00:00:00 2001 From: lipengyu Date: Sun, 25 Oct 2026 18:46:16 +0800 Subject: [PATCH] gh-157354: Honor sanitizer disable options in configure --- Lib/test/support/__init__.py | 23 +++-- ...-09-12-15-33-26.gh-issue-157354.2hw6fe.rst | 2 + configure | 86 ++++++++++++------- configure.ac | 38 ++++---- 4 files changed, 92 insertions(+), 57 deletions(-) create mode 100644 Misc/NEWS.d/next/Build/2026-09-12-15-33-26.gh-issue-157354.2hw6fe.rst diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 780f7895361749c..fca5b4987694ed7 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -11,6 +11,7 @@ import _opcode import os import re +import shlex import stat import sys import sysconfig @@ -443,22 +444,34 @@ def check_sanitizer(*, address=False, memory=False, ub=False, thread=False, cflags = sysconfig.get_config_var('CFLAGS') or '' - config_args = sysconfig.get_config_var('CONFIG_ARGS') or '' + config_args = shlex.split(sysconfig.get_config_var('CONFIG_ARGS') or '') + + def configured_with_sanitizer(name): + with_option = f'--with-{name}-sanitizer' + without_option = f'--without-{name}-sanitizer' + enabled = False + for arg in config_args: + if arg == without_option or arg == f'{with_option}=no': + enabled = False + elif arg == with_option or arg.startswith(f'{with_option}='): + enabled = True + return enabled + memory_sanitizer = ( '-fsanitize=memory' in cflags or - '--with-memory-sanitizer' in config_args + configured_with_sanitizer('memory') ) address_sanitizer = ( '-fsanitize=address' in cflags or - '--with-address-sanitizer' in config_args + configured_with_sanitizer('address') ) ub_sanitizer = ( '-fsanitize=undefined' in cflags or - '--with-undefined-behavior-sanitizer' in config_args + configured_with_sanitizer('undefined-behavior') ) thread_sanitizer = ( '-fsanitize=thread' in cflags or - '--with-thread-sanitizer' in config_args + configured_with_sanitizer('thread') ) function_sanitizer = ( '-fsanitize=function' in cflags diff --git a/Misc/NEWS.d/next/Build/2026-09-12-15-33-26.gh-issue-157354.2hw6fe.rst b/Misc/NEWS.d/next/Build/2026-09-12-15-33-26.gh-issue-157354.2hw6fe.rst new file mode 100644 index 000000000000000..5bc35aaf9870c2a --- /dev/null +++ b/Misc/NEWS.d/next/Build/2026-09-12-15-33-26.gh-issue-157354.2hw6fe.rst @@ -0,0 +1,2 @@ +Fix the :samp:`--with-{name}-sanitizer=no` and :samp:`--without-{name}-sanitizer` +:program:`configure` options enabling the sanitizer instead of disabling it. diff --git a/configure b/configure index 07048c1ec7f96b7..2a4b6fc96cc863a 100755 --- a/configure +++ b/configure @@ -13523,20 +13523,26 @@ printf %s "checking for --with-address-sanitizer... " >&6; } if test ${with_address_sanitizer+y} then : withval=$with_address_sanitizer; -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $withval" >&5 -printf "%s\n" "$withval" >&6; } +else case e in #( + e) with_address_sanitizer=no ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_address_sanitizer" >&5 +printf "%s\n" "$with_address_sanitizer" >&6; } +if test "x$with_address_sanitizer" = xno +then : + +else case e in #( + e) BASECFLAGS="-fsanitize=address -fno-omit-frame-pointer $BASECFLAGS" LDFLAGS="-fsanitize=address $LDFLAGS" # ASan works by controlling memory allocation, our own malloc interferes. with_pymalloc="no" - -else case e in #( - e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } ;; + ;; esac fi - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-memory-sanitizer" >&5 printf %s "checking for --with-memory-sanitizer... " >&6; } @@ -13544,8 +13550,18 @@ printf %s "checking for --with-memory-sanitizer... " >&6; } if test ${with_memory_sanitizer+y} then : withval=$with_memory_sanitizer; -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $withval" >&5 -printf "%s\n" "$withval" >&6; } +else case e in #( + e) with_memory_sanitizer=no ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_memory_sanitizer" >&5 +printf "%s\n" "$with_memory_sanitizer" >&6; } +if test "x$with_memory_sanitizer" = xno +then : + +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fsanitize=memory" >&5 printf %s "checking whether C compiler accepts -fsanitize=memory... " >&6; } if test ${ax_cv_check_cflags___fsanitize_memory+y} @@ -13592,14 +13608,10 @@ fi # MSan works by controlling memory allocation, our own malloc interferes. with_pymalloc="no" - -else case e in #( - e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } ;; + ;; esac fi - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-undefined-behavior-sanitizer" >&5 printf %s "checking for --with-undefined-behavior-sanitizer... " >&6; } @@ -13607,22 +13619,27 @@ printf %s "checking for --with-undefined-behavior-sanitizer... " >&6; } if test ${with_undefined_behavior_sanitizer+y} then : withval=$with_undefined_behavior_sanitizer; -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $withval" >&5 -printf "%s\n" "$withval" >&6; } -BASECFLAGS="-fsanitize=undefined $BASECFLAGS" -LDFLAGS="-fsanitize=undefined $LDFLAGS" -with_ubsan="yes" +else case e in #( + e) with_undefined_behavior_sanitizer=no ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_undefined_behavior_sanitizer" >&5 +printf "%s\n" "$with_undefined_behavior_sanitizer" >&6; } +if test "x$with_undefined_behavior_sanitizer" = xno +then : + +with_ubsan="no" else case e in #( e) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -with_ubsan="no" +BASECFLAGS="-fsanitize=undefined $BASECFLAGS" +LDFLAGS="-fsanitize=undefined $LDFLAGS" +with_ubsan="yes" ;; esac fi - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-thread-sanitizer" >&5 printf %s "checking for --with-thread-sanitizer... " >&6; } @@ -13630,22 +13647,27 @@ printf %s "checking for --with-thread-sanitizer... " >&6; } if test ${with_thread_sanitizer+y} then : withval=$with_thread_sanitizer; -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $withval" >&5 -printf "%s\n" "$withval" >&6; } -BASECFLAGS="-fsanitize=thread $BASECFLAGS" -LDFLAGS="-fsanitize=thread $LDFLAGS" -with_tsan="yes" +else case e in #( + e) with_thread_sanitizer=no ;; +esac +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_thread_sanitizer" >&5 +printf "%s\n" "$with_thread_sanitizer" >&6; } +if test "x$with_thread_sanitizer" = xno +then : + +with_tsan="no" else case e in #( e) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -with_tsan="no" +BASECFLAGS="-fsanitize=thread $BASECFLAGS" +LDFLAGS="-fsanitize=thread $LDFLAGS" +with_tsan="yes" ;; esac fi - # Set info about shared libraries. diff --git a/configure.ac b/configure.ac index e371f1edb06cff8..f51935d8813ca64 100644 --- a/configure.ac +++ b/configure.ac @@ -3401,14 +3401,14 @@ AC_MSG_CHECKING([for --with-address-sanitizer]) AC_ARG_WITH([address_sanitizer], AS_HELP_STRING([--with-address-sanitizer], [enable AddressSanitizer memory error detector, 'asan' (default is no)]), -[ -AC_MSG_RESULT([$withval]) +[], [with_address_sanitizer=no]) +AC_MSG_RESULT([$with_address_sanitizer]) +AS_VAR_IF([with_address_sanitizer], [no], [], [ BASECFLAGS="-fsanitize=address -fno-omit-frame-pointer $BASECFLAGS" LDFLAGS="-fsanitize=address $LDFLAGS" # ASan works by controlling memory allocation, our own malloc interferes. with_pymalloc="no" -], -[AC_MSG_RESULT([no])]) +]) AC_MSG_CHECKING([for --with-memory-sanitizer]) AC_ARG_WITH( @@ -3417,16 +3417,16 @@ AC_ARG_WITH( [--with-memory-sanitizer], [enable MemorySanitizer allocation error detector, 'msan' (default is no)] )], -[ -AC_MSG_RESULT([$withval]) +[], [with_memory_sanitizer=no]) +AC_MSG_RESULT([$with_memory_sanitizer]) +AS_VAR_IF([with_memory_sanitizer], [no], [], [ AX_CHECK_COMPILE_FLAG([-fsanitize=memory],[ BASECFLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer $BASECFLAGS" LDFLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 $LDFLAGS" ],[AC_MSG_ERROR([The selected compiler doesn't support memory sanitizer])]) # MSan works by controlling memory allocation, our own malloc interferes. with_pymalloc="no" -], -[AC_MSG_RESULT([no])]) +]) AC_MSG_CHECKING([for --with-undefined-behavior-sanitizer]) AC_ARG_WITH( @@ -3435,15 +3435,14 @@ AC_ARG_WITH( [--with-undefined-behavior-sanitizer], [enable UndefinedBehaviorSanitizer undefined behaviour detector, 'ubsan' (default is no)] )], -[ -AC_MSG_RESULT([$withval]) +[], [with_undefined_behavior_sanitizer=no]) +AC_MSG_RESULT([$with_undefined_behavior_sanitizer]) +AS_VAR_IF([with_undefined_behavior_sanitizer], [no], [ +with_ubsan="no" +], [ BASECFLAGS="-fsanitize=undefined $BASECFLAGS" LDFLAGS="-fsanitize=undefined $LDFLAGS" with_ubsan="yes" -], -[ -AC_MSG_RESULT([no]) -with_ubsan="no" ]) AC_MSG_CHECKING([for --with-thread-sanitizer]) @@ -3453,15 +3452,14 @@ AC_ARG_WITH( [--with-thread-sanitizer], [enable ThreadSanitizer data race detector, 'tsan' (default is no)] )], -[ -AC_MSG_RESULT([$withval]) +[], [with_thread_sanitizer=no]) +AC_MSG_RESULT([$with_thread_sanitizer]) +AS_VAR_IF([with_thread_sanitizer], [no], [ +with_tsan="no" +], [ BASECFLAGS="-fsanitize=thread $BASECFLAGS" LDFLAGS="-fsanitize=thread $LDFLAGS" with_tsan="yes" -], -[ -AC_MSG_RESULT([no]) -with_tsan="no" ]) # Set info about shared libraries.