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

Calling _io().close() on ByteBufferKaitaiStream leaves open file descriptors #497

Closed
brunchboy opened this issue Dec 5, 2018 · 3 comments
Milestone

Comments

@brunchboy
Copy link

In the Java runtime, once a Kaitai Struct has been opened using fromFile() with the default stream implementation generated by the compiler, it is impossible to properly close all open file descriptors using the API. lsof on the Java process shows two file descriptors being opened by fromFile(), and only one of them gets closed when you call _io().close(). This is a problem because it prevents removable media from which structures have been read from being ejected until the entire process is terminated, and that is a common desirable use case for me.

@brunchboy
Copy link
Author

Explicitly constructing objects using RandomAccessFileKaitaiStream does not exhibit this problem.

brunchboy added a commit to Deep-Symmetry/crate-digger that referenced this issue Dec 5, 2018
Also needed to switch from using default ByteBufferKaitaiStream to
explicitly creating RandomAccessFileKaitaiStream instances because
of kaitai-io/kaitai_struct#497
brunchboy added a commit to Deep-Symmetry/beat-link that referenced this issue Dec 5, 2018
Close Kaitai Struct files when possible, and provide a way to
explicitly close those which are returned to API clients. Also had to
switch from using the default Kaitai stream implementation because of
kaitai-io/kaitai_struct#497
brunchboy added a commit to Deep-Symmetry/beat-link-trigger that referenced this issue Dec 5, 2018
Also explicitly change the stream implementation used, due to
kaitai-io/kaitai_struct#497
@GreyCat
Copy link
Member

GreyCat commented Dec 8, 2018

I did some examination and this is the result: kaitai-io/kaitai_struct_java_runtime@83ee786

I don't think we can do more at this point. To summarize, it's a defiency of Java APIs, which does not allow us to explicitly "close" mmap, thus removing mmap. Current solution will allow you to "close" mmap-backed KaitaiStream by invoking close() and then running System.gc() manually.

I've tested in a simple application. Before this change, I was getting these in lsof:

# Before close()
java    4082 greycat  mem    REG                8,2      138 29142950 /path/to/file
java    4082 greycat   23r   REG                8,2      138 29142950 /path/to/file
# After close()
java    4082 greycat  mem    REG                8,2      138 29142950 /path/to/file

After this change + System.gc(), I'm getting more or less consistent closure:

# Before close()
java    4685 greycat  mem    REG                8,2      138 29142950 /path/to/file
java    4685 greycat   23r   REG                8,2      138 29142950 /path/to/file
# After close()

For historical purposes, this is the lsof invocation line I've been using:

MYPID=$(ps awwx | grep testfileclose.Main | grep -v grep | cut -c1-5); MYPID=$(($MYPID)); lsof -n -p $MYPID | grep /path/to/file

@GreyCat GreyCat closed this as completed Dec 8, 2018
@GreyCat GreyCat added this to the v0.9 milestone Dec 8, 2018
@brunchboy
Copy link
Author

Thanks for the explanation and link to the JDK bug discussion. What an ugly mess! This does perfectly explain some of the exceptions one of my Windows users was encountering as well.

I agree that this is the best that the Kaitai project can do until the underlying Java issue is fixed. The hack-arounds that some people were suggesting are a terrible idea.

Since System.gc() is not guaranteed to do anything, from my perspective this means that ByteBufferKaitaiStream simply cannot be used in Java until Java is fixed. Thankfully, you do offer RandomAccessFileKaitaiStream which I am now successfully using.

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

No branches or pull requests

2 participants