Skip to content

BUG: General fixes to f2py reference counts (dereferencing) #12633

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

Merged
merged 2 commits into from
Oct 15, 2019

Conversation

seberg
Copy link
Member

@seberg seberg commented Dec 31, 2018

Continuation of gh-12624, I am not sure how much I will keep working on this. I think the changes should be mostly/all fine. But the error handlig is not improved, only the reference counting dirtily. So sometimes I am not sure if this might actually make things worse and XDECREF should be used at least.

A lot of this could probably simply use a bit of an audit and love...

There is a single (probably) leak left in test_compile_functions.py after this, if I see it right.

@mattip
Copy link
Member

mattip commented Dec 31, 2018

Any idea why the python 3.5 tests are failing on travis?

@seberg
Copy link
Member Author

seberg commented Dec 31, 2018

Hmmm, I guess there may be one DECREF too many somewhere? But funny it only shows on 3.5.

}
Py_XDECREF(v);
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this was correct before, I am just not used to not having curly brackets here.

#varname#_xa_capi = (PyTupleObject *)PySequence_Tuple(capi_tmp);
else
Py_DECREF(capi_tmp);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, this is the only thing that I am not quite sure of on first sight. I guess have to run it through a debugger/valgrind with python 3.5, but do not have a 3.5 on my arch laptop available right now.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does not really smell wrong though, so really need to run through a debugger on py3.5...

@mattip
Copy link
Member

mattip commented Dec 31, 2018

Can reproduce the segfault in free after downloading the python3.5 used in the CI testing. It seems to be local to cleanup after running python3.5 runtests.py -t numpy/f2py/tests

@seberg
Copy link
Member Author

seberg commented Dec 31, 2018

@mattip can you run it in valgrind with --track-origins? I think that might tell us which python object got decref'd twice.

@mattip
Copy link
Member

mattip commented Dec 31, 2018

@mattip
Copy link
Member

mattip commented Dec 31, 2018

found thise PyDict issue while nosing around, I don't know if it is relevant though it describes various use-after-free issues with dict that were fixed https://bugs.python.org/issue27945

@@ -215,6 +215,7 @@
\td = PyModule_GetDict(m);
\ts = PyString_FromString(\"$R""" + """evision: $\");
\tPyDict_SetItemString(d, \"__version__\", s);
\tPy_DECREF(s);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the source of the double free on Python3.5. When I remove it I still get a segfault, but not a double free and abort

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems strange that this should be so bad, it seems obviously right, no? Don't really have time to look into it though.

Copy link
Contributor

@superbobry superbobry Aug 7, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have observed the double free with Python 3.5 as well, and the fix (counter-intuitively) is to use PyObject_Del instead of PyMem_Free in fortran_dealloc (see gh-14217).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm, PyObject_Free is the correct thing in any case I think. Although, I am a bit puzzle why it ends up crashing things so hard, but then I do not know how the python memory management works internally. I think I will rebase your PyObject_Free fix as a first commit into my PR?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sgtm!

@mattip
Copy link
Member

mattip commented Dec 31, 2018

I am not sure this is worth the effort. There is a problem with module teardown on python3.5. Using PYTHONVERBOSE=3 I get the following at teardown when running python3 runtests.py -t numpy/f2py/tests/test_callback.py

# cleanup[3] wiping _test_ext_module_5403
#   clear[2] func0
double free or corruption (out)

It seems the func0 value in the module dict has already been freed?

@seberg
Copy link
Member Author

seberg commented Dec 31, 2018

I think the leaks here are probably pretty harmless, since they are on import. The main reason would be to make debugging other stuff easier in the long run probably.

@charris charris changed the title BUG: Gneral fixes to f2py reference counts (dereferencing) BUG: General fixes to f2py reference counts (dereferencing) Jan 2, 2019
@charris charris added this to the 1.16.1 release milestone Jan 2, 2019
@charris
Copy link
Member

charris commented Jan 19, 2019

Segfaulting on 3.5, not sure why.

@charris
Copy link
Member

charris commented Jan 19, 2019

@seberg Do you feel that it would be safe to backport this?

@seberg
Copy link
Member Author

seberg commented Jan 19, 2019

@charris, likely safe. But at least almost all are just import time leaks that nobody ever noticed much. So I don't think it is important probably. Those 3.5 segfaults are worrying. Matti tracked something down that may be related, never looked at it closely, but it makes me think it might be best to just delay this for now in any case.

@charris charris modified the milestones: 1.16.1 release, 1.16.2 release Jan 19, 2019
@charris
Copy link
Member

charris commented Jan 19, 2019

OK, I kicked it off to 1.16.2.

@charris charris removed this from the 1.16.2 release milestone Jan 22, 2019
@charris charris removed the 09 - Backport-Candidate PRs tagged should be backported label Jun 28, 2019
Note that the extension module dict seems to be never dereferenced
(there is an additional reference to it kept around somewhere).
This reference seems to part of the C python module loading
(possibly intentionally), and I could not find how to remove it or
where it originates from.


def test_f2py_init_compile_failure():
# verify an appropriate integer status value returned by
# f2py.compile() when invalid Fortran is provided
ret_val = numpy.f2py.compile(b"invalid")
ret_val = numpy.f2py.compile(b"invalid", verbose=False)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

curious why you changed this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, those are those spammy comilation prints you say if you run the tests with -- -s... and they seem pretty unimportant to pirnt out by default.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assumes anyone looking for what went wrong in the tests will know to add verbose=True in whatever test interests them

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe add a comment somewhere?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe, it would probably be nicestest to store it in a variable. In a sense that is what pytest does. I think part of it was that pytest leaks had issues with it (which are fixed). So I just remove it for now, can be added easily at any time.

@mattip
Copy link
Member

mattip commented Sep 22, 2019

LGTM. Anyone else want to take a look?

@mattip mattip merged commit 908b601 into numpy:master Oct 15, 2019
@seberg seberg deleted the f2py-refcnt branch October 15, 2019 17:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants