Dag Sverre Seljebotn wrote:
> Cython currently segfaults when using a buffer in nogil and accessing
> out of bounds (which triggers an IndexError). This is a bug, however I
> would like to do more than disallow it.
>
> I.e. what should happen here:
>
>      cdef object[int] buf = ... # buffer of length < 6
>      with nogil:
>          buf[5] = 0
>
> Option 1) Reacquire the GIL temporarily to construct the IndexError
> instance. This seems to work wonderfully in my current patch; but is it
> too unintuitive to raise an exception from an operation in a nogil
> section?

Well, exceptions happen to be the error reporting mechanism in Python. In
any case, the above must exit the nogil block immediately and should not
crash (as long as we can prevent it in a reasonable way). To me, this
sounds like an exception is the right thing.

However, it's quite possible that this kind of control flow makes error
handling and C-level cleanup measures a nightmare. How would such a nogil
block interact with try-except or try-finally, for example? We can't allow
try-except /inside/ the block, so you'd have to anticipate all errors and
wrap separate sections of the nogil block in their own try-except or
try-finally statements to make sure the cleanup works as required.


> Will any other operation trigger an exception within a nogil
> section?

You can have exceptions that get raised in callbacks that re-acquire the
GIL, so you can't be sure that nogil blocks do not raise exceptions
anyway.

Think of code like this (which does not currently work):

    cdef extern from *:
        # some external C library function
        void call_into_c(...) nogil except *

    cdef void callback(void* data) with gil except *:
        ((...*)data).failed = 1   # cause abort in calling C library
        raise IndexError

    try:
        with nogil:
            call_into_c(callback, &some_data)
            printf("we never get here!")
    except IndexError:
        print "holy moly!"

To support this, Cython would have to generate code to re-acquire the GIL
after the call to "call_into_c()", check for an error and then either jump
out of the failed nogil block or release the GIL and continue.

If we start raising exceptions inside nogil blocks, this would be the next
obvious step. I have not made up my mind yet if this is a good thing. At
least, I know a couple of cases in lxml where I could use it, but this
will certainly need some prior exploration before deciding to make this an
official language feature.


> Option 2) Only allow buffer use in nogil if @cython.boundscheck(False).
> This has some usability problems; it would be a pain to turn on/off
> nogil for debugging.

Sounds like a viable alternative, though. Should be followed if exception
raising is not considered accurate from inside nogil blocks.


> Option 3) Print to standard output using printf instead of raising
> exception.

-1 This is a clear error case that should not pass silently.

Stefan

_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to