Issues with MonoTouch and CFStream API - ios

I am currently developing an application that needs to communicate with a MQTT server via a socket connection. As the System.Net.Sockets API tends to misbehave when switching from a WiFi network to a 3G network (and this happens quite a lot actually) I've decided to give the CFStream API a try. In doing so I've encountered several issues, as follows.
Creating a pair of streams with CreatePairWithSocketToHost crashes the application as soon as I call Open() on either one of the streams.
CFStream.CreatePairWithSocketToHost(GetEndPoint(), out mReadStream, out mWriteStream);
mReadStream.EnableEvents(CFRunLoop.Current, CFRunLoop.CFDefaultRunLoopMode);
mWriteStream.EnableEvents(CFRunLoop.Current, CFRunLoop.CFDefaultRunLoopMode);
mReadStream.Open();
mWriteStream.Open();
The crash occurs regardless of whether I call EnableEvents() or not. The exception is:
[ERROR] FATAL UNHANDLED EXCEPTION: MonoTouch.CoreFoundation.CFException: The operation couldn’t be completed. Cannot allocate memory
at MonoTouch.CoreFoundation.CFStream.CheckError () [0x0000f] in /Developer/MonoTouch/Source/monotouch/src/shared/CoreFoundation/CFStream.cs:236
at MonoTouch.CoreFoundation.CFStream.Open () [0x00040] in /Developer/MonoTouch/Source/monotouch/src/shared/CoreFoundation/CFStream.cs:248
at TestCfNework.RootViewController.TestCreatePairToHost () [0x00041] in /Users/adrian/Projects/TestCfNework/TestCfNework/RootViewController.cs:79
at TestCfNework.RootViewController.ViewDidLoad () [0x00000] in /Users/adrian/Projects/TestCfNework/TestCfNework/RootViewController.cs:24
at MonoTouch.UIKit.UIWindow.MakeKeyAndVisible () [0x00008] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIWindow.g.cs:124
at TestCfNework.AppDelegate.FinishedLaunching (MonoTouch.UIKit.UIApplication app, MonoTouch.Foundation.NSDictionary options) [0x0002e] in /Users/adrian/Projects/TestCfNework/TestCfNework/AppDelegate.cs:32
at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38
at TestCfNework.Application.Main (System.String[] args) [0x00000] in /Users/adrian/Projects/TestCfNework/TestCfNework/Main.cs:17
Creating a pair of streams with CreatePairWithSocket by first creating and connecting a CFSocket allows for Open() to proceed without crashing, but CanAcceptBytesEvent is never fired, CanAcceptBytes() is always false and any write attempt fails with a timeout.
mSocket = new CFSocket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp,
CFRunLoop.Current);
mSocket.ConnectEvent += delegate {
Console.WriteLine("Socket connected");
CFStream.CreatePairWithSocket(mSocket, out mReadStream, out mWriteStream);
mReadStream.EnableEvents(CFRunLoop.Current, CFRunLoop.CFDefaultRunLoopMode);
mWriteStream.EnableEvents(CFRunLoop.Current, CFRunLoop.CFDefaultRunLoopMode);
mReadStream.Open();
mWriteStream.Open();
mWriteStream.CanAcceptBytesEvent += delegate {
Console.WriteLine("Write stream can now accept data");
};
mWriteStream.ErrorEvent += delegate {
Console.WriteLine(mWriteStream.GetError());
};
};
mSocket.Connect(GetEndPoint(), 0);
Creating a pair of streams using CreatePairWithPeerSocketSignature is the only one that actually produces a pair of streams that I can work with: opening does not crash and I am allowed to write to and read from respectively.
The API behaves this way both on the simulator and on the actual device. So, is this something I am doing wrong? Is it a MonoTouch issue? Is it a bug in the CFStream API itself?
MonoTouch version: 6.0.1.
XCode version: 4.5.

I wrote most the CFNetwork code in MonoMac / MonoTouch, so I should hopefully be able to help you with this :-)
Your code looks ok to me. It works fine with MonoMac (stand-alone Cocoa application on the Mac), but I see the same problem with MonoTouch. Opening the read stream sometimes works, sometimes not, opening the write stream always fails.
CFStream.CreatePairWithSocketToHost() calls CFStreamCreatePairWithSocketToCFHost().
After adding a new overloaded version:
public static void CreatePairWithSocketToHost (string host, int port,
out CFReadStream readStream,
out CFWriteStream writeStream)
which calls CFStreamCreatePairWithSocketToHost(), this is now working fine.
I just had a look at this and found the problem, will have a fix for it shortly.
About your second problem, the CFSocket API is hitting the same code path internally, so it's also affected by this bug.

To wake up the 3G network, you want to use:
http://iosapi.xamarin.com/?link=T%3aMonoTouch.ObjCRuntime.Runtime%2fM%2fStartWWAN

