Skip to content

Commit 20d23e2

Browse files
committed
Move segfault test to subprocess
1 parent 4bc7a11 commit 20d23e2

File tree

1 file changed

+26
-5
lines changed

1 file changed

+26
-5
lines changed

tests/test_invalid_holder_access.py

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
import gc
4+
import multiprocessing
45
import weakref
56

67
import pytest
@@ -12,6 +13,12 @@
1213
XFAIL_REASON = "Known issues: https://github.com/pybind/pybind11/pull/5654"
1314

1415

16+
try:
17+
spawn_context = multiprocessing.get_context("spawn")
18+
except ValueError:
19+
spawn_context = None
20+
21+
1522
@pytest.mark.skipif(
1623
pybind11_tests.cpp_std_num < 14,
1724
reason="std::{unique_ptr,make_unique} not available in C++11",
@@ -34,16 +41,13 @@ def test_no_init():
3441
vec.__init__()
3542

3643

37-
# The test might succeed on some platforms with some compilers, but
38-
# it is not guaranteed to work everywhere. It is marked as xfail.
39-
@pytest.mark.xfail(reason=XFAIL_REASON, raises=SystemError, strict=False)
40-
def test_manual_new():
44+
def manual_new_target():
4145
# Repeatedly trigger allocation without initialization (raw malloc'ed) to
4246
# detect uninitialized memory bugs.
4347
for _ in range(32):
4448
# The holder is a pointer variable while the C++ ctor is not called.
4549
vec = m.VectorOwns4PythonObjects.__new__(m.VectorOwns4PythonObjects)
46-
if vec.is_empty():
50+
if vec.is_empty(): # <= this line could cause a segfault
4751
# The C++ compiler initializes container correctly.
4852
assert vec.size() == 0
4953
else:
@@ -56,6 +60,23 @@ def test_manual_new():
5660
vec.append(4)
5761

5862

63+
# This test might succeed on some platforms with some compilers, but it is not
64+
# guaranteed to work everywhere. It is marked as non-strict xfail.
65+
@pytest.mark.xfail(reason=XFAIL_REASON, raises=SystemError, strict=False)
66+
@pytest.mark.skipif(spawn_context is None, reason="spawn context not available")
67+
def test_manual_new():
68+
process = spawn_context.Process(
69+
target=manual_new_target,
70+
name="manual_new_target",
71+
)
72+
process.start()
73+
process.join()
74+
if process.exitcode != 0:
75+
raise SystemError(
76+
"Segmentation Fault: The C++ compiler initializes container incorrectly."
77+
)
78+
79+
5980
@pytest.mark.skipif("env.PYPY or env.GRAALPY", reason="Cannot reliably trigger GC")
6081
@pytest.mark.skipif(
6182
pybind11_tests.cpp_std_num < 14,

0 commit comments

Comments
 (0)