Skip to content

Commit 2563dd2

Browse files
authored
[3.10] bpo-34602: Quadruple stack size on macOS when compiling with UBSAN (pythonGH-27309) (pythonGH-28280)
(cherry picked from commit be9de87) Co-authored-by: Łukasz Langa <[email protected]>
1 parent 89966f5 commit 2563dd2

File tree

5 files changed

+146
-113
lines changed

5 files changed

+146
-113
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
When building CPython on macOS with ``./configure
2+
--with-undefined-behavior-sanitizer --with-pydebug``, the stack size is now
3+
quadrupled to allow for the entire test suite to pass.

Python/thread_pthread.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,17 @@
3232
#define THREAD_STACK_SIZE 0 /* use default stack size */
3333
#endif
3434

35-
/* The default stack size for new threads on OSX and BSD is small enough that
35+
/* The default stack size for new threads on BSD is small enough that
3636
* we'll get hard crashes instead of 'maximum recursion depth exceeded'
3737
* exceptions.
3838
*
39-
* The default stack sizes below are the empirically determined minimal stack
39+
* The default stack size below is the empirically determined minimal stack
4040
* sizes where a simple recursive function doesn't cause a hard crash.
41+
*
42+
* For macOS the value of THREAD_STACK_SIZE is determined in configure.ac
43+
* as it also depends on the other configure options like chosen sanitizer
44+
* runtimes.
4145
*/
42-
#if defined(__APPLE__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
43-
#undef THREAD_STACK_SIZE
44-
/* Note: This matches the value of -Wl,-stack_size in configure.ac */
45-
#define THREAD_STACK_SIZE 0x1000000
46-
#endif
4746
#if defined(__FreeBSD__) && defined(THREAD_STACK_SIZE) && THREAD_STACK_SIZE == 0
4847
#undef THREAD_STACK_SIZE
4948
#define THREAD_STACK_SIZE 0x400000

configure

Lines changed: 81 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -827,11 +827,11 @@ with_trace_refs
827827
with_assertions
828828
enable_optimizations
829829
with_lto
830-
with_hash_algorithm
831-
with_tzpath
832830
with_address_sanitizer
833831
with_memory_sanitizer
834832
with_undefined_behavior_sanitizer
833+
with_hash_algorithm
834+
with_tzpath
835835
with_libs
836836
with_system_expat
837837
with_system_ffi
@@ -1547,12 +1547,6 @@ Optional Packages:
15471547
--with-assertions build with C assertions enabled (default is no)
15481548
--with-lto enable Link-Time-Optimization in any build (default
15491549
is no)
1550-
--with-hash-algorithm=[fnv|siphash24]
1551-
select hash algorithm for use in Python/pyhash.c
1552-
(default is SipHash24)
1553-
--with-tzpath=<list of absolute paths separated by pathsep>
1554-
Select the default time zone search path for zoneinfo.TZPATH
1555-
15561550
--with-address-sanitizer
15571551
enable AddressSanitizer memory error detector,
15581552
'asan' (default is no)
@@ -1561,6 +1555,12 @@ Optional Packages:
15611555
--with-undefined-behavior-sanitizer
15621556
enable UndefinedBehaviorSanitizer undefined
15631557
behaviour detector, 'ubsan' (default is no)
1558+
--with-hash-algorithm=[fnv|siphash24]
1559+
select hash algorithm for use in Python/pyhash.c
1560+
(default is SipHash24)
1561+
--with-tzpath=<list of absolute paths separated by pathsep>
1562+
Select the default time zone search path for zoneinfo.TZPATH
1563+
15641564
--with-libs='lib1 ...' link against additional libs (default is no)
15651565
--with-system-expat build pyexpat module using an installed expat
15661566
library, see Doc/library/pyexpat.rst (default is no)
@@ -9566,6 +9566,65 @@ $as_echo "no" >&6; }
95669566
;;
95679567
esac
95689568

9569+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-address-sanitizer" >&5
9570+
$as_echo_n "checking for --with-address-sanitizer... " >&6; }
9571+
9572+
# Check whether --with-address_sanitizer was given.
9573+
if test "${with_address_sanitizer+set}" = set; then :
9574+
withval=$with_address_sanitizer;
9575+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $withval" >&5
9576+
$as_echo "$withval" >&6; }
9577+
BASECFLAGS="-fsanitize=address -fno-omit-frame-pointer $BASECFLAGS"
9578+
LDFLAGS="-fsanitize=address $LDFLAGS"
9579+
# ASan works by controlling memory allocation, our own malloc interferes.
9580+
with_pymalloc="no"
9581+
9582+
else
9583+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
9584+
$as_echo "no" >&6; }
9585+
fi
9586+
9587+
9588+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-memory-sanitizer" >&5
9589+
$as_echo_n "checking for --with-memory-sanitizer... " >&6; }
9590+
9591+
# Check whether --with-memory_sanitizer was given.
9592+
if test "${with_memory_sanitizer+set}" = set; then :
9593+
withval=$with_memory_sanitizer;
9594+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $withval" >&5
9595+
$as_echo "$withval" >&6; }
9596+
BASECFLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer $BASECFLAGS"
9597+
LDFLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 $LDFLAGS"
9598+
# MSan works by controlling memory allocation, our own malloc interferes.
9599+
with_pymalloc="no"
9600+
9601+
else
9602+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
9603+
$as_echo "no" >&6; }
9604+
fi
9605+
9606+
9607+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-undefined-behavior-sanitizer" >&5
9608+
$as_echo_n "checking for --with-undefined-behavior-sanitizer... " >&6; }
9609+
9610+
# Check whether --with-undefined_behavior_sanitizer was given.
9611+
if test "${with_undefined_behavior_sanitizer+set}" = set; then :
9612+
withval=$with_undefined_behavior_sanitizer;
9613+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $withval" >&5
9614+
$as_echo "$withval" >&6; }
9615+
BASECFLAGS="-fsanitize=undefined $BASECFLAGS"
9616+
LDFLAGS="-fsanitize=undefined $LDFLAGS"
9617+
with_ubsan="yes"
9618+
9619+
else
9620+
9621+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
9622+
$as_echo "no" >&6; }
9623+
with_ubsan="no"
9624+
9625+
fi
9626+
9627+
95699628
# Set info about shared libraries.
95709629

95719630

@@ -9776,9 +9835,20 @@ then
97769835
# Issue #18075: the default maximum stack size (8MBytes) is too
97779836
# small for the default recursion limit. Increase the stack size
97789837
# to ensure that tests don't crash
9779-
# Note: This matches the value of THREAD_STACK_SIZE in
9780-
# thread_pthread.h
9781-
LINKFORSHARED="-Wl,-stack_size,1000000 $LINKFORSHARED"
9838+
stack_size="1000000" # 16 MB
9839+
if test "$with_ubsan" == "yes"
9840+
then
9841+
# Undefined behavior sanitizer requires an even deeper stack
9842+
stack_size="4000000" # 64 MB
9843+
fi
9844+
9845+
LINKFORSHARED="-Wl,-stack_size,$stack_size $LINKFORSHARED"
9846+
9847+
9848+
cat >>confdefs.h <<_ACEOF
9849+
#define THREAD_STACK_SIZE 0x$stack_size
9850+
_ACEOF
9851+
97829852

97839853
if test "$enable_framework"
97849854
then
@@ -10374,61 +10444,6 @@ fi
1037410444

1037510445

1037610446

