Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Python 3.2: Segmentation fault in numpy/testing/print_coercion_tables.py #2738

Closed
certik opened this Issue · 12 comments

3 participants

@certik
Owner
$ wget https://raw.github.com/numpy/numpy/master/numpy/testing/print_coercion_tables.py
$ 2to3 -w print_coercion_tables.py
$ python print_coercion_tables.py
[...]
O 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 
M 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 
m 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 

In these tables, ValueError is '!', OverflowError is '@', TypeError is '#'

scalar + scalar
+ ? b h i l q p B H I L Q P e f d g F D G S U V O M m 
Segmentation fault (core dumped)

The problem is here:

0x00007ffff6666343 in PyArray_FromScalar (scalar=0x15e79a0, outcode=0x0)
    at numpy/core/src/multiarray/scalarapi.c:307
307         if (typecode->f->setitem(scalar, PyArray_DATA(r), r) < 0) {
(gdb) p typecode->f
$1 = (PyArray_ArrFuncs *) 0xdbdbdbdbdbdbdbdb
(gdb) p typecode->f->setitem(scalar, PyArray_DATA(r), r)
Cannot access memory at address 0xdbdbdbdbdbdbdc8b

Full stacktrace:

#0  0x00007ffff6666343 in PyArray_FromScalar (scalar=0x15e79a0, outcode=0x0)
    at numpy/core/src/multiarray/scalarapi.c:307
        typecode = 0x1616260
        r = 0x1600ec0
        memptr = 0x7ffff69fd1a0 ""
        ret = 0x4
        __PRETTY_FUNCTION__ = "PyArray_FromScalar"
#1  0x00007ffff66c7762 in PyArray_FromAny (op=0x15e79a0, newtype=0x0, 
    min_depth=0, max_depth=0, flags=0, context=0x0)
    at numpy/core/src/multiarray/ctors.c:1617
        arr = 0x0
        ret = 0x1600f40
        dtype = 0x16161d8
        ndim = 0
        dims = {8866040, 8866040, 11051188, 8867072, 8866040, 8866040, 
          8867072, 8971872, 8867072, 22944648, 8587464, 22944656, 1, 
          140737488338048, 12884884544, 1, 140737488339264, 4491496, 0, 1, 
          22944664, 52, 4265172472917657865, 14974928, 15381816, 8866040, 
          8866040, 8866040, 8866040, 11157008, 1, 140737488338049}
#2  0x00007ffff5dc528a in get_ufunc_arguments (ufunc=0xd8c040, args=0x1614e70, 
    kwds=0x0, out_op=0x7fffffffc040, out_order=0x7fffffffbfec, 
    out_casting=0x7fffffffbff0, out_extobj=0x7fffffffbfa0, 
    out_typetup=0x7fffffffbfa8, out_subok=0x7fffffffbfdc, 
    out_wheremask=0x7fffffffbf98) at numpy/core/src/umath/ufunc_object.c:755
        i = 1
        nargs = 2
        nin = 2
        nout = 1
        obj = 0x15e79a0
        context = 0x0
        str_key_obj = 0x0
        ufunc_name = 0x7ffff5de80b2 "add"
        any_flexible = 0
        any_object = 0
#3  0x00007ffff5dc9b9d in PyUFunc_GenericFunction (ufunc=0xd8c040, 
    args=0x1614e70, kwds=0x0, op=0x7fffffffc040)
    at numpy/core/src/umath/ufunc_object.c:2110
        nin = 2
        nout = 1
        i = 3
        nop = 3
        ufunc_name = 0x7ffff5de80b2 "add"
        retval = -1
        subok = 1
        need_fancy = 0
        dtypes = {0x0, 0x0, 0x0, 0x17268c8, 0x8748f8, 0x8748f8, 
          0x7ffff7f573e8, 0x80, 0x0, 0x1600fa8, 0x1600fa7, 0xffffffff00585eb3, 
          0x7fffffffbe30, 0x41bca8, 0x60, 0x0, 0x2ffffbe40, 0x7ffff74b3720, 
          0x1, 0x5e3a7b, 0x0, 0x0, 0x5e4027, 0x0, 0x7fffffffbe70, 0x100000000, 
          0x3, 0x100853920, 0x1723d10, 0x7ffff67a4956, 0x0, 0x1}
        buffersize = 0
        errormask = 0
        errobj = 0x0
        first_error = 1
        wheremask = 0x0
        arr_prep = {0x0, 0x0, 0x0, 0x7ffff66c5906, 0x200, 0x7fffffffbf78, 
          0xd27640, 0x0, 0x7fffffffc1b0, 0x5c6d22, 0x7ffff6a02940, 
          0x7ffff69fd1e0, 0x2000000060, 0x3b7b6f00, 0x7fffffffbf30, 0x1f, 0x0, 
          0x5dd720, 0x7fffffffc318, 0x1, 0x5dd71e, 0x0, 0x1, 
          0x4f00000100000001, 0x7fffffffbfc0, 0x49f964, 0x7fffffffc090, 0x1, 
          0x7fffffffc010, 0x41bfe7, 0x7fffffffc0e0, 0x7fffffffc010}
        arr_prep_args = 0x0
        trivial_loop_ok = 0
        order = NPY_KEEPORDER
        casting = NPY_INTERNAL_UNSAFE_CASTING_BUT_WARN_UNLESS_SAME_KIND
        extobj = 0x0
        type_tup = 0x0
#4  0x00007ffff5dcfb89 in ufunc_generic_call (ufunc=0xd8c040, args=0x1614e70, 
    kwds=0x0) at numpy/core/src/umath/ufunc_object.c:3833
        i = 3
        ret = 0x2
        mps = {0x1600f40, 0x0, 0x0, 0x5, 0x7fffffffc080, 0x3b7b6f00, 0x0, 
          0x8a0a2ed03b7b6f00, 0x7fffffffc180, 0x4a330b, 0x858220, 0x5e3a76, 
          0x0, 0xbb8370, 0x3000000028, 0x7fffffffc190, 0x7fffffffc0d0, 
          0x1ffffc110, 0x49c0a2, 0x888610, 0x874d00, 0x1600f40, 
          0x7fffffffc1c8, 0x7fffffffc1d0, 0x500f7fa39c0, 0x888610, 
          0x7fffffffc160, 0x60, 0x0, 0x15e79e8, 0x15e79e7, 0xffffffff00000001}
        retobj = {0x7fffffffc180, 0x41bca8, 0x40, 0x6d00888610, 0x0, 0x60, 
          0x15e7990, 0x15e79e0, 0x7fffffffc1a0, 0x41bae9, 0x1ffffc1d8, 
          0x15e79a0, 0x7fffffffc1c0, 0x419fff, 0xbb8370, 0x15e79a0, 
          0x7fffffffc1f0, 0x7ffff66554e8, 0x0, 0x7ffff6a00780, 0x40, 
          0x15e79a0, 0x7fffffffc240, 0x551b37, 0x2000000060, 0x0, 0xbb8370, 
          0x7ffff6a00780, 0x1600f40, 0x7ffff7fbd880, 0x0, 0x15e79a0}
        wraparr = {0x7fffffffc2b0, 0x550f44, 0x7ffff6a00780, 0x1600f40, 
          0x7fffffffc280, 0x0, 0xbb8370, 0x7ffff6a00780, 0x7fffffffc2b0, 0x0, 
          0x0, 0x0, 0x0, 0x1600f40, 0x7fffffffc330, 0x7ffff6661bee, 0x1600f40, 
          0x0, 0xbb8370, 0x7ff, 0x7ffff7fb0f48, 0xbf1850, 0x7fffffffc330, 
          0xca7390, 0x7ffff6a00780, 0x1, 0x874d00, 0x2, 0x7fffffffc370, 
          0x4b8ed2, 0x7fffffffc3c0, 0x874d00}
        res = 0x88e660
        errval = 2
#5  0x0000000000537482 in PyObject_Call (func=0xd8c040, arg=0x1614e70, kw=0x0)
    at Objects/abstract.c:2149
        result = 0x7ffff69fd180
        call = 0x7ffff5dcfb18 <ufunc_generic_call>
#6  0x000000000048b09e in do_call (func=0xd8c040, pp_stack=0x7fffffffc4e0, 
    na=2, nk=0) at Python/ceval.c:4141
        callargs = 0x1614e70
        kwdict = 0x0
        result = 0x0
#7  0x000000000048a448 in call_function (pp_stack=0x7fffffffc4e0, oparg=2)
    at Python/ceval.c:3944
        na = 2
        nk = 0
        n = 2
        pfunc = 0x1723d00
        func = 0xd8c040
        x = 0xa23a58
        w = 0xa23a38
