esheldon / fitsio

A python package for FITS input/output wrapping cfitsio
GNU General Public License v2.0
134 stars 58 forks source link

1.1.9 segfaults in test_table_read_write() on i586 #370

Closed olebole closed 1 year ago

olebole commented 1 year ago

I am currently doing an upgrade of the python-fitsio Debian package to the latest version.

On a (32-bit) i386, the test_table.py::test_table_read_write test creates a core dump caused by a segmentation fault. With gdb, I found that this happens in https://github.com/esheldon/fitsio/blob/54cc73d4457d827c0efe0aca0ba7ff3d91ea3654/fitsio/fitsio_pywrap.c#L3555-L3558

because sortind is set to NULL. sortind was an argument for this function read_binary_rec_columns(), it was called here: https://github.com/esheldon/fitsio/blob/54cc73d4457d827c0efe0aca0ba7ff3d91ea3654/fitsio/fitsio_pywrap.c#L3643-L3653

Here, sortindObj seems OK (it points to {ob_refcnt = 3, ob_type = 0xf70d3040 <PyArray_Type>}, and nsortind is 141220876 after the get_int64_from_array(sortindObj, &nsortind) call, but the function returns a NULL.

More of the stacktrace:

#0  __kernel_vsyscall () at /build/linux-2WvuD6/linux-6.3.7/arch/x86/entry/vdso/vdso32/system_call.S:72
#1  0xf7c8a1d7 in __pthread_kill_implementation (threadid=threadid@entry=4159104768, signo=signo@entry=11, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:43
#2  0xf7c8a24b in __pthread_kill_internal (signo=11, threadid=4159104768) at ./nptl/pthread_kill.c:78
#3  0xf7c390d1 in __GI_raise (sig=11) at ../sysdeps/posix/raise.c:26
#4  <signal handler called>
#5  0xf5ecd64a in read_binary_rec_columns (status=0xffd78cc0, array=<optimized out>, sortind=0x0, rows=0xa01dd60, nrows=<optimized out>,  colnums=0xa4b1710, ncols=3, fits=<optimized out>) at fitsio/fitsio_pywrap.c:3558
#6  PyFITSObject_read_columns_as_rec (self=0xf63a4f60, args=0xf4985668) at fitsio/fitsio_pywrap.c:3649
#7  0x08163437 in method_vectorcall_VARARGS (func=0xf5e71730, args=0xf7fbdd20, nargsf=2147483654, kwnames=0x0) at ../Objects/descrobject.c:330
#8  0x08178bb1 in _PyObject_VectorcallTstate (kwnames=0x0, nargsf=2147483654, args=0xf7fbdd20, callable=0xf5e71730, tstate=0x86adc0c <_PyRuntime+84940>) at ../Include/internal/pycore_call.h:92
#9  PyObject_Vectorcall (callable=0xf5e71730, args=0xf7fbdd20, nargsf=2147483654, kwnames=0x0) at ../Objects/call.c:299
#10 0x0816b0ed in _PyEval_EvalFrameDefault (tstate=<optimized out>, frame=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:4774
#11 0x08193cc7 in _PyEval_EvalFrame (throwflag=0, frame=0xf7fbdbb0, tstate=0x86adc0c <_PyRuntime+84940>) at ../Include/internal/pycore_ceval.h:73
#12 _PyEval_Vector (kwnames=<optimized out>, argcount=<optimized out>, args=<optimized out>, locals=0x0, func=0xf4b2c708,   tstate=0x86adc0c <_PyRuntime+84940>) at ../Python/ceval.c:6439
#13 _PyFunction_Vectorcall (func=<optimized out>, stack=<optimized out>, nargsf=<optimized out>, kwnames=<optimized out>) at ../Objects/call.c:393
#14 0x081a1395 in _PyVectorcall_Call (kwargs=0xf497acd0, tuple=0x86a09a0 <_PyRuntime+31072>, callable=0xf4b2c708, func=0x8193b60 <_PyFunction_Vectorcall>, tstate=0x86adc0c <_PyRuntime+84940>) at ../Objects/call.c:245
#15 _PyObject_Call (kwargs=0xf497acd0, args=0x86a09a0 <_PyRuntime+31072>, callable=0xf4b2c708, tstate=0x86adc0c <_PyRuntime+84940>) at ../Objects/call.c:328
#16 PyObject_Call (callable=0xf4b2c708, args=0x86a09a0 <_PyRuntime+31072>, kwargs=0xf497acd0) at ../Objects/call.c:355
#17 0x0816f0a6 in do_call_core (use_tracing=<optimized out>, kwdict=0xf497acd0, callargs=0x86a09a0 <_PyRuntime+31072>, func=0xf4b2c708, tstate=<optimized out>) at ../Python/ceval.c:7357
#18 _PyEval_EvalFrameDefault (tstate=<optimized out>, frame=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:5381
#19 0x08193cc7 in _PyEval_EvalFrame (throwflag=0, frame=0xf7fbdb50, tstate=0x86adc0c <_PyRuntime+84940>) at ../Include/internal/pycore_ceval.h:73
#20 _PyEval_Vector (kwnames=<optimized out>, argcount=<optimized out>, args=<optimized out>, locals=0x0, func=0xf75864d8,tstate=0x86adc0c <_PyRuntime+84940>) at ../Python/ceval.c:6439
[…]

The full build log is here.

esheldon commented 1 year ago

Thanks for the report. I think I see the problem. I'll make a PR.

esheldon commented 1 year ago

I'm not sure how to test 32 bit in github actions

olebole commented 1 year ago

Just for this case, I can check for you. Other than that, here is what I do for IRAF: github/workflows/citest.yml#L38-L41

            sudo dpkg --add-architecture i386
            sudo apt-get update -y
            sudo apt-get install -y gcc-multilib libcurl4-openssl-dev:i386 libexpat1-dev:i386 libreadline-dev:i386 zlib1g-dev:i386

You can install any package with the :i386 suffix, even Python. Not sure how far it works.