10377-
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-address-sanitizer" >&5
10378-
$as_echo_n "checking for --with-address-sanitizer... " >&6; }
10379-
10380-
# Check whether --with-address_sanitizer was given.
10381-
if test "${with_address_sanitizer+set}" = set; then :
10382-
withval=$with_address_sanitizer;
10383-
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $withval" >&5
10384-
$as_echo "$withval" >&6; }
10385-
BASECFLAGS="-fsanitize=address -fno-omit-frame-pointer $BASECFLAGS"
10386-
LDFLAGS="-fsanitize=address $LDFLAGS"
10387-
# ASan works by controlling memory allocation, our own malloc interferes.
10388-
with_pymalloc="no"
10389-
10390-
else
10391-
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
10392-
$as_echo "no" >&6; }
10393-
fi
10394-
10395-
10396-
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-memory-sanitizer" >&5
10397-
$as_echo_n "checking for --with-memory-sanitizer... " >&6; }
10398-
10399-
# Check whether --with-memory_sanitizer was given.
10400-
if test "${with_memory_sanitizer+set}" = set; then :
10401-
withval=$with_memory_sanitizer;
10402-
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $withval" >&5
10403-
$as_echo "$withval" >&6; }
10404-
BASECFLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer $BASECFLAGS"
10405-
LDFLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 $LDFLAGS"
10406-
# MSan works by controlling memory allocation, our own malloc interferes.
10407-
with_pymalloc="no"
10408-
10409-
else
10410-
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
10411-
$as_echo "no" >&6; }
10412-
fi
10413-
10414-
10415-
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-undefined-behavior-sanitizer" >&5
10416-
$as_echo_n "checking for --with-undefined-behavior-sanitizer... " >&6; }
10417-
10418-
# Check whether --with-undefined_behavior_sanitizer was given.
10419-
if test "${with_undefined_behavior_sanitizer+set}" = set; then :
10420-
withval=$with_undefined_behavior_sanitizer;
10421-
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $withval" >&5
10422-
$as_echo "$withval" >&6; }
10423-
BASECFLAGS="-fsanitize=undefined $BASECFLAGS"
10424-
LDFLAGS="-fsanitize=undefined $LDFLAGS"
10425-
10426-
else
10427-
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
10428-
$as_echo "no" >&6; }
10429-
fi
10430-
10431-
1043210447
# Most SVR4 platforms (e.g. Solaris) need -lsocket and -lnsl.
1043310448
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for t_open in -lnsl" >&5
1043410449
$as_echo_n "checking for t_open in -lnsl... " >&6; }

configure.ac

Lines changed: 53 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2562,6 +2562,47 @@ case $ac_sys_system/$ac_sys_release in
25622562
;;
25632563
esac
25642564

2565+
AC_MSG_CHECKING(for --with-address-sanitizer)
2566+
AC_ARG_WITH(address_sanitizer,
2567+
AS_HELP_STRING([--with-address-sanitizer],
2568+
[enable AddressSanitizer memory error detector, 'asan' (default is no)]),
2569+
[
2570+
AC_MSG_RESULT($withval)
2571+
BASECFLAGS="-fsanitize=address -fno-omit-frame-pointer $BASECFLAGS"
2572+
LDFLAGS="-fsanitize=address $LDFLAGS"
2573+
# ASan works by controlling memory allocation, our own malloc interferes.
2574+
with_pymalloc="no"
2575+
],
2576+
[AC_MSG_RESULT(no)])
2577+
2578+
AC_MSG_CHECKING(for --with-memory-sanitizer)
2579+
AC_ARG_WITH(memory_sanitizer,
2580+
AS_HELP_STRING([--with-memory-sanitizer],
2581+
[enable MemorySanitizer allocation error detector, 'msan' (default is no)]),
2582+
[
2583+
AC_MSG_RESULT($withval)
2584+
BASECFLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer $BASECFLAGS"
2585+
LDFLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 $LDFLAGS"
2586+
# MSan works by controlling memory allocation, our own malloc interferes.
2587+
with_pymalloc="no"
2588+
],
2589+
[AC_MSG_RESULT(no)])
2590+
2591+
AC_MSG_CHECKING(for --with-undefined-behavior-sanitizer)
2592+
AC_ARG_WITH(undefined_behavior_sanitizer,
2593+
AS_HELP_STRING([--with-undefined-behavior-sanitizer],
2594+
[enable UndefinedBehaviorSanitizer undefined behaviour detector, 'ubsan' (default is no)]),
2595+
[
2596+
AC_MSG_RESULT($withval)
2597+
BASECFLAGS="-fsanitize=undefined $BASECFLAGS"
2598+
LDFLAGS="-fsanitize=undefined $LDFLAGS"
2599+
with_ubsan="yes"
2600+
],
2601+
[
2602+
AC_MSG_RESULT(no)
2603+
with_ubsan="no"
2604+
])
2605+
25652606
# Set info about shared libraries.
25662607
AC_SUBST(SHLIB_SUFFIX)
25672608
AC_SUBST(LDSHARED)
@@ -2765,9 +2806,18 @@ then
27652806
# Issue #18075: the default maximum stack size (8MBytes) is too
27662807
# small for the default recursion limit. Increase the stack size
27672808
# to ensure that tests don't crash
2768-
# Note: This matches the value of THREAD_STACK_SIZE in
2769-
# thread_pthread.h
2770-
LINKFORSHARED="-Wl,-stack_size,1000000 $LINKFORSHARED"
2809+
stack_size="1000000" # 16 MB
2810+
if test "$with_ubsan" == "yes"
2811+
then
2812+
# Undefined behavior sanitizer requires an even deeper stack
2813+
stack_size="4000000" # 64 MB
2814+
fi
2815+
2816+
LINKFORSHARED="-Wl,-stack_size,$stack_size $LINKFORSHARED"
2817+
2818+
AC_DEFINE_UNQUOTED(THREAD_STACK_SIZE,
2819+
0x$stack_size,
2820+
[Custom thread stack size depending on chosen sanitizer runtimes.])
27712821

