You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
boost::iostreams::file_descriptor has the following two constructors on Windows (among others):
file_descriptor( int fd, file_descriptor_flags );
file_descriptor( HANDLE hFile, file_descriptor_flags );
When using the first one in combination with close_handle, the file descriptor is leaked. Take the following code:
#ifdef _WIN32
#include<io.h>
#endif
#include<fcntl.h>
#include<sys/stat.h>
#include<iostream>
#include<boost/iostreams/device/file_descriptor.hpp>intmain() {
std::cout << "open + stream:" << std::endl;
for (int i = 0; i < 3; i++) {
int fd = open("tmp", O_CREAT|O_RDWR, S_IREAD|S_IWRITE);
std::cout << "open(): " << fd << std::endl;
boost::iostreams::file_descriptor iostreamsFd(fd, boost::iostreams::close_handle);
}
std::cout << "open + close:" << std::endl;
for (int i = 0; i < 3; i++) {
int fd = open("tmp", O_CREAT|O_RDWR, S_IREAD|S_IWRITE);
std::cout << "open(): " << fd << std::endl;
close(fd);
}
}
It repeatedly uses open to create int file descriptors, and then constructs boost::iostreams::file_descriptor with boost::iostreams::close_handle from it, which then go out of scope immediately, which should close the fd. For comparison, a second loop just calls close to verify that fd numbers are actually reused immediately.
Running this on Windows (Windows 10, MSVC 19.29.30146.0, Boost 1.79.0) gives the following output, i.e. it leaks the fds from the first loop but not from the second:
open + stream:
open(): 3
open(): 4
open(): 5
open + close:
open(): 6
open(): 6
open(): 6
In comparison, running the same code on Linux (Arch Linux, g++ 12.1.0, Boost 1.79.0), the output looks like this, no fds are leaked:
open + stream:
open(): 3
open(): 3
open(): 3
open + close:
open(): 3
open(): 3
open(): 3
It looks like _get_osfhandle is used to obtain a HANDLE from the int fd:
To close a file whose operating system (OS) file handle is obtained by _get_osfhandle, call _close on the file descriptor fd. Never call CloseHandle on the return value of this function. The underlying OS file handle is owned by the fd file descriptor, and is closed when _close is called on fd.
This probably explains the leak: due to not using close/_close, the int fd is kept open (but now refers to an invalid handle).
The text was updated successfully, but these errors were encountered:
boost::iostreams::file_descriptor
has the following two constructors on Windows (among others):When using the first one in combination with
close_handle
, the file descriptor is leaked. Take the following code:It repeatedly uses
open
to createint
file descriptors, and then constructsboost::iostreams::file_descriptor
withboost::iostreams::close_handle
from it, which then go out of scope immediately, which should close the fd. For comparison, a second loop just callsclose
to verify that fd numbers are actually reused immediately.Running this on Windows (Windows 10, MSVC 19.29.30146.0, Boost 1.79.0) gives the following output, i.e. it leaks the fds from the first loop but not from the second:
In comparison, running the same code on Linux (Arch Linux, g++ 12.1.0, Boost 1.79.0), the output looks like this, no fds are leaked:
It looks like
_get_osfhandle
is used to obtain aHANDLE
from theint
fd:iostreams/src/file_descriptor.cpp
Lines 111 to 112 in 8003232
Which is then later used with
CloseHandle
:iostreams/src/file_descriptor.cpp
Line 266 in 8003232
According to the documentation for
_get_osfhandle
, this is something you explicitly shouldn't do:This probably explains the leak: due to not using
close
/_close
, theint
fd is kept open (but now refers to an invalid handle).The text was updated successfully, but these errors were encountered: