[ 
https://issues.apache.org/jira/browse/SPARK-60305?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

L. C. Hsieh updated SPARK-60305:
--------------------------------
    Affects Version/s: 4.2.0
                       4.1.3
                       4.0.4
                       4.3.0
                       4.4.0
                           (was: 5.0.0)

> Interrupting a Python Arrow UDF task can free its input buffer while it is 
> being written
> ----------------------------------------------------------------------------------------
>
>                 Key: SPARK-60305
>                 URL: https://issues.apache.org/jira/browse/SPARK-60305
>             Project: Spark
>          Issue Type: Bug
>          Components: PySpark
>    Affects Versions: 4.2.0, 4.3.0, 4.1.3, 4.0.4, 4.4.0
>            Reporter: L. C. Hsieh
>            Priority: Major
>
> Since SPARK-44705, the default (non-pipelined) Python runner serializes the 
> task input on the task thread into a DirectByteBufferOutputStream inside 
> BasePythonRunner.ReaderInputStream. The Arrow-based inputs (PythonArrowInput, 
> ColumnarArrowPythonInput) write that stream through 
> Channels.newChannel(dataOut), via ArrowStreamWriter and WriteChannel. The 
> returned channel is an AbstractInterruptibleChannel: each write chunk runs 
> between begin() and end(), and closing the channel closes the wrapped stream.
> If another thread interrupts the task thread while it is inside such a write, 
> for example Task.kill(interruptThread = true) when a speculative attempt or a 
> cancelled job is killed, Thread.interrupt() runs the channel's interruptor on 
> the interrupting thread. That closes the DataOutputStream and therefore the 
> DirectByteBufferOutputStream, which frees its direct buffer while the task 
> thread is still copying into it (or copying the old buffer in grow()). This 
> can crash the executor, silently corrupt memory, or fail with an NPE / 
> internal error instead of a clean task kill.
> Affected: Arrow-based Python UDFs and related operators (pandas/Arrow UDFs, 
> Arrow-optimized Python UDFs, mapInPandas/mapInArrow, applyInPandas, ...) on 
> the default non-pipelined path. The pickled BatchEvalPython path writes the 
> stream directly and is not affected.
> Fix: hand the writer a stream whose close() does not close the underlying 
> buffer, and free the buffer only where the runner closes it itself.
> Reported by Dongjoon Hyun in the review of 
> https://github.com/apache/spark/pull/59332 (SPARK-60113), which fixes the 
> same issue on the pipelined writer path.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to