27722822
if test "$enable_framework"
27732823
then
@@ -3011,43 +3061,6 @@ esac
30113061
AC_MSG_RESULT("$TZPATH")])
30123062
AC_SUBST(TZPATH)
30133063

3014-
AC_MSG_CHECKING(for --with-address-sanitizer)
3015-
AC_ARG_WITH(address_sanitizer,
3016-
AS_HELP_STRING([--with-address-sanitizer],
3017-
[enable AddressSanitizer memory error detector, 'asan' (default is no)]),
3018-
[
3019-
AC_MSG_RESULT($withval)
3020-
BASECFLAGS="-fsanitize=address -fno-omit-frame-pointer $BASECFLAGS"
3021-
LDFLAGS="-fsanitize=address $LDFLAGS"
3022-
# ASan works by controlling memory allocation, our own malloc interferes.
3023-
with_pymalloc="no"
3024-
],
3025-
[AC_MSG_RESULT(no)])
3026-
3027-
AC_MSG_CHECKING(for --with-memory-sanitizer)
3028-
AC_ARG_WITH(memory_sanitizer,
3029-
AS_HELP_STRING([--with-memory-sanitizer],
3030-
[enable MemorySanitizer allocation error detector, 'msan' (default is no)]),
3031-
[
3032-
AC_MSG_RESULT($withval)
3033-
BASECFLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer $BASECFLAGS"
3034-
LDFLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 $LDFLAGS"
3035-
# MSan works by controlling memory allocation, our own malloc interferes.
3036-
with_pymalloc="no"
3037-
],
3038-
[AC_MSG_RESULT(no)])
3039-
3040-
AC_MSG_CHECKING(for --with-undefined-behavior-sanitizer)
3041-
AC_ARG_WITH(undefined_behavior_sanitizer,
3042-
AS_HELP_STRING([--with-undefined-behavior-sanitizer],
3043-
[enable UndefinedBehaviorSanitizer undefined behaviour detector, 'ubsan' (default is no)]),
3044-
[
3045-
AC_MSG_RESULT($withval)
3046-
BASECFLAGS="-fsanitize=undefined $BASECFLAGS"
3047-
LDFLAGS="-fsanitize=undefined $LDFLAGS"
3048-
],
3049-
[AC_MSG_RESULT(no)])
3050-
30513064
# Most SVR4 platforms (e.g. Solaris) need -lsocket and -lnsl.
30523065
AC_CHECK_LIB(nsl, t_open, [LIBS="-lnsl $LIBS"]) # SVR4
30533066
AC_CHECK_LIB(socket, socket, [LIBS="-lsocket $LIBS"], [], $LIBS) # SVR4 sockets

pyconfig.h.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1509,6 +1509,9 @@
15091509
(which you can't on SCO ODT 3.0). */
15101510
#undef SYS_SELECT_WITH_SYS_TIME
15111511

1512+
/* Custom thread stack size depending on chosen sanitizer runtimes. */
1513+
#undef THREAD_STACK_SIZE
1514+
15121515
/* Library needed by timemodule.c: librt may be needed for clock_gettime() */
15131516
#undef TIMEMODULE_LIB
15141517

0 commit comments

Comments
 (0)