Skip to content

Mod Python causing segmentation faults when compiled with Python3.9 #122

Open
@rohan-97

Description

@rohan-97

Hello,

I have recently upgraded from python3.7 to python3.9 and compiled mod_pyhton with python3.9.
After the upgrade, I see apache process crashing with segmentation fault intemittently.

I generated core dump and following is the traceback which I see.

[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
--Type <RET> for more, q to quit, c to continue without paging--l
Core was generated by `/usr/sbin/apache2 -d /var/service_dispatcher -X -k start'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  release_sentinel (wr_raw=0x7fd5ee538810) at ../Modules/_threadmodule.c:1246
1246    ../Modules/_threadmodule.c: No such file or directory.
[Current thread is 1 (Thread 0x7fd5e47f8700 (LWP 62175))]
(gdb) bt
#0  release_sentinel (wr_raw=0x7fd5ee538810) at ../Modules/_threadmodule.c:1246
#1  0x00007fd5f17f0a2a in release_interpreter (idata=0x564a091fcb40) at mod_python.c:306
#2  python_handler (req=0x7fd5c496f0a0, phase=<optimized out>) at mod_python.c:1573
#3  0x0000564a08e0c2d0 in ap_run_fixups ()
#4  0x0000564a08e0ea3b in ap_process_request_internal ()
#5  0x0000564a08e30978 in ap_process_async_request ()
#6  0x0000564a08e30bce in ap_process_request ()
#7  0x0000564a08e2ca44 in ?? ()
#8  0x0000564a08e216e0 in ap_run_process_connection ()
#9  0x00007fd5f18522d3 in ?? () from /usr/lib/apache2/modules/mod_mpm_worker.so
#10 0x00007fd5f1b30ea7 in start_thread () from /lib/x86_64-linux-gnu/libpthread.so.0
#11 0x00007fd5f1a50aef in clone () from /lib/x86_64-linux-gnu/libc.so.6
(gdb)

The traceback points to following line in mod_python.c,

following is the code block for reference

static void release_interpreter(interpreterdata *idata)
{
    PyThreadState *tstate = PyThreadState_Get();
#ifdef WITH_THREAD
    PyThreadState_Clear(tstate);
    if (idata)
        APR_ARRAY_PUSH(idata->tstates, PyThreadState *) = tstate;
    else
        PyThreadState_Delete(tstate);
    PyEval_ReleaseThread(tstate);
#else
    if (!idata) PyThreadState_Delete(tstate);
#endif
}

Looking at the code, we first create a PyThreadState object,
then make a call to PyThreadState_Clear(tstate) and if idata is empty, we make call to PyThreadState_Delete(tstate).

but in python3.9, there is a change in behaviour of PyThreadState_Clear and PyThreadState_Delete methods.

If we check the official documenatation of python, it states

void PyThreadState_Clear(PyThreadState *tstate)
Part of the Stable ABI.
Reset all information in a thread state object. The global interpreter lock must be held.

Changed in version 3.9: This function now calls the PyThreadState.on_delete callback. Previously, that happened in PyThreadState_Delete().

however when PyThreadState.on_delete callback is called, we see segmentation fault.

Following is the pull request which introduced this change,

python/cpython#18296

In the changed files we can see tstate->on_delete hook call is moved from PyThreadState_Delete to PyThreadState_Clear,

In order to avoid call to this hook,
I changed tstate->on_delete to point to null and following is th change which I did in mod_python.c's release_interpreter code block

static void release_interpreter(interpreterdata *idata)
{
    PyThreadState *tstate = PyThreadState_Get();
#ifdef WITH_THREAD
    tstate->on_delete = NULL;
    PyThreadState_Clear(tstate);
    if (idata)
        APR_ARRAY_PUSH(idata->tstates, PyThreadState *) = tstate;
    else
        PyThreadState_Delete(tstate);
    PyEval_ReleaseThread(tstate);
#else
    if (!idata) PyThreadState_Delete(tstate);
#endif
}

After this change, mod_python and apache is working completely fine,
However I am not sure if this is right fix or not.

Let me know if there are other ways to fix this issue and make mod_python compatible with python3.9

Otherwise I can raise a Pull request with that change.

Attaching core dump.

Thank You

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions