jenkinsci / lib-file-leak-detector

Java agent that detects file handle leak
http://file-leak-detector.kohsuke.org/
MIT License
241 stars 112 forks source link

Support for java.nio #11

Closed centic9 closed 4 years ago

centic9 commented 11 years ago

It seems file operations using java.nio are not captured currently, e.g. the following piece of code opens a file, but is not visible in the file-leak-detector currently:

    FileChannel channel = FileChannel.open(Paths.get("somefile"), StandardOpenOption.READ);

These are usually done via java.nio.FileChannel, I tried to take a look, but the necessary instrumentation is non-trivial.

Any plans to add this so also the newer Java NIO file handles are checked?

centic9 commented 10 years ago

I tried to work on this myself because I have several projects that would benefit from this, but unfortunately I cannot really get a good grip on this because my bytecode/asm knowledge is not that far-reaching.

What I see is that FileChannel and FileChannelImpl have static methods open(), which are called from other places. I tried to instrument this and FileSystemProvider.newFileChannel() to get the necessary entry-points for file-leak-detector, but I ran into some hurdles on the way, e.g. it seems only RETURN is handled in MethodAppender.append(), but these methods return a reference via ARETURN, this seems to be not supported currently by file-leak-detector, or?

Any hints on how support for Java NIO would need to be built to make it work?

hakanai commented 7 years ago

I was coming to ask about an NIO thing which is obliquely related.

This RAF is supposedly not closed:

#106 /tmp/+~JF1627244331554911179.tmp by thread:x on Fri Aug 18 10:35:56 JST 2017
    at java.io.RandomAccessFile.<init>(RandomAccessFile.java:244)
    at java.io.RandomAccessFile.<init>(RandomAccessFile.java:124)
    at sun.font.TrueTypeFont$1.run(TrueTypeFont.java:311)

But what the code's actually doing is:

                RandomAccessFile var2 = (RandomAccessFile)AccessController.doPrivileged(new PrivilegedAction() {
                    public Object run() {
                        try {
                            return new RandomAccessFile(TrueTypeFont.this.platName, "r");
                        } catch (FileNotFoundException var2) {
                            return null;
                        }
                    }
                });
                this.disposerRecord.channel = var2.getChannel();

Assuming that I have not found a bug in the JRE itself, I guess the getChannel() call should be treated as equivalent to close() here, and then the FileChannel watched instead?

dwnusbaum commented 4 years ago

Files opened through FileChannel.open should be detected as of https://github.com/kohsuke/file-leak-detector/pull/33. The behavior is tested in integration tests here.

centic9 commented 4 years ago

Yep, seems it's there for some time now, so this one can be set closed as implemented via #33