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)

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

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

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.