#8  0x00000000004848fb in PyEval_EvalFrameEx (f=0x1723b00, throwflag=0)
    at Python/ceval.c:2692
        sp = 0x1723d08
        stack_pointer = 0x1723d18
        next_instr = 0xc61f5f "}\f"
        opcode = 131
        oparg = 2
        why = WHY_NOT
        err = 0
        x = 0x15e79a0
        v = 0xa23a38
        w = 0x7ffff7fb0f48
        u = 0xa9dfb8
        t = 0x2
        fastlocals = 0x1723c88
        freevars = 0x1723cf0
        retval = 0x0
        tstate = 0x88e660
        co = 0xbfb0f8
        instr_ub = -1
        instr_lb = 0
        instr_prev = -1
        first_instr = 0xc61e40 "t"
        names = 0xb73220
        consts = 0x9c5740
        filename = 0x1612c40 "print_coercion_tables.py"
        opcode_targets = {0x485b9e, 0x4795b9, 0x47968f, 0x479707, 0x479798, 
          0x479888, 0x485b9e, 0x485b9e, 0x485b9e, 0x47914e, 0x4799c2, 
          0x479b45, 0x479cc8, 0x485b9e, 0x485b9e, 0x47a010, 0x485b9e, 
          0x485b9e, 0x485b9e, 0x47a193, 0x47a396, 0x485b9e, 0x47a990, 
          0x47abae, 0x47ade6, 0x47afe4, 0x47a792, 0x47a594, 0x47c56b, 
          0x47c36d, 0x485b9e <repeats 24 times>, 0x48188e, 0x47c967, 0x47cb9f, 
          0x47c16f, 0x485b9e, 0x47c769, 0x47d793, 0x47da47, 0x47b1e2, 
          0x47b3e0, 0x47b5de, 0x47b7dc, 0x47b9da, 0x47bf6c, 0x483a03, 
          0x47df40, 0x47dc79, 0x47edf7, 0x485b9e, 0x485b9e, 0x485b9e, 
          0x47cd9d, 0x47cf9b, 0x47d199, 0x47d397, 0x47d595, 0x483f50, 
          0x4844cf, 0x485b9e, 0x47e0e1, 0x482686, 0x485b9e, 0x47e129, 
          0x47e644, 0x47e841, 0x47e17c, 0x47eee6, 0x47f12d, 0x47f1ea, 
          0x483bee, 0x47f631, 0x47f730, 0x47f9c8, 0x47faa0, 0x47fc80, 
          0x485b9e, 0x479329, 0x47fd07, 0x480ff7, 0x4811f2, 0x4813f2, 
          0x4816d3, 0x481dd0, 0x481f8e, 0x4821aa, 0x48287c, 0x482a53, 
          0x48317b, 0x483527, 0x4838d2, 0x482adb, 0x482e2b, 0x48002d, 
          0x485b9e, 0x485b9e, 0x483f69, 0x483fce, 0x483ffa, 0x484026, 
          0x485b9e, 0x4791ad, 0x479466, 0x4806ba, 0x485b9e, 0x485b9e, 
          0x485b9e, 0x47de76, 0x4848b9, 0x484fec, 0x485860, 0x484fc0, 
          0x480a67, 0x480c54, 0x480e34, 0x4808e6, 0x485b9e, 0x484a84, 
          0x484ab0, 0x484adc, 0x484196, 0x485b36, 0x47bbd8, 0x47bda2, 
          0x481b1b, 0x485b9e <repeats 108 times>}
        __PRETTY_FUNCTION__ = "PyEval_EvalFrameEx"
#9  0x0000000000488357 in PyEval_EvalCodeEx (_co=0xbfb0f8, globals=0x91fa40, 
    locals=0x0, args=0xa6ea50, argcount=4, kws=0xa6ea70, kwcount=0, 
    defs=0xbb82b8, defcount=1, kwdefs=0x0, closure=0x0) at Python/ceval.c:3350
        co = 0xbfb0f8
        f = 0x1723b00
        retval = 0x0
        fastlocals = 0x1723c88
        freevars = 0x1723cf0
        tstate = 0x88e660
        x = 0x853920
        u = 0xbb83c0
        total_args = 5
        __PRETTY_FUNCTION__ = "PyEval_EvalCodeEx"
