Skip to content

Commit 5c2ec84

Browse files
committed
Merge branch 'main' of https://github.com/Rasputin2/cpython into Issue_80914_Adding_PEP_318_Reference
2 parents 5d673ec + 471aa75 commit 5c2ec84

File tree

10 files changed

+84
-11
lines changed

10 files changed

+84
-11
lines changed

Doc/library/configparser.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ out. Values can also span multiple lines, as long as they are indented deeper
271271
than the first line of the value. Depending on the parser's mode, blank lines
272272
may be treated as parts of multiline values or ignored.
273273

274-
By default, a valid section name can be any string that does not contain '\\n' or ']'.
274+
By default, a valid section name can be any string that does not contain '\\n'.
275275
To change this, see :attr:`ConfigParser.SECTCRE`.
276276

277277
Configuration files may include comments, prefixed by specific

Doc/library/signal.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ The variables defined in the :mod:`signal` module are:
157157

158158
Alias to :data:`SIGCHLD`.
159159

160+
.. availability:: not macOS.
161+
160162
.. data:: SIGCONT
161163

162164
Continue the process if it is currently stopped

Doc/using/configure.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,13 @@ Debug options
745745

746746
.. versionadded:: 3.6
747747

748+
.. option:: --with-thread-sanitizer
749+
750+
Enable ThreadSanitizer data race detector, ``tsan``
751+
(default is no).
752+
753+
.. versionadded:: 3.13
754+
748755

749756
Linker options
750757
--------------

