Skip to content

BUG: numpy.seterr() segfaults on a self-referencing object array #32609

Description

@BHUVANSH855

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions