Bug 38408 - Error disposing of Filestream when leaving using statement
Summary: Error disposing of Filestream when leaving using statement
Status: RESOLVED FIXED
Alias: None
Product: Runtime
Classification: Mono
Component: io-layer (show other bugs)
Version: 4.2.0 (C6)
Hardware: All All
: --- normal
Target Milestone: ---
Assignee: Aleksey Kliger
URL:
Depends on:
Blocks:
 
Reported: 2016-02-03 22:06 UTC by nicholas.rudh
Modified: 2016-02-12 19:58 UTC (History)
4 users (show)

See Also:
Tags:
Is this bug a regression?: ---
Last known good build:


Attachments

Description nicholas.rudh 2016-02-03 22:06:36 UTC
Overview: when using a FileStream to write to the /dev/xdevcfg file on an embedded Linux system running on Xilinx zynq board, if an error is thrown inside the "using" statement the file is locked and if I catch the error and try to reprogram the PL with this file I get an error saying "Error: Sharing violation on path /dev/xdevcfg" 

Steps to Reproduce: create a using statement which uses a filestream catch an error when writing then try to reopen the file with a filestream outside of the using statement.

Actual Results: get an error saying the file is still open

Expected Results: ability to reopen the file

Build Date & Hardware: build 4.2.2

Additional Builds and Platforms: Not known

Additional Information: Code below

NOTE: this works with .bin file which do not produce an error programming the PL; however I need to be able to try and use bad .bin files and then fix them, so the error occurs using a known bad .bin file which results in the /dev/xdevcfg returning an error

try
{

  using(FileStream br = new FileStream(pathIn, FileMode.Open))
  using(FileStream bw = new FileStream(pathOut, FileMode.Open))
  {
    byte[] buffer = new byte[512];
    int bytesRead;
    while((bytesRead = br.Read(buffer, 0, 512)) > 0)
    {
      bw.Write(buffer, 0, bytesRead);
    }
  }  
}
catch (IOException e)
{
  using(FileStream bw = new FileStream(pathOut, FileMode.Open))//ERROR OCCURS HERE
  using(FileStream br = new FileStream(GOODPATH, FileMode.Open))
  {
    byte[] buffer = new byte[512];
    int bytesRead;
    while((bytesRead = br.Read(buffer, 0, 512)) > 0)
    {
      bw.Write(buffer, 0, bytesRead);
    }

  }
}
Comment 1 nicholas.rudh 2016-02-04 19:27:08 UTC
Additional Notes:
From testing the problem only occurs when an exception is thrown inside the using statement and the file is a "0 byte" file. I tried to do a similar test with /dev/mem and threw an exception and the result was the same sharing violation error. However when I tried it with just a .txt file the result was as expected and was able to open the filestream again.

thanks
Comment 2 Aleksey Kliger 2016-02-11 17:05:26 UTC
Happens with character devices too (for example try the code below with /dev/zero).  Also a problem on OSX. Not a permission error.  No need for try/catch either.  

Minimal example:

    using System;
    using System.IO;
    
    class Example {
    	public static void Main (String[] args)
    	{
    		string p = args[0];
    		Console.WriteLine ("p = {0}", p);
    		using (var f = new FileStream (p, FileMode.Open))
    		{
    			Console.WriteLine ("one");
    		}
    		Console.WriteLine ("two");
    		using (var g = new FileStream (p, FileMode.Open))
    		{
    			Console.WriteLine ("three");
    		}
    	}
    }

Output:
    p = /dev/zero
    one
    two
    
    Unhandled Exception:
    System.IO.IOException: Sharing violation on path /dev/zero
      at System.IO.FileStream..ctor (System.String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, Boolean anonymous, FileOptions options) <0x2a29ef0 + 0x00708> in <filename unknown>:0 
      at System.IO.FileStream..ctor (System.String path, FileMode mode) <0x2a299c0 + 0x00060> in <filename unknown>:0 
      at (wrapper remoting-invoke-with-check) System.IO.FileStream:.ctor (string,System.IO.FileMode)
      at Us1.Main (System.String[] args) <0x17d9ed8 + 0x000d7> in <filename unknown>:0 
    [ERROR] FATAL UNHANDLED EXCEPTION: System.IO.IOException: Sharing violation on path /dev/zero
      at System.IO.FileStream..ctor (System.String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, Boolean anonymous, FileOptions options) <0x2a29ef0 + 0x00708> in <filename unknown>:0 
      at System.IO.FileStream..ctor (System.String path, FileMode mode) <0x2a299c0 + 0x00060> in <filename unknown>:0 
      at (wrapper remoting-invoke-with-check) System.IO.FileStream:.ctor (string,System.IO.FileMode)
      at Us1.Main (System.String[] args) <0x17d9ed8 + 0x000d7> in <filename unknown>:0
Comment 3 Aleksey Kliger 2016-02-11 22:08:51 UTC
In fact, the fact that it's a character device is what's causing all the trouble.  We never decrement the share ref count when closing console handles.
Comment 4 Aleksey Kliger 2016-02-12 19:58:29 UTC
Fixed on master in 1113ca6b61c4dd863a41bb586f55087d4aa9f9ce.  Fixed on the mono-4.3.2-branch in 619f48b58b49cd8c10c6ec77238283681514c519.

Note You need to log in before you can comment on or make changes to this bug.