Bug in FileStream.Dispose in Framework 1.1

G

Guest

I have come across a bug in FileStream.Close that causes File handles to leak.

If you create a FileStream then try to write to it when the destination disk
is full:

outputStream.Write(buffer, 0, readCount);

you get an IOException "There is not enough space on the disk".

That's fine, until you then try to dispose the FileStream, by calling
Dispose (or Close, which simply calls Dispose). Dispose attempts to flush
the stream, which causes it to attempt to write the buffer, which generates
an error (since the disk is full), which throws an IOException, leaving the
system file handle unreleased, resulting in a leaked handle.

I've considered obtaining the handle in my catch block and releasing it
directly, but that seems to be a path fraught with peril-- after all, I don't
know what else the FileStream code might do when the object is finalized...

Anyone else seen this? How do I go about reporting it to MS?
 
P

Peter Huang [MSFT]

Hi,

Currently I am researching the issue and we will reply here with more
information as soon as possible.
If you have any more concerns on it, please feel free to post here.

Thanks for your understanding!

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
P

Peter Huang [MSFT]

Hi

So far I can reproduce the problem and I have reported the issue to our dev
team.
I will update you with new information ASAP.

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
P

Peter Huang [MSFT]

Hi

We have confirmed this is problem in our product, and we will plan to fix
it in the next release(Whidbey).

So you may try to use CloseHandle API to force the file handle release if
you found there is a IOException with error(disk is full)
This is just test code, you may adjust according or your scenario.
NOTE: Please try to get the FileHandle before the exception may occur.
class Class1
{
[DllImport("kernel32.dll")]
private static extern bool CloseHandle(IntPtr hObject);

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
string path = @"..\..\Test1.txt";
string str = "Test";
byte[] bts = Encoding.ASCII.GetBytes(str);
//byte[] bts = new byte[512*1024*1024];
MessageBox.Show("Before Create");
FileStream fs = new FileStream(path,FileMode.OpenOrCreate);
IntPtr hFile = fs.Handle;
try
{
MessageBox.Show("Created");
while(true)
fs.Write(bts,0,bts.Length);
fs.Flush();
MessageBox.Show("Before Closed");
fs.Close();
MessageBox.Show("Closed");
}
catch(Exception ex)
{
try
{
MessageBox.Show(ex.ToString());
fs.Flush();
MessageBox.Show("Before Closed");
fs.Close();
MessageBox.Show("Closed");
}
catch(Exception exp)
{
try
{
MessageBox.Show(exp.ToString());
MessageBox.Show("Before Closed");
fs.Close();
MessageBox.Show("Closed");
}
catch(Exception expt)
{
MessageBox.Show(expt.ToString());
}
}
}
MessageBox.Show("Before Exit");
//MessageBox.Show(CloseHandle(hFile).ToString());//We have to call the
API to force close the file handle
fs = null;
MessageBox.Show("Before GC");
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
MessageBox.Show("After GC");
}
}


Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top