Notice (2018-05-24): bugzilla.xamarin.com is now in
Please join us on
Visual Studio Developer Community and in the
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
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.
"For multithreaded applications, Cocoa frameworks use locks and other forms of internal synchronization to ensure they behave correctly. To prevent these locks from degrading performance in the single-threaded case, however, Cocoa does not create them until the application spawns its first new thread using the NSThread class. If you spawn threads using only POSIX thread routines, Cocoa does not receive the notifications it needs to know that your application is now multithreaded. When that happens, operations involving the Cocoa frameworks may destabilize or crash your application.
To let Cocoa know that you intend to use multiple threads, all you have to do is spawn a single thread using the NSThread class and let that thread immediately exit. Your thread entry point need not do anything. Just the act of spawning a thread using NSThread is enough to ensure that the locks needed by the Cocoa frameworks are put in place.
If you are not sure if Cocoa thinks your application is multithreaded or not, you can use the isMultiThreaded method of NSThread to check."
When I check NSThread.IsMultiThreaded from inside a C# Thread, it returns false.
What is the scenario that is failing for you?
And would you mind doing this to your application to figure out if this is the fix you are looking for?
Before you call the UIApplication.Main in your mina method, can you create an NSThread and launch it?
I'll detail my bug below, but may I ask, under what situation you believe it to be appropriate when using managed Threads to *not* initialize the iOS frameworks mutexes? Calling an iOS framework that relies on these mutexes is guaranteed to cause problems. How do we know which iOS API calls use these mutexes? We can't.
I've been doing iOS for over two years now, and this was the first I'd heard of this. I've never had to worry because I used NSThreads in my natively coded apps.
I believe that the onus falls on Mono to initialize the mutexes. The instructions are clear: if you use pthreads, and you use iOS frameworks, you must initialize the mutexes. Monotouch uses pthreads, and monotouch uses iOS frameworks.
Here's my bug. It may or not be caused by NSThread.IsMultiThreaded being false. But it lead me to the documentation on it.
I have an utterly random bug that results in crashes (NullRefs and SIGSEGVs) in random places. Often the stack is unavailable higher than where the problem happened, which suggest to me that a) the stack is blown and b) the stack was blown while the thread was asleep, it woke up, loaded some dodgy values, and then called the code which then crashed.
When I first had the problem (about a month ago), I git-bisected the problem and the check-in which broke it could not possibly have caused the error. It was just unlucky.
Creating the project as an XCode project and running that caused the problem to go away (Geoff helped me immensely getting that working). Running in debug mode makes the problem go away. Eventually after bashing my head trying different things on the bistected build, and I gave up and tried doing things with HEAD, and the problems went away.
Not surprisingly they came back yesterday, and it was then that I noticed the stack state and that looks like another thread bombing this one's stack. So thats when I started looking for thread related issues.
Btw: After a few changes, I could not get my app to reproduce the bug - even backtracking. Otherwise I would totally try adding just that NSThread init to main and seeing what happened.
Of course, if I added that line, and it fixed the problem, it wouldn't actually prove that NSThread fixed it, because adding any given line of code may make the code go away. =(
Agreed, MonoTouch will be updated to address this issue, but I wanted to find the use case that was failing.
The problem is how do you debug such a thing? Normally when one has thread bugs, they are because a mutex isn't being used somewhere it should, or something like that.
But that's not what we have here. Here we have a (supposedly) working framework, with mutexes that we are deliberately disabling! To "repro" these framework "bugs", we have to deliberately turn off all mutexes and then "see what happens". What would the purpose of that be?
It would certainly be useful to me to know that *my* bug is caused by not turning on thread-safety in iOS, yes. Unfortunately, that will be impossible to prove. Lets say calling, or not calling the NSThread start, fixes/hides the bug. Did the bug go away because it was caused by iOS framework's lack of mutexes? Or did it go away simply because the mutexes introduced new timing, and the timing suppressed the bug?
Really the thing to do is slap a hardware breakpoint on the stack that's being bombed and see where it happens. However, I don't believe there is a way to do that without making an XCode build, and the last time I did that (with Geoff's help) it just made the bug go away. I was sad.
I wonder if rooting the device will allow me to attach a debugger from ssh?
This has now been fixed.