Bug 22234 - FileStream Read on created Thread dies with exception after time
Summary: FileStream Read on created Thread dies with exception after time
Status: RESOLVED UPSTREAM
Alias: None
Product: Android
Classification: Xamarin
Component: Mono runtime / AOT Compiler ()
Version: 4.16.0
Hardware: PC Windows
: Normal normal
Target Milestone: ---
Assignee: Marek Habersack
URL:
Depends on:
Blocks:
 
Reported: 2014-08-20 14:43 UTC by Frederic Rudman
Modified: 2017-06-27 19:25 UTC (History)
6 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 Developer Community or GitHub 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 UPSTREAM

Description Frederic Rudman 2014-08-20 14:43:42 UTC
I suspect this is similar (though slightly different symptoms) to BUG#20360.

Although I added a comment at the end of that previous bug, I open this new one today because the old one is now closed and deemed fixed (for an older environment) but some of the same symptoms are still happening today in our app (with the latest Android stable version as of August 20, 2014: v4.14.0.

For your convenience, I simply cut-and-paste my previous comments here:

We are experiencing something very close (but not exactly the same) as the
problem listed above. The symptoms are described below but first, a quick
question: it's now August 20th, 2014: has the fix above been released to
Android/IDE yet or not. If it has, our problem is NOT solved. If not, I'm
hoping maybe your fix will work for us. This is a serious/major/show-stopper
problem for us.



[IMPORTANT: as per the last statement below: If it has been fixed but not yet
released, is there a way for us to test your fix right away? Please let us
know. Thanks.]



Our environment: An Android-based UDOO Quad (Android running on the Freescale
i.MX6 side; Arduino running on an Atmel SAM3x mcu). We're trying to use the
Arduino connected to Android as per Android's ADK/USB Accessory.

Steps to reproduce are consistent (sadly): we simply get the USBManager (as per
Android docs/protocol), open the FileInputStream from the Accessory's
FileDescriptor (a Java object) and start reading that fileInputStream. [on the
Arduino side, we use USBHost/ADK, also as per protocol]

For the tests, we kept everything simple: we simply periodically write a few
bytes on the Arduino side to be read on the Android side. Reading is done a
Thread (.net) and upon reception of bytes we update the UI (via RunOnUIThread
calls, obviously). All threading/reading is done on the .Net side, in a simple
loop with NO dynamic object allocations: we use a once-allocated byte buffer
over-and-over, 1024 bytes.

All is well for a while: we've had anywhere from 12,000 reads all the way up to
30,000 reads depending on how we varied the delay on the Arduino's side (a
simple write functions that writes M bytes consistently to the USB Accessory
every N milliseconds: we tested N with 50ms, 300ms, 330ms, 400ms, and 500ms,
and matrix tested with M at 9 bytes, 14 bytes, and 26 bytes.

Although the failure rates were sometimes different we've ALWAYS failed in the
fileInputStream.read after anywhere from 12,000 reads (a few minutes at 50ms)
to 30,000 reads (a few hours at 500ms).

All these reads are done on a simple separate .Net THREAD (not Java) and it was
never a hang (unlike the symtoms described by you above): we always end up with
a caught Java.IO exception (caught from the .net try/catch side): most often
(99%, but not 100%) it's a "No Such Device/ENODEV" error (as if the "device"
disappeared suddenly" [at libcore.io.IoBridge.read (IoBridge.java: 435;
FileInputStream.java: 179]). We can supply all the test code, if needed/wanted,
to consistently reproduce this problem.

When the reads succeeded (up until the end) the bytes read were always correct
(not a single error).

We've also tested it with regular and, separately, occasional writes (using
FileOutputStream) in case we needed to perhaps "prime/refresh the
pump/pipeline" both ways. No go.

We've also tested with regularly CLOSING, then REOPENING the file streams (both
input and output) after a fixed number of messages (e.g. 1,000) as a "soft
reset" feature. That definitely improved the number of loops (from our early
3K-5K to 12K-30K) but still failed in the end.

