Describe the issue:
If you pass a numpy object array that contains itself as the all argument to numpy.seterr(), it segfaults instead of raising an error.
all is supposed to be one of 'ignore', 'warn', 'raise', 'call', 'print', 'log' (or None), so any other input should just raise TypeError/ValueError. Tested this on numpy 2.5.3 from pip and also 2.6.0.dev0 built from git main, same result on both, so it's not something specific to a dev build.
Repro:
import numpy as np
obj_array = np.empty(2, dtype=object)
obj_array[0] = obj_array
obj_array[1] = [obj_array, obj_array]
np.seterr(obj_array)
Crash:
Fatal Python error: Segmentation fault
Current thread 0x00007a5c6ba36740 (most recent call first):
File "/home/bhuvansh/numpy/numpy/_core/_ufunc_config.py", line 105 in seterr
File "repro_seterr_segfault.py", line 13 in <module>
Extension modules: numpy._core._multiarray_umath, numpy.linalg._umath_linalg
Segmentation fault (core dumped)
I ran it under gdb to figure out what's actually happening:
gdb -q -batch -ex "run" -ex "bt 30" --args python repro_seterr_segfault.py
Turns out it's a stack overflow, 19309 frames deep, stuck in this loop:
array_richcompare -> PyArray_GenericBinaryFunction -> PyObject_Vectorcall.warm
-> ufunc_generic_fastcall -> call_cached_loop -> OBJECT_equal -> PyObject_RichCompare
-> back to array_richcompare
So seterr calls into _make_extobj (compiled, under numpy/_core/src/umath/) which checks all against the allowed strings using ==. For an object array that comparison goes elementwise through array_richcompare/OBJECT_equal, and since the array contains itself, it just keeps comparing the array to itself forever. It's C-level recursion so Python's own recursion limit never kicks in, it just eats the whole stack until the OS kills it.
This is basically the same class of bug as #8306 / #9077, where a self-referencing array would stack-overflow bool(array). That got fixed with a Py_EnterRecursiveCall guard in _array_nonzero (number.c), but that only covers the truthiness path, not == comparisons like this one goes through. Might be other places with the same issue.
Top of the actual backtrace (it's 19309 lines total, this is the repeating chunk):
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff6b8c8cd in PyArray_NewFromDescr_int () from .../_multiarray_umath.cpython-313-x86_64-linux-gnu.so
#0 0x00007ffff6b8c8cd in PyArray_NewFromDescr_int ()
#1 0x00007ffff6b91dd2 in PyArray_FromAny_int ()
#2 0x00007ffff6b922a1 in PyArray_FromAny ()
#3 0x00007ffff6d079d9 in ufunc_generic_fastcall ()
#4 0x0000000001ad5341 in PyObject_Vectorcall.warm ()
#5 0x00007ffff6c0a366 in PyArray_GenericBinaryFunction ()
#6 0x00007ffff6b66be9 in array_richcompare ()
#7 0x000000000183039c in PyObject_RichCompare ()
#8 0x00007ffff6b0cfcf in OBJECT_equal ()
#9 0x00007ffff6cfade2 in call_cached_loop ()
#10 0x00007ffff6d09c44 in ufunc_generic_fastcall ()
... repeats ~2760 more times
Python and NumPy Versions:
3.13.15
2.5.3
Runtime Environment:
[{'numpy_version': '2.6.0.dev0+git20260913.cb4db63',
'python': '3.13.15 (main, Aug 14 2026, 15:34:59) [Clang 22.1.3 ]',
'uname': uname_result(system='Linux', node='WOLF', release='6.6.87.2-microsoft-standard-WSL2', version='#1 SMP PREEMPT_DYNAMIC Thu Jun 5 18:30:46 UTC 2025', machine='x86_64')},
{'simd_extensions': {'baseline': ['X86_V2'],
'found': ['X86_V3'],
'not_found': ['X86_V4', 'AVX512_ICL', 'AVX512_SPR']}},
{'ignore_floating_point_errors_in_matmul': False}]
How does this issue affect you or how did you find it:
Found this fuzzing with fusil (https://github.com/devdanzin/fusil) using the fusil-python-threaded harness plus fusil_numpy_plugin (https://github.com/devdanzin/fusil_numpy_plugin), which throws weird stuff like self-referencing arrays at whatever module you point it at. Not something you'd hit by accident, but anything that ends up calling seterr(all=...) with data it doesn't fully control could crash on this.
Describe the issue:
If you pass a numpy object array that contains itself as the
allargument tonumpy.seterr(), it segfaults instead of raising an error.allis supposed to be one of'ignore','warn','raise','call','print','log'(or None), so any other input should just raise TypeError/ValueError. Tested this on numpy 2.5.3 from pip and also 2.6.0.dev0 built from git main, same result on both, so it's not something specific to a dev build.Repro:
Crash:
I ran it under gdb to figure out what's actually happening:
Turns out it's a stack overflow, 19309 frames deep, stuck in this loop:
So
seterrcalls into_make_extobj(compiled, undernumpy/_core/src/umath/) which checksallagainst the allowed strings using==. For an object array that comparison goes elementwise througharray_richcompare/OBJECT_equal, and since the array contains itself, it just keeps comparing the array to itself forever. It's C-level recursion so Python's own recursion limit never kicks in, it just eats the whole stack until the OS kills it.This is basically the same class of bug as #8306 / #9077, where a self-referencing array would stack-overflow
bool(array). That got fixed with aPy_EnterRecursiveCallguard in_array_nonzero(number.c), but that only covers the truthiness path, not==comparisons like this one goes through. Might be other places with the same issue.Top of the actual backtrace (it's 19309 lines total, this is the repeating chunk):
Python and NumPy Versions:
3.13.15
2.5.3
Runtime Environment:
How does this issue affect you or how did you find it:
Found this fuzzing with fusil (https://github.com/devdanzin/fusil) using the fusil-python-threaded harness plus fusil_numpy_plugin (https://github.com/devdanzin/fusil_numpy_plugin), which throws weird stuff like self-referencing arrays at whatever module you point it at. Not something you'd hit by accident, but anything that ends up calling
seterr(all=...)with data it doesn't fully control could crash on this.