Skip to content

BUG: on OpenBSD/i386 numpy segfaults while running tests (1.20rc1 to 1.22.0 crash / 1.19.5 is the last known working version) #20799

Open

Description

@didickman

Describe the issue:

Starting with numpy 1.20rc1 and also happening in every release through 1.22.0, the tests cause a segfault on OpenBSD/i386. I've tested this with both python 3.8 and python 3.9. numpy 1.19.5 appears to allow the test suite to run.

The backtrace from gdb shows "solve_diophantine" may be where it's crashing?

In case helpful to know, on OpenBSD, netlib Blas is used.

Reproduce the code example:

$ egdb python3
GNU gdb (GDB) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "i386-unknown-openbsd7.0".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from python3...
(No debugging symbols found in python3)
(gdb) run
Starting program: /usr/local/bin/python3
Python 3.8.12 (default, Jan 11 2022, 03:22:43)
[Clang 13.0.0 ] on openbsd7
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy
>>> numpy.test(verbose=2)
NumPy version 1.20.0rc1
NumPy relaxed strides checking option: True
NumPy CPU features: SSE SSE2 SSE3* SSSE3* SSE41* POPCNT* SSE42* AVX? F16C* FMA3? AVX2? AVX512F? AVX512CD? AVX512_KNL? AVX512_KNM? AVX512_SKX? AVX512_CLX? AVX512_CNL? AVX512_ICL?
===================================================================================================== test session starts ======================================================================================================
platform openbsd7 -- Python 3.8.12, pytest-6.2.5, py-1.8.2, pluggy-1.0.0
rootdir: /home/didickman/numpy, configfile: pytest.ini
plugins: hypothesis-6.35.0
collecting 11938 items / 4 errors / 11934 selected
Program received signal SIGSEGV, Segmentation fault.
0x0aba548b in solve_diophantine () from /usr/local/lib/python3.8/site-packages/numpy/core/_multiarray_umath.cpython-38.so
(gdb) bt
#0  0x0aba548b in solve_diophantine () from /usr/local/lib/python3.8/site-packages/numpy/core/_multiarray_umath.cpython-38.so
#1  0x0aba681b in solve_may_share_memory () from /usr/local/lib/python3.8/site-packages/numpy/core/_multiarray_umath.cpython-38.so
#2  0x0ab7c8bf in PyUFunc_GenericFunction_int () from /usr/local/lib/python3.8/site-packages/numpy/core/_multiarray_umath.cpython-38.so
#3  0x0ab7d001 in ufunc_generic_call () from /usr/local/lib/python3.8/site-packages/numpy/core/_multiarray_umath.cpython-38.so
#4  0x08c40e6f in _PyObject_MakeTpCall () from /usr/local/lib/libpython3.8.so.0.0
#5  0x08c42e04 in object_vacall () from /usr/local/lib/libpython3.8.so.0.0
#6  0x08c42f71 in PyObject_CallFunctionObjArgs () from /usr/local/lib/libpython3.8.so.0.0
#7  0x0aa02e31 in PyArray_GenericInplaceBinaryFunction () from /usr/local/lib/python3.8/site-packages/numpy/core/_multiarray_umath.cpython-38.so
#8  0x08c2a072 in PyNumber_InPlaceMultiply () from /usr/local/lib/libpython3.8.so.0.0
#9  0x08cffd87 in _PyEval_EvalFrameDefault () from /usr/local/lib/libpython3.8.so.0.0
#10 0x08d0875e in _PyEval_EvalCodeWithName () from /usr/local/lib/libpython3.8.so.0.0
#11 0x08c4193a in _PyFunction_Vectorcall () from /usr/local/lib/libpython3.8.so.0.0
#12 0x08c411be in PyVectorcall_Call () from /usr/local/lib/libpython3.8.so.0.0
#13 0x08c412ac in PyObject_Call () from /usr/local/lib/libpython3.8.so.0.0
#14 0x0a93935c in array_implement_array_function () from /usr/local/lib/python3.8/site-packages/numpy/core/_multiarray_umath.cpython-38.so
#15 0x08c41481 in cfunction_call_varargs () from /usr/local/lib/libpython3.8.so.0.0
#16 0x08c41f8a in PyCFunction_Call () from /usr/local/lib/libpython3.8.so.0.0
#17 0x08c40e6f in _PyObject_MakeTpCall () from /usr/local/lib/libpython3.8.so.0.0
#18 0x08d07b86 in call_function () from /usr/local/lib/libpython3.8.so.0.0
#19 0x08d04965 in _PyEval_EvalFrameDefault () from /usr/local/lib/libpython3.8.so.0.0
#20 0x08d0875e in _PyEval_EvalCodeWithName () from /usr/local/lib/libpython3.8.so.0.0
#21 0x08c4193a in _PyFunction_Vectorcall () from /usr/local/lib/libpython3.8.so.0.0
#22 0x08d07b44 in call_function () from /usr/local/lib/libpython3.8.so.0.0
<snipped by @seberg>