We suspected all along that it was a memory/GC problem but when we list
available RAM (using Android's MemoryInfo) it shows plenty of memory and very
little used (our code does NOT do dynamic allocations).

We need to be able to have our Arduino hardware communicate "continuously" over
the USB Accessory port for MONTHS on end, not just a few minutes or hours. We
can probably reduce the frequency of writes from 50ms to maybe 500ms [that
would be slow but we could adjust for that] in case speed is an issue for the
USB Accessory link, but it needs to be either:
1) consistent and never fail) 
...OR...
2) If it must fail, we need to be able to reset/restart it in software (we
can/could [probably] afford a few seconds/minute of no comm while that link is
being reset).

Does any of this seem familiar to you folks or should I file this as a separate
bug?

Would there be any workaround in the meantime: this bug is a major show-stopper
for us. The biggest problem is that when the communication between Arduino and
Android dies, we have no way to restart it: Android cannot be software-tricked
into Resetting the USB Accessory (unless you know something we don't?)

IMPORTANT: If this is likely the same problem you fixed but it has been fixed
but not yet released, is there a way for us to test your fix right away? Please
let us know. Thanks.

ALSO: here's the info on our Xamarin setup:

=== Xamarin Studio ===

Version 5.2.1 (build 1)
Installation UUID: 75a1b04b-0573-48dd-9033-bf08bc7f5047
Runtime:
	Microsoft .NET 4.0.30319.18444
	GTK+ 2.24.22 (MS-Windows theme)
	GTK# 2.12.25

=== Xamarin.Android ===

Version: 4.14.0 (Indie Edition)
Android SDK: C:\Users\DV18Admin\AppData\Local\Android\android-sdk
	Supported Android versions:
		2.1   (API level 7)
		2.2   (API level 8)
		2.3   (API level 10)
		3.1   (API level 12)
		4.0   (API level 14)
		4.0.3 (API level 15)
		4.2   (API level 17)
		4.3   (API level 18)
		4.4   (API level 19)
Java SDK: C:\Program Files (x86)\Java\jdk1.6.0_39
java version "1.6.0_39"
Java(TM) SE Runtime Environment (build 1.6.0_39-b04)
Java HotSpot(TM) Client VM (build 20.14-b01, mixed mode, sharing)

=== Build Information ===

Release ID: 502010001
Git revision: d06832ce9807d6be24aca225457e8b37c7669f6f
Build date: 2014-08-07 14:35:09-04
Xamarin addins: 1de032531be4cecf2f39dbee3b87aac78204058c

=== Operating System ===

Windows 6.1.7601.65536 (64-bit)
Comment 1 Frederic Rudman 2014-08-29 11:17:08 UTC
Well, we gave up on this one and went the Java route, as a workaround. We re-implemented the same code using only Java (using Android Studio [works pretty well btw]) and the code has been running flawlessly for 6 days now (30MM iterations or so). 

Not sure what's the problem with Xamarin and either FileInputStream and/or USB Accessory but it's unusable.

What we're doing next: creating a Service that will simply hand off the data from Java back to our C# app. PITA.
Comment 2 Frederic Rudman 2014-08-29 11:21:10 UTC
Also, just to add: we had tried it with version 4.16 which supposedly had the FileStream fix from the prior-reported bug: that di NOT work for us. Same problems. So either that bug fix was for a different problem or it was not a fix in the first place.

One additional note: we noticed that with the Java version, whenver we killed the app then restarted it, the USB Accessory was automatically detected and re-initialized. That NEVER happened with the C# code. Whenever we stopped the App (before it died, obviously) and try to re-enter it, the USB Accessory did NOT restart. We could open it and the file descriptors and the file streams (input, output) but nothing happened: no input, no output. Until we had to physically reboot the device.
Comment 3 Jatin 2015-01-13 06:32:11 UTC
I have tried to reproduce this issue at my end using the latest builds, but I am not able to reproduce it. As I am still observing the behavior mentioned in the comment #2 of the Bug 22234

Below is the screencast for the same:
http://www.screencast.com/t/ATEmIsde95aV

Please let me know if you are still facing this issue.

As of now marking this issue as needinfo.

Build information:

Microsoft Visual Studio Professional 2013
Version 12.0.31101.00 Update 4
Microsoft .NET Framework
Version 4.5.50938

Installed Version: Professional

LightSwitch for Visual Studio 2013   06177-004-0446016-02757
Microsoft LightSwitch for Visual Studio 2013

Team Explorer for Visual Studio 2013   06177-004-0446016-02757
Microsoft Team Explorer for Visual Studio 2013

Visual Basic 2013   06177-004-0446016-02757
Microsoft Visual Basic 2013

Visual C# 2013   06177-004-0446016-02757
Microsoft Visual C# 2013

Visual C++ 2013   06177-004-0446016-02757
Microsoft Visual C++ 2013

Visual F# 2013   06177-004-0446016-02757
Microsoft Visual F# 2013

Visual Studio 2013 Code Analysis Spell Checker   06177-004-0446016-02757
Microsoft® Visual Studio® 2013 Code Analysis Spell Checker

Portions of International CorrectSpell™ spelling correction system © 1993 by Lernout & Hauspie Speech Products N.V. All rights reserved.

The American Heritage® Dictionary of the English Language, Third Edition Copyright © 1992 Houghton Mifflin Company. Electronic version licensed from Lernout & Hauspie Speech Products N.V. All rights reserved.

Windows Phone SDK 8.0 - ENU   06177-004-0446016-02757
Windows Phone SDK 8.0 - ENU

Application Insights Tools for Visual Studio Package   1.0
Application Insights Tools for Visual Studio

ASP.NET and Web Tools   12.4.51016.0
Microsoft Web Developer Tools contains the following components:
Support for creating and opening ASP.NET web projects
Browser Link: A communication channel between Visual Studio and browsers
Editor extensions for HTML, CSS, and JavaScript
Page Inspector: Inspection tool for ASP.NET web projects
Scaffolding: A framework for building and running code generators
Server Explorer extensions for Microsoft Azure Websites
Web publishing: Extensions for publishing ASP.NET web projects to hosting providers, on-premises servers, or Microsoft Azure

ASP.NET Web Frameworks and Tools 2012.2   4.1.21001.0
For additional information, visit http://go.microsoft.com/fwlink/?LinkID=309563

ASP.NET Web Frameworks and Tools 2013   5.2.21010.0
For additional information, visit http://www.asp.net/

Common Azure Tools   1.3
Provides common services for use by Azure Mobile Services and Microsoft Azure Tools.

Microsoft Advertising SDK for Windows Phone   
Microsoft Advertising SDK for Windows Phone
Build 

Microsoft Azure Mobile Services Tools   1.3
Microsoft Azure Mobile Services Tools

NuGet Package Manager   2.8.50926.663
NuGet Package Manager in Visual Studio. For more information about NuGet, visit http://docs.nuget.org/.

Office Developer Tools for Visual Studio 2013 ENU   12.0.30626
Microsoft Office Developer Tools for Visual Studio 2013 ENU

PowerShell Tools   1.3
Provides file classification services using PowerShell

PreEmptive Analytics Visualizer   1.2
Microsoft Visual Studio extension to visualize aggregated summaries from the PreEmptive Analytics product.

SQL Server Data Tools   12.0.41012.0
Microsoft SQL Server Data Tools

Windows Phone 8.1 SDK Integration   1.0
This package integrates the tools for the Windows Phone 8.1 SDK into the menus and controls of Visual Studio.

Workflow Manager Tools 1.0   1.0
This package contains the necessary Visual Studio integration components for Workflow Manager.

Xamarin   3.9.236.0 (d6a2cae)
Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android.

Xamarin.Android   4.20.0.34 (49a04b966feb40dfdba49d57ba16249b66d606a6)
Visual Studio plugin to enable development for Xamarin.Android.

Xamarin.iOS   8.6.0.0 (eb24bdcf5cba2c12b673a07e0a8cce368b9563b3)
Visual Studio extension to enable development for Xamarin.iOS.

Xamarin.iOS Unified Migration   1.0
Automated migration for Xamarin iOS Classic projects to Unified
Comment 4 Antao Almada 2016-02-10 09:58:42 UTC
I'm struggling with this same ENODEV issue.

I'm trying to communicate with our custom USB device using UsbAccessory but I keep getting a "Java.IO.IOException: read failed: ENODEV (No such device)" at random times but always during a read operation.

I've been accessing one other custom device using UsbDevice with no issues. Now I really need to have UsbAccessory working...

I suspected it was a thread related issue with the Java-based streams so I'm using a Rx.NET LoopEventScheduler (https://msdn.microsoft.com/en-us/library/system.reactive.concurrency.eventloopscheduler(v=vs.103).aspx) This garantees that stream creating and read/write operations always happen on the same thread. Unfortunately it did not fix the issue.

It's good to know that it works with Java but I would much prefer not to have to go on that route.

I've been struggling with this for several weeks and I'm suposed to ship this product this week. :(

It's hard for me to send you my source code as it requires custom hardware but the steps Frederic describes above can be tested with an Arduino.

A Java UsbAccessory example can be found at https://github.com/devunwired/accessory-samples/blob/master/AccessoryController/src/com/examples/accessory/controller/MainUsbActivity.java

Antao

=== Xamarin Studio ===

Version 5.10.2 (build 56)
Installation UUID: a74dcad0-6570-426b-a93c-513c340e4f08
Runtime:
	Microsoft .NET 4.0.30319.42000
	GTK+ 2.24.23 (MS-Windows theme)
	GTK# 2.12.30

=== Xamarin.Profiler ===

Version: 0.30.0
Location: C:\Program Files (x86)\Xamarin\Profiler\XamarinProfiler.exe

=== Xamarin.Android ===

Version: 6.0.1.10 (Business Edition)
Android SDK: D:\Android\sdk
	Supported Android versions:
		4.0.3 (API level 15)
		4.4   (API level 19)
		5.0   (API level 21)
		5.1   (API level 22)
		6.0   (API level 23)

SDK Tools Version: 24.3.4

SDK Platform Tools Version: 23

SDK Build Tools Version: 23 rc1


Java SDK: C:\Program Files\Java\jdk1.7.0_80
java version "1.7.0_80"
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)

=== Xamarin Android Player ===

Version: 0.3.7.2
Location: C:\Program Files\Xamarin Android Player\DeviceManager.exe

=== Build Information ===

Release ID: 510020056
Git revision: bb74ff467c62ded42b7b7ac7fdd2edc60f8647b0
Build date: 2016-01-26 15:49:39-05
Xamarin addins: 8b797d7ba24d5abab226c2cf9fda77f666263f1b
Build lane: monodevelop-windows-cycle6-c6sr1

=== Operating System ===

Windows 6.3.9600.0 (64-bit)
Comment 5 Antao Almada 2016-03-26 19:09:23 UTC
After a lot of research we tracked this issue to a bug in the Android USB accessory kernel driver.

https://android.googlesource.com/kernel/common/+/daafe226f73674d5246a642c2399b8e81afac540%5E%21/#F0

I just don't understand how using Java changed the behavior. We had to use native C code for an workaround.
Comment 6 Frederic Rudman 2016-03-29 21:07:28 UTC
so what is the workaround? Can we go back to a C#.net-only solution and dump the java code?
Comment 7 Antao Almada 2016-03-31 08:59:44 UTC
You have to use the Android API through Xamarin to request user permission and open the accessory. Get the file descriptor from the resulting ParcelFileDescriptor.
Use p/invoke to create a pthread in native code. Block the following signals in the pthread: SIGPWR, SIGSYS, SIGXCPU, SIGTTOU and SIGABRT. 
Use another p/invoke call to send the file descriptor and a buffer to read the accessory data. Use semaphore to send and retrieve data to the pthread and use read(fd, data, len) inside it.
Comment 8 Chris Hardy [MSFT] 2017-06-27 19:25:21 UTC
Marking as resolved upstream due to the issue happening as part of the Android source