Application crashes without logs

SorinNistorSorinNistor ROMember

I'm building a custom control for Xamarin.Mac using Visual Studio for Mac. The control loads a PDF file and displays it. The control is in the early development stages so it crashes from time to time. The problem is when the control crashes the application window just closes without any exceptions in the log.
The test application has a main window from which (using a button) the second window with the control is opened. It is the second window that just closes when the data is loaded in the control. The 'Application output' window does not display anything (just some Loading assembly ... items).
How can I find why the window closes? Are there some other logs where I can look?

Tagged:

Posts

  • ChrisHamonsChrisHamons USXamarin Team Xamurai

    To explain what you are seeing, let me describe the different classifications of Xamarin.Mac crashes:

    • Native Crash - Someone dereferences null, or seg faults, or something else bad.

      • We're dead, full stop. There is no real recovery here, just like an unmanaged application.
      • Locally, it should popup a crash dialog from macOS with the stack trace.
      • You can find most of these logs in the Console application -> User Reports
      • If you hook up some crash reporting somewhere, it can catch these are report them when they happen on customer machines.
      • Most of the time called by (misusing / threading mistakes ) a Cocoa API. Rarely caused by bugs in the mono runtime itself.
    • Native Exception - Someone throws an NSException

      • We're still pretty much dead. Unlike managed exceptions, NSExceptions are generally not recoverable.
      • You should see things in the Application Output in XS.
      • You should be able to find a log in Console as well.
      • If you run your application from the command line: ./Foo.App/Contents/MacOS/Foo it should be printed there as well
      • You can tweak XM's behavior of NSExceptions via these command line arguments or be notified of them with these events.
      • A vast majority of the time it is caused by misusing Cocoa APIs. Rarely it can be caused by Xamarin.Mac bugs.
    • Managed Exception - Someone throws in C#

      • Unless it "bubbles" out of the managed stacks [1] you can catch and continue on happily
      • A vast majority of these are in your code. Xamarin.Mac will throw a few when it catches programming mistakes (such as calling UI APIs on the non-UI thread).
      • Can be caught in VSfM/XS easily.

    [1] - Example - A click handler is calling your C# code with a stack like this (with made up names):

    [Managed] MyView.HandleClick
    [Native] [NSView doSomeStuff]
    [Native] ...stuff...
    [Native] NApplication runMyEventLoop
    [Managed] NSApplication Main
    [Native] Launcher stuff
    

    If you throw in HandleClick without catching it, then it will "bubble out" of the managed stacks and the behavior you set in https://github.com/xamarin/xamarin-macios/blob/master/tools/common/Driver.cs#L75 will be called. It's generally best to not do that.

  • SorinNistorSorinNistor ROMember

    I went through these links but I still cannot find an explanation for what is happening.
    I managed to reproduce the problem with a simple project that does not include any of my custom code: main window includes a button. When the button is clicked a child window is displayed. The child window includes a button and a textbox. Click on the button and a NSOpenPanel is displayed. Select a file and click Open. The selected file name is displayed in the textbox. When this flow is executed the first time, the child window closes as soon as 'Open' has been clicked in NSOpenPanel. If the child window is opened again, file selection works and the filename is displayed in the textbox. This happens every time I run the application.
    Test project is attached.

  • ChrisHamonsChrisHamons USXamarin Team Xamurai

    The child window is not crashing. I believe your code is just wrong.

    You have:

        partial void OpenNewWindowButtonClick(NSObject sender)
        {
            var storyboard = NSStoryboard.FromName("Main", null);
            var controller = storyboard.InstantiateControllerWithIdentifier("ChildWindow") as NSWindowController;
            controller.ShowWindow(this);
        }
    

    You should have:

    NSWindowController controller;
        partial void OpenNewWindowButtonClick(NSObject sender)
        {
            var storyboard = NSStoryboard.FromName("Main", null);
            controller = storyboard.InstantiateControllerWithIdentifier("ChildWindow") as NSWindowController;
            controller.ShowWindow(this);
        }
    

    In your code, your NSWindowController has zero references after ShowWindow is called, so the GC is fully within it's rights to dispose of it whenever it feels like. It just happens to pick after the nested message loop from the modal dialog fires.

    In my example, we keep a reference, so it does not get disposed.

  • SorinNistorSorinNistor ROMember

    You are correct. Old habits from Windows programming do not work here :)

Sign In or Register to comment.