#10 0x000000000048a861 in fast_function (func=0x160cec0, 
    pp_stack=0x7fffffffd1e0, n=4, na=4, nk=0) at Python/ceval.c:4019
        co = 0xbfb0f8
        globals = 0x91fa40
        argdefs = 0xbb8290
        kwdefs = 0x0
        d = 0xbb82b8
        nd = 1
        __PRETTY_FUNCTION__ = "fast_function"
#11 0x000000000048a42c in call_function (pp_stack=0x7fffffffd1e0, oparg=4)
    at Python/ceval.c:3942
        na = 4
        nk = 0
        n = 4
        pfunc = 0xa6ea48
        func = 0x160cec0
        x = 0xe33588
        w = 0xdfece0
#12 0x00000000004848fb in PyEval_EvalFrameEx (f=0xa6e8c0, throwflag=0)
    at Python/ceval.c:2692
        sp = 0xa6ea70
        stack_pointer = 0xa6ea70
        next_instr = 0xa8a560 "\001e\b"
        opcode = 131
        oparg = 4
        why = WHY_NOT
        err = 0
        x = 0x853920
        v = 0xdfece0
        w = 0xbbe318
        u = 0x888610
        t = 0x4
        fastlocals = 0xa6ea48
        freevars = 0xa6ea48
        retval = 0x0
        tstate = 0x88e660
        co = 0xbfb1b0
        instr_ub = -1
        instr_lb = 0
        instr_prev = -1
        first_instr = 0xa8a4d0 "d"
        names = 0xa38de0
        consts = 0xa85210
        filename = 0xbb8150 "print_coercion_tables.py"
        opcode_targets = {0x485b9e, 0x4795b9, 0x47968f, 0x479707, 0x479798, 
          0x479888, 0x485b9e, 0x485b9e, 0x485b9e, 0x47914e, 0x4799c2, 
          0x479b45, 0x479cc8, 0x485b9e, 0x485b9e, 0x47a010, 0x485b9e, 
          0x485b9e, 0x485b9e, 0x47a193, 0x47a396, 0x485b9e, 0x47a990, 
          0x47abae, 0x47ade6, 0x47afe4, 0x47a792, 0x47a594, 0x47c56b, 
          0x47c36d, 0x485b9e <repeats 24 times>, 0x48188e, 0x47c967, 0x47cb9f, 
          0x47c16f, 0x485b9e, 0x47c769, 0x47d793, 0x47da47, 0x47b1e2, 
          0x47b3e0, 0x47b5de, 0x47b7dc, 0x47b9da, 0x47bf6c, 0x483a03, 
          0x47df40, 0x47dc79, 0x47edf7, 0x485b9e, 0x485b9e, 0x485b9e, 
          0x47cd9d, 0x47cf9b, 0x47d199, 0x47d397, 0x47d595, 0x483f50, 
          0x4844cf, 0x485b9e, 0x47e0e1, 0x482686, 0x485b9e, 0x47e129, 
          0x47e644, 0x47e841, 0x47e17c, 0x47eee6, 0x47f12d, 0x47f1ea, 
          0x483bee, 0x47f631, 0x47f730, 0x47f9c8, 0x47faa0, 0x47fc80, 
          0x485b9e, 0x479329, 0x47fd07, 0x480ff7, 0x4811f2, 0x4813f2, 
          0x4816d3, 0x481dd0, 0x481f8e, 0x4821aa, 0x48287c, 0x482a53, 
          0x48317b, 0x483527, 0x4838d2, 0x482adb, 0x482e2b, 0x48002d, 
          0x485b9e, 0x485b9e, 0x483f69, 0x483fce, 0x483ffa, 0x484026, 
          0x485b9e, 0x4791ad, 0x479466, 0x4806ba, 0x485b9e, 0x485b9e, 
          0x485b9e, 0x47de76, 0x4848b9, 0x484fec, 0x485860, 0x484fc0, 
          0x480a67, 0x480c54, 0x480e34, 0x4808e6, 0x485b9e, 0x484a84, 
          0x484ab0, 0x484adc, 0x484196, 0x485b36, 0x47bbd8, 0x47bda2, 
          0x481b1b, 0x485b9e <repeats 108 times>}
        __PRETTY_FUNCTION__ = "PyEval_EvalFrameEx"
