Bug 8407 - Random crashes with Task Parallel Library
Summary: Random crashes with Task Parallel Library
Status: RESOLVED DUPLICATE of bug 8437
Alias: None
Product: iOS
Classification: Xamarin
Component: General ()
Version: 6.0.x
Hardware: Macintosh Mac OS
: --- major
Target Milestone: 6.4 (async)
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2012-11-14 15:30 UTC by Pierce Boggan [MSFT]
Modified: 2013-07-08 18:39 UTC (History)
5 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 DUPLICATE of bug 8437

Description Pierce Boggan [MSFT] 2012-11-14 15:30:48 UTC
"The crashes are rare and random but it looks like they happen only when this method is called from within a TPL task continuation. Again, I can't attach a reproducible example because it happens too randomly. Pokémon try-catch doesn't help."

Additional Details:
-Occurs at random times
-Does not occur in Debug mode, only Release
-Don't occur in any one method
-Works fine on simulator, not device
-Works using ThreadPool

*Attached crash reports*
*Attached StackTraces*
Comment 3 Pierce Boggan [MSFT] 2012-11-14 15:34:08 UTC
Last stacktrace was a crash in debug mode. This is one of the rare times it does.
Comment 5 Dan Abramov 2012-11-14 17:00:00 UTC
Hi Sebastien,
I sent more information to Pierce, I will also post it here.

You're absolutely right: at least one of the crashes turned out to be from the lack of 0-type trampolines.
I bumped the number from 512 to 2048 and haven't gotten this kind of crash again.

Another crash was due to RestSharp thread-safety problem, but it isn't the most common crash, and I won't have a problem fixing it.

However, I found that 90% of crashes happen when I cancel a CancellationToken which in turn aborts an HTTP request.

Relevant code from RestClientExtensions.cs:

var async = client.ExecuteAsync<IRestResponse>(request, (response, _) => {
    if (cancel.IsCancellationRequested || response == null)
        return;

    if (response.StatusCode != HttpStatusCode.OK) {
        tcs.TrySetException(new DropboxException(response));
    } else {
        tcs.TrySetResult(response);
    }
});

cancel.Register(() => {
    async.Abort(); // <- OFFENDING LINE
    tcs.TrySetCanceled();
});

When I comment out the HttpWebRequest.Abort() call,  most crashes go away.
Comment 14 Dan Abramov 2012-11-14 18:13:48 UTC
It is very possible that all recent crashes (after removing Abort call) were caused by a different problem.
I noticed this in device log before each of these crashes:

assetsd[86] <Error>: ImageIO: CGImageDestinationAddImage image parameter is nil
assetsd[86] <Error>: ImageIO: CGImageDestinationFinalize image destination does not have enough images
assetsd[86] <Error>: CGContextTranslateCTM: invalid context 0x0
assetsd[86] <Error>: CGContextScaleCTM: invalid context 0x0
assetsd[86] <Error>: CGContextSetBaseCTM: invalid context 0x0
assetsd[86] <Error>: CGContextSaveGState: invalid context 0x0
assetsd[86] <Error>: CGContextSetInterpolationQuality: invalid context 0x0
assetsd[86] <Error>: CGContextTranslateCTM: invalid context 0x0
assetsd[86] <Error>: CGContextScaleCTM: invalid context 0x0
assetsd[86] <Error>: CGContextSetFillColorWithColor: invalid context 0x0
assetsd[86] <Error>: CGContextFillRects: invalid context 0x0
assetsd[86] <Error>: CGContextTranslateCTM: invalid context 0x0
assetsd[86] <Error>: CGContextScaleCTM: invalid context 0x0
assetsd[86] <Error>: CGContextTranslateCTM: invalid context 0x0
assetsd[86] <Error>: CGContextTranslateCTM: invalid context 0x0
assetsd[86] <Error>: CGContextTranslateCTM: invalid context 0x0
assetsd[86] <Error>: CGContextConcatCTM: invalid context 0x0
assetsd[86] <Error>: CGContextTranslateCTM: invalid context 0x0
assetsd[86] <Error>: CGContextDrawImage: invalid context 0x0
assetsd[86] <Error>: CGContextRestoreGState: invalid context 0x0

So I suppose this has nothing to do with TPL and thus unrelated to the Abort() issue.
Comment 15 Dan Abramov 2012-11-14 18:38:29 UTC
False alert. Messages from the previous comment are not related to the crash (they happened a minute before). I don't know what causes these rare crashes yet.
Comment 18 Dan Abramov 2012-11-14 21:11:31 UTC
I think I have some good news.
I noticed each of the more recent crash reports had these lines:

p_144_llvm + 32
p_81_llvm + 8
monotouch_MonoTouch_CoreFoundation_CFProxy_get_ProxyType + 104
p_132_llvm + 164
monotouch_MonoTouch_CoreFoundation_CFNetwork_CFWebProxy_IsBypassed_System_Uri + 44
System_System_Net_ServicePointManager_FindServicePoint_System_Uri_System_Net_IWebProxy + 120
System_Net_HttpWebRequest_GetServicePoint_0 + 100
System_Net_HttpWebRequest_BeginGetResponse_System_AsyncCallback_object_0 + 516
RestSharp_Http_GetStyleMethodInternalAsync_string_System_Action_1_RestSharp_HttpResponse_0 + 508
RestSharp_MonoTouch_RestSharp_Http_AsGetAsync_System_Action_1_RestSharp_HttpResponse_string + 40
RestSharp_MonoTouch_RestSharp_RestClient_DoAsGetAsync_RestSharp_IHttp_System_Action_1_RestSharp_HttpResponse_string + 36

The only related thread I found was this one: http://monotouch.2284126.n4.nabble.com/100-NullReferenceException-in-HttpWebRequest-GetRequestStream-td3888273.html

That's where I found a workaround:

request.Proxy =  GlobalProxySelection.GetEmptyWebProxy(); 

It may be wishful thinking on my part, but I haven't been able to reproduce the second crash since putting in that line. 

My current understanding is there have been two different issues, both of which were not directly related to TPL.

The first bug represents regular crashes when calling HttpWebRequest.Abort() method in a CancellationToken's teardown process—not sure if it is specific to the requests DropNet/RestSharp creates. The bitter workaround is _not_ to abort the request (which sucks but will do for now).

The second bug represents rare crashes when beginning HttpWebRequest under certain unknown conditions, and hopefully seems to be cured by setting Proxy to GlobalProxySelection.GetEmptyWebProxy().

Just in case, the device in question is a non-jailbreaked iPad 2 running 6.0 (10A403).
For now, that's all I know.
Comment 19 Sebastien Pouliot 2012-11-15 15:43:47 UTC
It's possible that something in CFProxy is not thread safe. I'll look at it (and opened a new bug report for it, since this one history is already long and a bit confusing).
https://bugzilla.xamarin.com/show_bug.cgi?id=8437

IIRC HttpWebRequest.Abort called (at least a long time ago) Thread.Abort and we had (for Moonlight) to workaround that. Thread.Abort is never 100% safe to use. c.c. Martin for that one.

Also removing Jeremie from c.c. since there's nothing TPL specific.