Skip to content

Python: fix load_chunk to temporary #913

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
Feb 22, 2021
Merged

Conversation

ax3l
Copy link
Member

@ax3l ax3l commented Jan 29, 2021

Keep a reference in load_chunk until data is not used anymore.

Follow-up to #912 and related to #833

@ax3l ax3l added frontend: Python3 api: new additions to the API labels Jan 29, 2021
@ax3l ax3l force-pushed the topic-pyStoreChunkInMem branch 2 times, most recently from 4c7e3c0 to aab4d89 Compare January 29, 2021 07:06
@franzpoeschel
Copy link
Contributor

We might want to be careful not to do this twice ;) @ax3l
#901

I needed to implement something very similar for that PR

@ax3l
Copy link
Member Author

ax3l commented Jan 29, 2021

Yes, that's the follow-up PR to address the additional issue you mentioned and add an overload to allow in-memory reads:

Note: there is no in-memory overload for load_chunk yet exposed in Python.

I think it is still possible to trigger this bug in the load_chunk version. Notice that we create a new py::array on this line and pass it via shareRaw to the C++ API a few lines later. If the returned array is garbage-collected before the next flush, the next flush will write to free'd memory. That won't really happen in any sensible workflow, but we should still try to make it somewhat impossible to trigger memory errors from Python, and this one can be fixed much the same way that we already fixed the write-side API in this PR.

@ax3l ax3l mentioned this pull request Jan 29, 2021
2 tasks
@ax3l ax3l force-pushed the topic-pyStoreChunkInMem branch 3 times, most recently from 129d261 to 512d8c2 Compare January 29, 2021 21:13
@@ -1636,6 +1636,11 @@ def writeFromTemporaryStore(self, E_x):
data = np.array([[1, 2, 3]], dtype=np.dtype("int"))
E_x.store_chunk(data)

def loadToTemporaryStore(self, r_E_x):
# not catching the return value shall not result in a use-after-free:
r_E_x.load_chunk()
Copy link
Member Author

@ax3l ax3l Jan 29, 2021

Choose a reason for hiding this comment

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

@franzpoeschel it looks like these tests does not trigger the issue we were concerned about.

Maybe the GC zeroes out the data it frees or we are otherwise lucky... But then we should see this throw: https://github.com/openPMD/openPMD-api/blob/0.13.1/include/openPMD/RecordComponent.hpp#L334-L335

Do you have another Python snippet we could add in the test here that demonstrates the load_chunk issue?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd say this is likely a combination of (1) the rather small dataset that we test this on, (2) the fact that py::array initializes its data upon constructon and (3) that we don't allocate anything in between. So, maybe we could trigger this by making things go a bit wilder.

Copy link
Contributor

Choose a reason for hiding this comment

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

https://github.com/franzpoeschel/openPMD-api/tree/topic-pyStoreChunkInMem-increaseBuffersize
This branch triggers the issue on my machine and your implementation fixes it.

Copy link
Member Author

Choose a reason for hiding this comment

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

Great hint, thank you - increasing the tested memory triggers the issue reliably :)

@ax3l ax3l changed the title [Draft] Python: in-memory version of load_chunk [Draft] Python: fix load_chunk to temporary Jan 29, 2021
@ax3l ax3l removed the api: new additions to the API label Jan 29, 2021
@ax3l ax3l changed the title [Draft] Python: fix load_chunk to temporary Python: fix load_chunk to temporary Jan 29, 2021
@ax3l
Copy link
Member Author

ax3l commented Jan 29, 2021

We might want to be careful not to do this twice ;) @ax3l
#901

I needed to implement something very similar for that PR

@franzpoeschel sorry, there are too many LOC and feature editions in #901 that I did not see the partly overlap 🙈

I splitted my PR in a bugfix (this PR) and a feature addition (#914) to make them concise, backportable and easy to review. Let's see how we mingle them together.

Is #901 getting smaller once its dependent PR is merged and it can be rebased? :)

@ax3l ax3l force-pushed the topic-pyStoreChunkInMem branch from dc7444f to 4c9f9fb Compare January 29, 2021 21:43
@franzpoeschel
Copy link
Contributor

Is #901 getting smaller once its dependent PR is merged and it can be rebased? :)

A bit, but not drastically. Since this PR is the more "precise" one, I'd say go forward with implementing things here. I'll deal with getting things compatible during rebasing afterwards.

This should trigger a use-after-free.
@ax3l ax3l force-pushed the topic-pyStoreChunkInMem branch from 47a0200 to 4675b01 Compare February 22, 2021 07:44
Fix a use-after-free with load_chunk if the user discards the
returned object before flush.
@ax3l ax3l merged commit e743c03 into openPMD:dev Feb 22, 2021
@ax3l ax3l deleted the topic-pyStoreChunkInMem branch February 22, 2021 08:30
ax3l added a commit to ax3l/openPMD-api that referenced this pull request Apr 9, 2021
* Python Test: Discard loaded chunk

This should trigger a use-after-free.

* Fix Python: discarded load_chunk Object

Fix a use-after-free with load_chunk if the user discards the
returned object before flush.
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.

2 participants