Include/pyport.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,11 @@ extern "C" {
563563
# define _Py_ADDRESS_SANITIZER
564564
# endif
565565
# endif
566+
# if __has_feature(thread_sanitizer)
567+
# if !defined(_Py_THREAD_SANITIZER)
568+
# define _Py_THREAD_SANITIZER
569+
# endif
570+
# endif
566571
#elif defined(__GNUC__)
567572
# if defined(__SANITIZE_ADDRESS__)
568573
# define _Py_ADDRESS_SANITIZER

Lib/test/libregrtest/utils.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,9 @@ def get_build_info():
340340
# --with-undefined-behavior-sanitizer
341341
if support.check_sanitizer(ub=True):
342342
sanitizers.append("UBSAN")
343+
# --with-thread-sanitizer
344+
if support.check_sanitizer(thread=True):
345+
sanitizers.append("TSAN")
343346
if sanitizers:
344347
build.append('+'.join(sanitizers))
345348

@@ -634,19 +637,23 @@ def display_header(use_resources: tuple[str, ...],
634637
asan = support.check_sanitizer(address=True)
635638
msan = support.check_sanitizer(memory=True)
636639
ubsan = support.check_sanitizer(ub=True)
640+
tsan = support.check_sanitizer(thread=True)
637641
sanitizers = []
638642
if asan:
639643
sanitizers.append("address")
640644
if msan:
641645
sanitizers.append("memory")
642646
if ubsan:
643647
sanitizers.append("undefined behavior")
648+
if tsan:
649+
sanitizers.append("thread")
644650
if sanitizers:
645651
print(f"== sanitizers: {', '.join(sanitizers)}")
646652
for sanitizer, env_var in (
647653
(asan, "ASAN_OPTIONS"),
648654
(msan, "MSAN_OPTIONS"),
649655
(ubsan, "UBSAN_OPTIONS"),
656+
(tsan, "TSAN_OPTIONS"),
650657
):
651658
options= os.environ.get(env_var)
652659
if sanitizer and options is not None:

Lib/test/support/__init__.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -392,10 +392,10 @@ def skip_if_buildbot(reason=None):
392392
isbuildbot = False
393393
return unittest.skipIf(isbuildbot, reason)
394394

395-
def check_sanitizer(*, address=False, memory=False, ub=False):
395+
def check_sanitizer(*, address=False, memory=False, ub=False, thread=False):
396396
"""Returns True if Python is compiled with sanitizer support"""
397-
if not (address or memory or ub):
398-
raise ValueError('At least one of address, memory, or ub must be True')
397+
if not (address or memory or ub or thread):
398+
raise ValueError('At least one of address, memory, ub or thread must be True')
399399

400400

401401
cflags = sysconfig.get_config_var('CFLAGS') or ''
@@ -412,18 +412,23 @@ def check_sanitizer(*, address=False, memory=False, ub=False):
412412
'-fsanitize=undefined' in cflags or
413413
'--with-undefined-behavior-sanitizer' in config_args
414414
)
415+
thread_sanitizer = (
416+
'-fsanitize=thread' in cflags or
417+
'--with-thread-sanitizer' in config_args
418+
)
415419
return (
416420
(memory and memory_sanitizer) or
417421
(address and address_sanitizer) or
418-
(ub and ub_sanitizer)
422+
(ub and ub_sanitizer) or
423+
(thread and thread_sanitizer)
419424
)
420425

421426

422-
def skip_if_sanitizer(reason=None, *, address=False, memory=False, ub=False):
427+
def skip_if_sanitizer(reason=None, *, address=False, memory=False, ub=False, thread=False):
423428
"""Decorator raising SkipTest if running with a sanitizer active."""
424429
if not reason:
425430
reason = 'not working with sanitizers active'
426-
skip = check_sanitizer(address=address, memory=memory, ub=ub)
431+
skip = check_sanitizer(address=address, memory=memory, ub=ub, thread=thread)
427432
return unittest.skipIf(skip, reason)
428433

429434
# gh-89363: True if fork() can hang if Python is built with Address Sanitizer
@@ -432,7 +437,7 @@ def skip_if_sanitizer(reason=None, *, address=False, memory=False, ub=False):
432437

433438

434439
def set_sanitizer_env_var(env, option):
435-
for name in ('ASAN_OPTIONS', 'MSAN_OPTIONS', 'UBSAN_OPTIONS'):
440+
for name in ('ASAN_OPTIONS', 'MSAN_OPTIONS', 'UBSAN_OPTIONS', 'TSAN_OPTIONS'):
436441
if name in env:
437442
env[name] += f':{option}'
438443
else:

Lib/test/test_io.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1654,7 +1654,8 @@ def test_truncate_on_read_only(self):
16541654
class CBufferedReaderTest(BufferedReaderTest, SizeofTest):
16551655
tp = io.BufferedReader
16561656

1657-
@skip_if_sanitizer(memory=True, address=True, reason= "sanitizer defaults to crashing "
1657+
@skip_if_sanitizer(memory=True, address=True, thread=True,
1658+
reason="sanitizer defaults to crashing "
16581659
"instead of returning NULL for malloc failure.")
16591660
def test_constructor(self):
16601661
BufferedReaderTest.test_constructor(self)
@@ -2021,7 +2022,8 @@ def test_slow_close_from_thread(self):
20212022
class CBufferedWriterTest(BufferedWriterTest, SizeofTest):
20222023
tp = io.BufferedWriter
20232024

2024-
@skip_if_sanitizer(memory=True, address=True, reason= "sanitizer defaults to crashing "
2025+
@skip_if_sanitizer(memory=True, address=True, thread=True,
2026+
reason="sanitizer defaults to crashing "
20252027
"instead of returning NULL for malloc failure.")
20262028
def test_constructor(self):
20272029
BufferedWriterTest.test_constructor(self)
@@ -2520,7 +2522,8 @@ def test_interleaved_readline_write(self):
25202522
class CBufferedRandomTest(BufferedRandomTest, SizeofTest):
25212523
tp = io.BufferedRandom
25222524

2523-
@skip_if_sanitizer(memory=True, address=True, reason= "sanitizer defaults to crashing "
2525+
@skip_if_sanitizer(memory=True, address=True, thread=True,
2526+
reason="sanitizer defaults to crashing "
25242527
"instead of returning NULL for malloc failure.")
25252528
def test_constructor(self):
25262529
BufferedRandomTest.test_constructor(self)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add support for thread sanitizer (TSAN)

configure

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

configure.ac

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3067,6 +3067,24 @@ AC_MSG_RESULT([no])
30673067
with_ubsan="no"
30683068
])
30693069

3070+
AC_MSG_CHECKING([for --with-thread-sanitizer])
3071+
AC_ARG_WITH(
3072+
[thread_sanitizer],
3073+
[AS_HELP_STRING(
3074+
[--with-thread-sanitizer],
3075+
[enable ThreadSanitizer data race detector, 'tsan' (default is no)]
3076+
)],
3077+
[
3078+
AC_MSG_RESULT([$withval])
3079+
BASECFLAGS="-fsanitize=thread $BASECFLAGS"
3080+
LDFLAGS="-fsanitize=thread $LDFLAGS"
3081+
with_tsan="yes"
3082+
],
3083+
[
3084+
AC_MSG_RESULT([no])
3085+
with_tsan="no"
3086+
])
3087+
30703088
# Set info about shared libraries.
30713089
AC_SUBST([SHLIB_SUFFIX])
30723090
AC_SUBST([LDSHARED])

0 commit comments

Comments
 (0)