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

BugFix: Don't INCREF a Py section just allocated #3039

Merged
merged 15 commits into from
Sep 19, 2024

Conversation

ferdonline
Copy link
Member

@ferdonline ferdonline commented Aug 12, 2024

Context

Following #3023, we noticed that there might be extraneous call to INCREF, given it's done on an object returned by tp_alloc, which should return a new reference. New references have their ref count to 1 and therefore it should not require any additional reference increment.

Bug Reproducer

~$ nrniv -python

from neuron import h
h("create soma")
h("objref nc, nil")
h('soma nc = new NetCon(&v(0.5), nil)')
seg = h.nc.preseg()

Exit the interpreter and observe

Fatal Python error: bool_dealloc: deallocating True or False: bug likely caused by a refcount error in a C extension

Scope

  • Replace the code by the single function newpysechelp(sec) which seems to do just the right thing.
  • Added unit test

Testing

Two python unit tests added:

  • test_seg_from_sec_x_ref_python
  • test_seg_from_sec_x_ref_hocpy

For debug-ability it might be worth to add the following snippet to seg_from_sec_x

auto* psec = sec->prop->dparam[PROP_PY_INDEX].get<void*>();
fprintf(stderr, "In seg_from_sec_x. Pysec=%p\n", psec);

We will see along the lines of

In seg_from_sec_x. Pysec=0x7fa081736150
In seg_from_sec_x. Pysec=0x0

ensuring the we are exercising both cases.

After dropping the original section, the pure-python code end up with the same number of references as the hoc-python code.

@ferdonline ferdonline requested a review from 1uc August 12, 2024 22:02
Copy link

✔️ 4d66983 -> Azure artifacts URL

@bbpbuildbot

This comment has been minimized.

Copy link

codecov bot commented Aug 12, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 67.39%. Comparing base (4d749f1) to head (7842703).
Report is 1 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #3039   +/-   ##
=======================================
  Coverage   67.38%   67.39%           
=======================================
  Files         573      573           
  Lines      104936   104922   -14     
=======================================
  Hits        70711    70711           
+ Misses      34225    34211   -14     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@1uc 1uc changed the title Dont INCREF a new reference Don't INCREF a new reference Aug 13, 2024
@1uc
Copy link
Collaborator

1uc commented Aug 13, 2024

I see the logic behind the change and agree that the INCREF looks very suspicious.

IIUC a section is removed from a model, by letting the python object go out-of-scope. Once the object is GCed it's removed from the model.

We have some tests that assert this. I mostly see RXD tests fail because of this. Also for this PR, but it's failing in exactly the way RXD is known to fail from time to time: #2939.

This leak seems like something that changes the behaviour for users, i.e. it's a bug (because some section would refuse to be deleted from the model).

Do you see a way we could increase our test-coverage to catch the bug?

@ferdonline
Copy link
Member Author

ferdonline commented Aug 13, 2024

There is something else very suspicious. Notice that we let the created pyseg object get garbage collected (there was a DECREF before). I don't understand the reason to use a Python object basically as a factory for a hoc object... nrnpy_pyobject_in_obj seems to do the right thing though by incrementing the ref count.
Rerunning the failing job indeed made it pass... that's the observed condition then.

It might be worth more people to have a look. In the meantime I'll create a test

Copy link

✔️ 79891ce -> Azure artifacts URL

@bbpbuildbot

This comment has been minimized.

Copy link

✔️ 49a70be -> Azure artifacts URL

@bbpbuildbot

This comment has been minimized.

Copy link

✔️ 47b940f -> Azure artifacts URL

@bbpbuildbot

This comment has been minimized.

Copy link

✔️ 7caca61 -> Azure artifacts URL

@bbpbuildbot

This comment has been minimized.

@ferdonline ferdonline requested a review from alkino August 27, 2024 09:54
@ferdonline ferdonline changed the title Don't INCREF a new reference BugFix: Don't INCREF a Py section just allocated Aug 28, 2024
@ferdonline
Copy link
Member Author

Pls let me know if you consider the test sufficient

ferdonline added a commit that referenced this pull request Aug 29, 2024
@ferdonline
Copy link
Member Author

ferdonline commented Aug 29, 2024

@nrnhines We need your input in wrt the right behavior of seg_from_sec_x when there is not a corresponding Py Section. Do we want:

  • Py ref_count to be 2 and hoc ref_count not changed (current behavior)
  • Py ref_count be 1 and hoc ref_count not changed (patch 1)
  • Py ref_count be 1 and hoc ref_count incremented (last patch, behavior of newpysechelp)
  • ?

@bbpbuildbot

This comment has been minimized.

Copy link

✔️ 04637ce -> Azure artifacts URL

Copy link

✔️ 3f50c67 -> Azure artifacts URL

Copy link

✔️ fff7439 -> Azure artifacts URL

Copy link

✔️ 349d8a9 -> Azure artifacts URL

Copy link

✔️ e64040b -> Azure artifacts URL

Copy link

sonarcloud bot commented Sep 18, 2024

Copy link

✔️ 7842703 -> Azure artifacts URL

Copy link
Collaborator

@1uc 1uc left a comment

Choose a reason for hiding this comment

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

Very nicely done!

@1uc 1uc merged commit e462814 into master Sep 19, 2024
38 checks passed
@1uc 1uc deleted the fix/pybind/incref-on-new-ref branch September 19, 2024 15:28
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

Successfully merging this pull request may close these issues.

3 participants