Related

iOS: Setting up a Mach exception handler without interfering with LLDB

I'm using the library called CwlPreconditionTesting which is used to test Swift assertions. It uses Mach exceptions handler API to catch exceptions that's available on iOS and OS X.
The library works well in simulators, but devices aren't supported by it. The reason for this is that on devices, the Swift assert functions (e.g. fatalError) crash with EXC_BREAKPOINT exception type, which is also the exception type the debugger uses when someone puts a breakpoint somewhere and the debugger wants to suspend the program. The underlying assembly instruction is brk.
I wanted to add device tests support to the library, but after setting up the exception handler, if the debugger reaches a breakpoint I added manually, the debugger just hangs. To bypass this, I tried to make the exception handler forward the handling of the exception to the debugger.
When I implement an exception handler, if it returns with a failure (i.e. anything other than KERN_SUCCESS), the kernel should forward it to the next exception handler in line, the debugger in my case. I didn't find any official documentation on this, but it says so here and in a piece of code from Mike Ash's blog:
// Handle EXCEPTION_DEFAULT behavior
kern_return_t catch_mach_exception_raise (mach_port_t exception_port,
mach_port_t thread,
mach_port_t task,
exception_type_t exception,
mach_exception_data_t code,
mach_msg_type_number_t codeCnt)
{
// Do smart stuff here.
fprintf(stderr, "My exception handler was called by exception_raise()\n");
// Inform the kernel that we haven't handled the exception, and the
// next handler should be called.
return KERN_FAILURE;
}
Even if I always return KERN_FAILURE, the debugger hangs when I pause at a breakpoint. Here's a screenshot from the Variables View in Xcode, which loads indefinitely:
Is there a way to set up an exception handler and live in peace with LLDB?

Xamarin forms media plugin crashes on iphone when using SQLiteNetExtensions

Xamarin Forms Media Plugin crashes on my iphone when using SQLite-Net-Extensions.
the line below hangs then crashes after retrieving an image, but works if i don't use the camera.
SQLiteNetExtensions.Extensions.ReadOperations.GetAllWithChildren<MyObject>(database, recursive: true);
below is the exception:
2018-03-26 16:21:37.303 (ProjectName).iOS[364:41332] Unable to get metadata: System.ArgumentNullException: Value cannot be null.
Parameter name: asset
at Photos.PHImageManager.RequestImageData (Photos.PHAsset asset, Photos.PHImageRequestOptions options, Photos.PHImageDataHandler handler) [0x0008c] in /Library/Frameworks/Xamarin.iOS.framework/Versions/11.8.0.20/src/Xamarin.iOS/Photos/PHImageManager.g.cs:170
at Plugin.Media.PhotoLibraryAccess.GetPhotoLibraryMetadata (Foundation.NSUrl url) [0x0004c] in :0
at Plugin.Media.MediaPickerDelegate+d__25.MoveNext () [0x00305] in :0
i would like to know why this is happening and possible way of resolving this issue?
To anyone else having this problem, i manage to resolve it....the line that was actually cause this issue was not SQLiteNetExtensions.Extensions.ReadOperations.GetAllWithChildren<MyObject>(database, recursive: true);
but it was actually SQLiteNetExtensions.Extensions.WriteOperations.InsertOrReplaceWithChildren(database, item); ....that code was breaking because the foreign key relationship was incorrect....i am still not sure why that cause the camera to crash....but the issue is resolved now.

MvvmCross sometimes has problems with IoC

I encounter quite bad problem with MvvmCross IoC resolving.
We have a big application that registers about 100 different services and 6 plugins.
Sometimes we are getting problems with resolving these services. Most time it works fine, but then at Xamarin.Insights I can see that at production, there are some problems that happens(NOT ALWAYS), for example this:
Cirrious.CrossCore.Exceptions.MvxIoCResolveExceptionFailed to resolve
type Cirrious.MvvmCross.Localization.IMvxTextProvider
Cirrious.CrossCore.IoC.MvxSimpleIoCContainer.Resolve(Type)
at Cirrious.CrossCore.IoC.MvxSimpleIoCContainer.Resolve<Cirrious.MvvmCross.Localization.IMvxTextProvider> () <0x00023>
at Cirrious.CrossCore.Mvx.Resolve<Cirrious.MvvmCross.Localization.IMvxTextProvider> () <0x0004b>
<project>.Droid.Code.Menu.MenuActivity<TextMessageDetailsViewModel>.OnCreate(Bundle)
Android.App.Activity.n_OnCreate_Landroid_os_Bundle_(intptr, intptr, intptr)
at (wrapper dynamic-method) object.715a16ed-a35e-4884-89f1-5e2568dbe846 (intptr,intptr,intptr) <0x00043>
What can cause the problem that only sometimes it doesn't work?

Attempting to JIT compile method exception in MonoTouch.CoreGraphics.CGContext.DrawPDFPage

Here is the stack
System.ExecutionEngineException: Attempting to JIT compile method '(wrapper managed-to-native) MonoTouch.CoreGraphics.CGContext:CGContextDrawPDFPage (intptr,intptr)' while running with --aot-only. See http://docs.xamarin.com/ios/about/limitations for more information.
at MonoTouch.CoreGraphics.CGContext.DrawPDFPage (MonoTouch.CoreGraphics.CGPDFPage page) [0x00000] in :0
at Neva.PdfViewer.PageContentView.Draw (MonoTouch.CoreGraphics.CGContext context) [0x00000] in :0
at Neva.PdfViewer.PageContentTile.DrawInContext (MonoTouch.CoreGraphics.CGContext ctx) [0x00000] in :0 [7.1.1]
While we were not able to recreate this problem in QA or unit testing, this exception randomly happens on AppStore distributed installations.
Looking at DrawPDFPage in CGContext
public void DrawPDFPage (CGPDFPage page)
{
CGContext.CGContextDrawPDFPage (this.handle, page.handle);
}
where CGContextDrawPDFPage is a P/Invoke function
[DllImport ("/System/Library/Frameworks/CoreGraphics.framework/CoreGraphics")]
private static extern void CGContextDrawPDFPage (IntPtr c, IntPtr page);
doesn't give us any hint. The link above http://docs.xamarin.com/ios/about/limitations is not really helpful.
My question is, what could be causing such an exception? What are steps to debug and fix it?
This exception (System.ExecutionEngineException: Attempting to JIT compile method ...) should be 100% reproducible.
The fact that it isn't, points at something else (and probably worse): memory corruption of some sort.
However without some way to (at least randomly) reproduce it yourself, it's close to impossible to track down.
My initial suggestion would be to try to figure out if there's anything at all you can figure out in order to be able to create a test case yourself:
Does it only occur for a certain set of devices (only iPad 2 for instance)?
Does it only occur for a certain set of customers (only customers in Iceland for instance)?
Is the exception exactly the same every time, or does the P/Invoke / stack trace vary?
Is it a low-memory condition? Did the app get memory warnings prior to this occurring?
Are there any required steps in your app (i.e. if the user does X+Y it may crash, but if he does Y+X, then it never crashes)?

Facebook C# sdk random exception when posting photo

I am using Facebook C#sdk to upload photos to user profiles using a Windows Service as a background job. And I am logging exceptions in almost every place that I can think of and for the most part it works fine. But occasionally, and sometimes it is quite frequent, I get the following exception, which does not get caught by my handler, and gets logged by the Windows Event logger, and terminates my service:
Application: PhotoService.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.Exception
Stack:
at System.Net.Security._SslStream.WriteCallback(System.IAsyncResult)
at System.Net.LazyAsyncResult.Complete(IntPtr)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Net.ContextAwareResult.Complete(IntPtr)
at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)
From the looks of it, this is happening at FacebookClient.PostTaskAsync() method call, but I have no idea how to troubleshoot with the limited stacktrace information. Below is my photo posting method block:
public void PostPhotoToTimeline(string filename, byte[] photo, EventHandler<FacebookApiEventArgs> callbackCompleted)
{
var _filename = filename;
var mediaObject = new FacebookMediaObject
{
ContentType = "image/jpeg",
FileName = _filename
}.SetValue(photo);
_fb.PostCompleted += callbackCompleted;
var parameters = new Dictionary<string, object>();
parameters["file"] = mediaObject;
_fb.PostTaskAsync("/me/photos", parameters);
}
My biggest problem at the moment is, when this exception occurs, it terminates the service and I don't have service monitoring set up yet, so no way for me to find out the service has stopped. If I understand it correctly, this exception occurs in a separate thread and is not handled, thus it brings down the whole service. Is this correct? Any idea why this might be happening and where, or anyone faced this exception before? I have read about 'legacyUnhandledExceptionPolicy' to catch these unexpected exceptions. Will this prevent my service from terminating and is it good idea to use it? Sorry if I am asking too many questions in one go but these are all related and google hasn't been my friend on this so far.
Thanks for any help you can provide.
2 months gone and not a single answer, so I will post what I did to prevent this issue which might be useful to others. Still don't know the main cause for the crash but it is occasional, so using the flag "legacyUnhandledExceptionPolicy" has worked so far, with no unexpected terminations. The flag needs to be enabled in the config file:
<runtime>
<legacyUnhandledExceptionPolicy enabled="1"/>
</runtime>
Better explanation here: MSDN Reference

Resources