Error message:

Program received signal SIGSEGV, Segmentation fault.

NumPy/Python version information:

1.20.0rc1 3.8.12 (default, Jan 11 2022, 03:22:43)
[Clang 13.0.0 ]

Activity

  1. seberg commented on Jan 12, 2022

    @seberg
    Member

    @didickman just to get everyone on the same page, can you say how NumPy was installed, and if it was a wheel, maybe even see if compiling it locally helps?
    It seems like a failure in solve_diophantine, although the most interesting thing that does is passing around some 128bit integers (which need to be packed into a struct). It might be that the function doing that must be inlined for ABI reasons, but fail to be inlined or so. (Just a guess, I know such issues are possible, but I am not sure if it makes at all sense here.)

  2. didickman commented on Jan 12, 2022

    @didickman
    Author

    For the OpenBSD port we download the source from pypi and compile it ourselves. For example for 1.20rc1 I downloaded https://pypi.io/packages/source/n/numpy/numpy-1.20.0rc1.zip. If there's any test code I could try to run here that might let me debug the issue I could try that. I just don't know my way around the test suite well enough to know what to try look at/run.

  3. seberg commented on Jan 12, 2022

    @seberg
    Member

    No, running the test suite is completely fine and good enough. My random idea was basically replacing all static NPY_INLINE with NPY_FINLINE in numpy/core/src/common/npy_extint128.h to see if that might help.

  4. charris commented on Jan 12, 2022

    @charris
    Member

    Out of curiosity, what compiler are you using. IIRC, the memory overlap detection uses 128 bit integers in parts, which might be a problem.

  5. charris commented on Jan 12, 2022

    @charris
    Member

    Do things work on x86_64?

  6. didickman commented on Jan 12, 2022

    @didickman
    Author

    The base compiler on OpenBSD/i386 is clang 13:

    $ cc --version
    OpenBSD clang version 13.0.0
    Target: i386-unknown-openbsd7.0
    Thread model: posix
    InstalledDir: /usr/bin

    Will have to come back on how things look on x86_64. Thanks!

  7. seberg commented on Jan 12, 2022

    @seberg
    Member

    If you end up compiling again, maybe try including debug symbols and run gdb again, just to make sure we got the right idea? Not sure it will give us anything, but can't hurt?

    However, I agree with Chuck that the only likely problem is the issue of passing a 128bit struct by value. Force-inlining the functions in the header I pointed out _should solve that issue, so it would be a good first try I think.

  8. didickman commented on Jan 17, 2022

    @didickman
    Author

    unfortunately no change in behaviour when replacing static NPY_INLINE with NPY_FINLINE in numpy/core/src/common/npy_extint128.h

  9. seberg commented on Jan 17, 2022

    @seberg
    Member

    @didickman it seems hard to make progress on the issue. Any chance you can get the debug symbols in, so that we at least know where exactly it crashes (also we can see if the NPY_FINLINE did what I hoped it would do)? If you are stuck on getting that, worst case, clone the current git (recursive for the submodules), and then try:

    gdb --args python3 runtests.py -g
    

    (maybe compile with gdb, so could compile once first without to not get that. But should just work, hopefully.)

    For example Debian ships i386, so I somewhat expect it is something to do with clang 13 + i386, which makes it rather specific...

  10. didickman commented on Jan 17, 2022

    @didickman
    Author

    ok, i think i was able to get the debug symbols going (apologies, took me a bit to work it out with our ports infrastructure).

    See some details below. I hope this is helpful to pinpoint what's going on.

    >>> numpy.test(verbose=2)
    NumPy version 1.20.0rc1
    NumPy relaxed strides checking option: True
    NumPy CPU features: SSE SSE2 SSE3* SSSE3* SSE41* POPCNT* SSE42* AVX? F16C* FMA3? AVX2? AVX512F? AVX512CD? AVX512_KNL? AVX512_KNM? AVX512_SKX? AVX512_CLX? AVX512_CNL? AVX512_ICL?
    ===================================================================================================== test session starts ======================================================================================================
    platform openbsd7 -- Python 3.9.9, pytest-6.2.5, py-1.8.2, pluggy-1.0.0
    rootdir: /usr/ports/math/py-numpy
    plugins: cov-2.8.1, nbval-0.9.5, hypothesis-6.35.0
    collecting 12479 items
    Program received signal SIGSEGV, Segmentation fault.
    0x0e016cb2 in diophantine_precompute (Epsilon=0x77d16bd0, Gamma=0x77d20ff0, Ep=0x48ebab80, E=0xcf7ede40, n=2) at numpy/core/src/common/mem_overlap.c:551
    551             else if (diophantine_precompute(n, E, Ep, Gamma, Epsilon)) {
    (gdb) bt
    #0  0x0e016cb2 in diophantine_precompute (Epsilon=0x77d16bd0, Gamma=0x77d20ff0, Ep=0x48ebab80, E=0xcf7ede40, n=2) at numpy/core/src/common/mem_overlap.c:551
    #1  solve_diophantine (x=0xcf7edc2c, require_ub_nontrivial=0, max_work=1, b=799, E=0xcf7ede40, n=<optimized out>) at numpy/core/src/common/mem_overlap.c:551
    #2  solve_diophantine (n=2, E=0xcf7ede40, b=799, max_work=1, require_ub_nontrivial=0, x=0xcf7edc2c) at numpy/core/src/common/mem_overlap.c:481
    #3  0x0e01821b in solve_may_share_memory (a=0x578292c0, b=0x578292c0, max_work=1) at numpy/core/src/common/mem_overlap.c:835
    #4  0x0dfed72f in PyArray_EQUIVALENTLY_ITERABLE_OVERLAP_OK (arr1_read=1, arr2_read=0, arr2=<optimized out>, arr1=<optimized out>) at numpy/core/src/common/lowlevel_strided_loops.h:700
    #5  execute_legacy_ufunc_loop (op_flags=0xcf7ee330, full_args=..., arr_prep=0xcf7ee430, buffersize=8192, order=<optimized out>, dtypes=0xcf7ee3b0, op=0xcf7ee620, trivial_loop_ok=<optimized out>, ufunc=0x62c43578)
        at numpy/core/src/umath/ufunc_object.c:1677
    #6  PyUFunc_GenericFunction_int (ufunc=<optimized out>, ufunc@entry=0x62c43578, args=args@entry=(<numpy.ndarray at remote 0x578292c0>, <numpy.float64 at remote 0x6c5c2430>, <numpy.ndarray at remote 0x578292c0>),
        kwds=kwds@entry=0x0, op=0xcf7ee620) at numpy/core/src/umath/ufunc_object.c:3235
    #7  0x0dfede71 in ufunc_generic_call (ufunc=0x62c43578, args=(<numpy.ndarray at remote 0x578292c0>, <numpy.float64 at remote 0x6c5c2430>, <numpy.ndarray at remote 0x578292c0>), kwds=0x0)
        at numpy/core/src/umath/ufunc_object.c:4732
    #8  0x0e5695f1 in _PyObject_MakeTpCall () from /usr/local/lib/libpython3.9.so.0.0
    #9  0x0e56ae4c in object_vacall () from /usr/local/lib/libpython3.9.so.0.0
    #10 0x0e56afcf in PyObject_CallFunctionObjArgs () from /usr/local/lib/libpython3.9.so.0.0
    #11 0x0de73d71 in PyArray_GenericInplaceBinaryFunction (m1=<optimized out>, m2=<optimized out>, op=<optimized out>) at numpy/core/src/multiarray/number.c:306
    #12 0x0e551de2 in PyNumber_InPlaceMultiply () from /usr/local/lib/libpython3.9.so.0.0
    #13 0x0e633389 in _PyEval_EvalFrameDefault () from /usr/local/lib/libpython3.9.so.0.0
    #14 0x0e63a681 in _PyEval_EvalCode () from /usr/local/lib/libpython3.9.so.0.0
    #15 0x0e569dc0 in _PyFunction_Vectorcall () from /usr/local/lib/libpython3.9.so.0.0
    #16 0x0e569ad0 in PyVectorcall_Call () from /usr/local/lib/libpython3.9.so.0.0
    #17 0x0e569b67 in _PyObject_Call () from /usr/local/lib/libpython3.9.so.0.0
    #18 0x0e569c4e in PyObject_Call () from /usr/local/lib/libpython3.9.so.0.0
    #19 0x0ddaa24c in array_implement_array_function (__NPY_UNUSED_TAGGEDdummy=<module at remote 0x6439b2d0>, Python Exception <class 'gdb.error'> There is no member named dk_nentries.:
    positional_args=) at numpy/core/src/multiarray/arrayfunction_override.c:362
    #20 0x0e5aa87b in cfunction_call () from /usr/local/lib/libpython3.9.so.0.0
    #21 0x0e5695f1 in _PyObject_MakeTpCall () from /usr/local/lib/libpython3.9.so.0.0
    #22 0x0e639a47 in call_function () from /usr/local/lib/libpython3.9.so.0.0
    #23 0x0e63748e in _PyEval_EvalFrameDefault () from /usr/local/lib/libpython3.9.so.0.0
    #24 0x0e63a681 in _PyEval_EvalCode () from /usr/local/lib/libpython3.9.so.0.0
    #25 0x0e569dc0 in _PyFunction_Vectorcall () from /usr/local/lib/libpython3.9.so.0.0
    #26 0x0e6399b9 in call_function () from /usr/local/lib/libpython3.9.so.0.0
    #27 0x0e63741a in _PyEval_EvalFrameDefault () from /usr/local/lib/libpython3.9.so.0.0
    #28 0x0e63a681 in _PyEval_EvalCode () from /usr/local/lib/libpython3.9.so.0.0
    
    
  11. sthen commented on Aug 30, 2022

    @sthen

    I see the same segfault with numpy 1.23.2 on OpenBSD/i386, including with Python 3.10. (I'm trying to prepare the OpenBSD ports tree to move to Python 3.10 by default, and numpy is the biggest sticking point). Slightly longer backtrace here so I'll attach it rather than in-line (some of the _PyEval_EvalFrame lines are pretty wide). I'm no expert at debugging Python code but if you have anything you'd like me to try I'll see if I can help.

    numpy.bt.openbsd-i386.txt

    And here's the log from building numpy in case there's anything helpful there.

    py-numpy,python3.log

  12. sthen commented on Aug 30, 2022

    @sthen

    Similar segv/backtrace if I build with GCC instead of Clang.

  13. sthen commented on Aug 30, 2022

    @sthen

    Aha, after some bisecting it seems it was introduced in 8245b39 (the big "ENH: enable multi-platform SIMD compiler optimizations" diff). Moving back to 1.23.2 I've tested with "--cpu-dispatch min", which still segfaults, and "--disable-optimization" which is ok.

    btw, I noticed 'numpy/core/src/multiarray/common.h:181: warning: "_ALIGN" redefined' in build log. They're unrelated (occur on all OpenBSD archs, are nothing new, and still occur if I rename numpy's _ALIGN macro).

  14. 13 remaining items

  15. sthen commented on Jan 9, 2023

    @sthen
  16. charris commented on Aug 1, 2024

    @charris
    Member

    Pushing this off again. @didickman @sthen Any news of progress?

  17. didickman commented on Aug 2, 2024

    @didickman
    Author

    we’re now on version 1.25.2 and it was likely still a problem for this version since it looks like Stuart kept optimizations disabled for that update. Is there a newer version that’s expected to fix this? I have a local diff for 1.26.4 (although not 2.x yet). Do we need to get 2.x working on our side to test the fix? Separately, @sthen has the i386 ports machine. If needed I can set up a 32 bit box for testing on my end but it will take me a few weeks to pull the box from storage.

  18. charris commented on Aug 2, 2024

    @charris
    Member

    Is there a newer version that’s expected to fix this?

    Not that I know of, but sometimes things get fixed by accident :) Trying with a later version might get more attention, though.

  19. seberg commented on Aug 2, 2024

    @seberg
    Member

    Still as puzzling as always... Seems to be happening very early on? Maybe worth a shot to run it with valgrind (yes, that is infinitely slow)?
    Of all the errors, I really can't see how a segfault can come about here, unless the compiler is doing some incorrect optimizations!?

  20. removed this from the 2.2.0 release milestone on Aug 7, 2024
  21. sthen commented on Aug 28, 2024

    @sthen

    Same issue in 1.26.4

  22. mattip commented on Aug 29, 2024

    @mattip
    Member

    On this niche platform, I think it is an OK solution to add the --disable-optimization flag. It is unlikely we are going to get very far debugging this: we would need to set up exact emulation of this 32-bit processor and OpenBSD.

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

Metadata

Metadata

Assignees

Labels

00 - Bugcomponent: SIMDIssues in SIMD (fast instruction sets) code or machinery

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions