Skip to content
This repository has been archived by the owner on Aug 5, 2021. It is now read-only.

Segfault when iterating through Python globals dictionary #177

Open
pont-us opened this issue Sep 2, 2020 · 3 comments
Open

Segfault when iterating through Python globals dictionary #177

pont-us opened this issue Sep 2, 2020 · 3 comments
Labels

Comments

@pont-us
Copy link
Member

pont-us commented Sep 2, 2020

This bug manifested itself as a failure of the unit test PyObjectTest.testDictCopy(). It can also be triggered by the following minimal snippet (Python 3.8, 64-bit Ubuntu Linux 20.04) (after setting the necessary jpy configuration properties and calling PyLib.startPython()):

final Map<PyObject, PyObject> globalsDict = PyLib.getMainGlobals().asDict();
for (Map.Entry<PyObject, PyObject> entry : globalsDict.entrySet()) {
    System.out.println("Entry: " + entry.getKey() + " -> " + entry.getValue());
}

The iteration succeeds for two loops, printing Entry: __name__ -> __main__ and Entry: __doc__ -> None. At the start of the third iteration it crashes with a segmentation fault. The culprit appears to be builtins.call("next", it) in the iterator returned by PyDictWrapper.EntrySet.iterator(). This calls through to PyObject.call(). The control flow continues into PyLib_CallAndReturnObject in org_jpy_PyLib.c, and eventually to this line:

pyReturnValue = PyObject_CallObject(pyCallable, argCount > 0 ? pyArgs : NULL);

It is this call to PyObject_CallObject in Python's C API which directly triggers the segmentation fault.

@pont-us
Copy link
Member Author

pont-us commented Sep 2, 2020

Here's a minimal Java source file to reproduce the problem.

package test.jpysegfault;

import org.jpy.PyLib;
import org.jpy.PyObject;
import java.util.Map;

public class Main {

    public static void main(String[] args) {
        System.setProperty("jpy.pythonLib",
                "/home/pont/miniconda3/envs/jpy-38/lib/libpython3.8.so");
        System.setProperty("jpy.jpyLib",
                "/home/pont/loc/repos/jpy/build/lib.linux-x86_64-3.8/jpy.cpython-38-x86_64-linux-gnu.so");
        System.setProperty("jpy.jdlLib",
                "/home/pont/loc/repos/jpy/build/lib.linux-x86_64-3.8/jdl.cpython-38-x86_64-linux-gnu.so");
        PyLib.startPython();
        final Map<PyObject, PyObject> globalsDict = PyLib.getMainGlobals().asDict();
        for (Map.Entry<PyObject, PyObject> entry : globalsDict.entrySet()) {
            System.out.println("Entry: " + entry.getKey() + " -> " + entry.getValue());
        }
        PyLib.stopPython();
    }
}

@pont-us
Copy link
Member Author

pont-us commented Sep 2, 2020

Attached: log file generated by running the test script above with JPy_DiagFlags = JPy_DIAG_F_ALL set in src/main/c/jpy_diag.c.

hs_err_pid18349.log

@pont-us pont-us added the bug label Sep 2, 2020
@ag-tcm
Copy link

ag-tcm commented Feb 6, 2021

@pont-us I came across this bug. Are you aware of any workaround? Thanks!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants