Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash on program exit #248

Open
blakat360 opened this issue Feb 4, 2021 · 9 comments
Open

Crash on program exit #248

blakat360 opened this issue Feb 4, 2021 · 9 comments

Comments

@blakat360
Copy link

The following code segfaults with python 3. It does so on the Py_Finalize call

#include <matplotlibcpp.h>

int main() {
    namespace plt = matplotlibcpp;
    plt::plot({1,3,2,4});
    plt::show();
    plt::close();
    return 0;

The following does not:

#include <matplotlibcpp.h>

int main() {
    namespace plt = matplotlibcpp;
    plt::plot({1,3,2,4});
    plt::show();
    plt::close();
    plt::detail::_interpreter::kill();
    return 0;
}

I'm not plotting in different threads so not sure why this is happening.
Perhaps the following will solve this: https://stackoverflow.com/questions/1427002/calling-py-finalize-from-c

@JonasBreuling
Copy link

I've encountered the same problem but wasn't able to figure out what goes wrong. But I think you are right that something goes wrong with the call Py_Finalize();.

@blakat360
Copy link
Author

I tried a naive implementation of the above fix and it didnt work :(

Apparently Py_InitThreads is deprecated so no ideas here :( not very familiar with embedding python in c/c++

@JonasBreuling
Copy link

JonasBreuling commented Feb 5, 2021

That is interesting. I made some investigations and here is what I found out.

The following code crashes with a Segfault

#include <matplotlibcpp.h>
int main()
{
    matplotlibcpp::figure();
    matplotlibcpp::show();
}

but this works fine

#include <matplotlibcpp.h>
int main()
{
    matplotlibcpp::figure();
    matplotlibcpp::show();
    Py_Finalize();
}

I've also implemented a minimal working example of the core features of the above two calls. Everything works fine there...

#include <Python.h>

int main()
{
    Py_Initialize();

    PyObject* matplotlibname = PyUnicode_FromString("matplotlib");
    PyObject* matplotlib = PyImport_Import(matplotlibname);
    Py_DECREF(matplotlibname);

    PyObject* pyplotname = PyUnicode_FromString("matplotlib.pyplot");
    PyObject* pymod = PyImport_Import(pyplotname);
    Py_DECREF(pyplotname);

    PyObject* s_python_function_figure = PyObject_GetAttrString(pymod, "figure");
    PyObject* s_python_function_show = PyObject_GetAttrString(pymod, "show");
    PyObject* empty_tuple = PyTuple_New(0);

    PyObject *fig = PyObject_CallObject(s_python_function_figure, empty_tuple);
    PyObject *res = PyObject_CallObject(s_python_function_show, empty_tuple);

    Py_DECREF(matplotlib);
    Py_DECREF(pymod);
    Py_DECREF(s_python_function_figure);
    Py_DECREF(s_python_function_show);
    Py_DECREF(empty_tuple);
    Py_DECREF(fig);
    Py_DECREF(res);

    Py_Finalize();
}

So somewhere between the above core code and the matplotlibcpp code there is a problem I can't figure out.

@blakat360
Copy link
Author

Is there any way matplotlibcpp or the python interpreter spin up different threads?

@JonasBreuling
Copy link

Sorry for the late reply, I missed your message. And I don't know If something goes wrong with the threads.

@filiatra
Copy link

Hi,
same problem here, adding Py_Finalize(); at the end of the program fixes it.

@pascal-mueller
Copy link

This issue might be related to the backend of matplotlib. See #268

@amadeus84
Copy link

@pascal-mueller

It is related, it's explained in the stackoverflow link. Py_Finalize() is called from the _interpreter destructor, which is being called too late, because the interpreter is static. calling kill() or Py_Finalize() before return, in main fixes it. That's with Qt5Agg used by python3. Changing the backend to TkAgg seems to work without issues.

@pascal-mueller
Copy link

pascal-mueller commented Mar 14, 2022

@amadeus84 Thanks, I remember trying to solve it but couldn't. Can't remember why but also didn't had the time to dig into it too deep. You fix seems easy enough though. I hope it gets merged! It's quit a pain of a bug.

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

No branches or pull requests

5 participants