#13 0x0000000000488357 in PyEval_EvalCodeEx (_co=0xbfb1b0, globals=0x91fa40, 
    locals=0x91fa40, args=0x0, argcount=0, kws=0x0, kwcount=0, defs=0x0, 
    defcount=0, kwdefs=0x0, closure=0x0) at Python/ceval.c:3350
        co = 0xbfb1b0
        f = 0xa6e8c0
        retval = 0x0
        fastlocals = 0xa6ea48
        freevars = 0xa6ea48
        tstate = 0x88e660
        x = 0x900e40
        u = 0x900000
        total_args = 0
        __PRETTY_FUNCTION__ = "PyEval_EvalCodeEx"
#14 0x00000000004782ef in PyEval_EvalCode (co=0xbfb1b0, globals=0x91fa40, 
    locals=0x91fa40) at Python/ceval.c:767
No locals.
#15 0x00000000004be5f6 in run_mod (mod=0xc3eeb8, 
    filename=0xaea7e0 "print_coercion_tables.py", globals=0x91fa40, 
    locals=0x91fa40, flags=0x7fffffffe0c0, arena=0xb265e0)
    at Python/pythonrun.c:1810
        co = 0xbfb1b0
        v = 0x7fffffffde70
#16 0x00000000004be3e8 in PyRun_FileExFlags (fp=0xa6e890, 
    filename=0xaea7e0 "print_coercion_tables.py", start=257, globals=0x91fa40, 
    locals=0x91fa40, closeit=1, flags=0x7fffffffe0c0)
    at Python/pythonrun.c:1767
        ret = 0x18
        mod = 0xc3eeb8
        arena = 0xb265e0
#17 0x00000000004bc845 in PyRun_SimpleFileExFlags (fp=0xa6e890, 
    filename=0xaea7e0 "print_coercion_tables.py", closeit=1, 
    flags=0x7fffffffe0c0) at Python/pythonrun.c:1292
        m = 0x8fb588
        d = 0x91fa40
        v = 0x41bb94
        ext = 0xaea7f4 "s.py"
        set_file_name = 1
        ret = 0
        len = 24
#18 0x00000000004bbc1b in PyRun_AnyFileExFlags (fp=0xa6e890, 
    filename=0xaea7e0 "print_coercion_tables.py", closeit=1, 
    flags=0x7fffffffe0c0) at Python/pythonrun.c:1061
No locals.
#19 0x00000000004d7ddd in run_file (fp=0xa6e890, 
    filename=0x7ffff7f9a040 L"print_coercion_tables.py", p_cf=0x7fffffffe0c0)
    at Modules/main.c:307
        unicode = 0xa33da8
        bytes = 0xaea7b0
        filename_str = 0xaea7e0 "print_coercion_tables.py"
        run = -1979044144
#20 0x00000000004d8a9e in Py_Main (argc=2, argv=0x7ffff7f98040)
    at Modules/main.c:733
        c = -1
        sts = -1
        command = 0x0
        filename = 0x7ffff7f9a040 L"print_coercion_tables.py"
        module = 0x0
        fp = 0xa6e890
        p = 0x0
        skipfirstline = 0
        stdin_is_interactive = 1
        help = 0
        version = 0
        saw_unbuffered_flag = 0
        cf = {cf_flags = 0}
#21 0x00000000004162e0 in main (argc=2, argv=0x7fffffffe238)
    at ./Modules/python.c:63
        argv_copy = 0x7ffff7f98040
        argv_copy2 = 0x7ffff7f98070
        i = 2
        res = 0
        oldloc = 0x88d320 "\373\373\373\373\373\373\373", <incomplete sequence \373>
@teoliphant
Owner

Perhaps this is a reference count issue, but I don't now why it shows up in Python 3.2 but not Python 2.7

@seberg
Owner

Can it really be a reference count issue? It does not show up for me (Python 3.2.3 on Ubuntu 64bit), or does it only for the debug version or such?

@certik
Owner

I can't reproduce it either anymore. Let me bisect numpy just to be sure.

@certik
Owner

Ok, so it still fails in the latest master (4f7d3ff) as well as the latest 1.7 branch. But one has to use the debugging version of Python 3.2. I need to go to bed now, but this still has to be fixed.

@certik
Owner

I just tried python-2.7-debug, and it works here. So the problem only happens in 3.2-debug. Weird.

@certik
Owner

Here is a minimal script to reproduce the segfault:

import numpy as np
v = np.bytes_(0)
value = np.add(False, v)

The last line will segfault.

@certik
Owner

I bisected it a little bit. One bad commit is 5c7b9bb. All earlier commits don't even build in Python 3.2. So it looks like that this has never worked in Python 3.

@certik
Owner

Ok, so I dug into this. This patch "fixes" it (by creating a memory leak):

diff --git a/numpy/core/src/multiarray/scalarapi.c b/numpy/core/src/multiarray/s
index fcc68e9..2ab66f7 100644
--- a/numpy/core/src/multiarray/scalarapi.c
+++ b/numpy/core/src/multiarray/scalarapi.c
@@ -295,6 +295,7 @@ PyArray_FromScalar(PyObject *scalar, PyArray_Descr *outcode)
         return (PyObject *)r;
     }

+    Py_INCREF(typecode);
     r = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type,
             typecode,
             0, NULL,

The idea is quite simple. Here is the code that segfaults:

    r = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type,
            typecode,
            0, NULL,
            NULL, NULL, 0, NULL);
    if (r==NULL) {
        Py_XDECREF(outcode);
        return NULL;
    }
    if (PyDataType_FLAGCHK(typecode, NPY_USE_SETITEM)) {
        if (typecode->f->setitem(scalar, PyArray_DATA(r), r) < 0) {
            Py_XDECREF(outcode); Py_DECREF(r);
            return NULL;
        }
        goto finish;
    }

    memptr = scalar_value(scalar, typecode);

The definition of PyArray_NewFromDescr says:

/*NUMPY_API
 * Generic new array creation routine.
 *
 * steals a reference to descr (even on failure)
 */
NPY_NO_EXPORT PyObject *
PyArray_NewFromDescr(PyTypeObject *subtype, PyArray_Descr *descr, int nd,
                     npy_intp *dims, npy_intp *strides, void *data,
                     int flags, PyObject *obj)

Which means that a reference to typecode will be stolen. This however means, that we cannot access it anymore from our code, correct? So it's no surprise that we get a segfault when accessing typecode->f->setitem.
The patch above simply increases the refcount of typecode so that we can access it.

@certik
Owner

The PR #2831 that I just sent fixes this problem for me in the debug version. Now both the simple script as well as print_coercion_tables.py works just fine without any segfaults.

@teoliphant
Owner

Yes, you have identified the problem. One might think that typecode would be fine because you have a reference to the returned array which should keep a handle to the dtype object. However, there a few code-paths in PyArray_NewFromDescr that replace the datatype object with a new object (and therefore could cause the reference count of the data-type object passed in to fall below 1 unless typecode is incremented first).

This is a great catch. We should add a docstring to the PyArray_NewFromDescr function to emphasize that stealing the reference count means that you should not reference the typecode unless you can guarantee it will not be removed.

@teoliphant
Owner

This looks exactly right. At first blush it would seem that without the INCREF that "r" would have a reference to typecode and so it should be O.K. without the INCREF (as long as "r" stays around).

However, there are a few cases (subarray and scalars) where a code path in PyArray_NewFromDescr can result in the data-type being attached to "r" is a different data-type object than what is passed in and typecode is still dutifully DECREF'd. Thus, it could be deallocated and cause a segfault when referenced later.

So, yes, if PyArray_NewFromDescr is used and the caller wants to still use typecode specifically afterwards, a reference must be held.

Your fix is correct.

@certik certik closed this issue from a commit
@certik certik FIX: Fixes the segfault in PyArray_FromScalar
The problem was that PyArray_NewFromDescr() steals a reference to typecode and
so any further usage of it is undefined. Apparently this bug only appeared in
debug version of Python 3.2. The fix is to simply INCREF typecode and then
carefully DECREF it at each possible exit from the function.

Fixes gh-2738.
3c23c9f
@certik certik closed this in 3c23c9f
@certik
Owner

Thanks Travis. I really appreciate you looking over it. I am going to backport it now to the 1.7 branch.

@nouiz nouiz referenced this issue from a commit in nouiz/numpy
@certik certik FIX: Fixes the segfault in PyArray_FromScalar
The problem was that PyArray_NewFromDescr() steals a reference to typecode and
so any further usage of it is undefined. Apparently this bug only appeared in
debug version of Python 3.2. The fix is to simply INCREF typecode and then
carefully DECREF it at each possible exit from the function.

Fixes gh-2738.
e208de6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.