SIGSEGV annoyance - solved (somewhat)

EricKinoshitaEricKinoshita BRMember ✭✭
edited August 2014 in Xamarin.iOS

Hello,

I'm just writing this as I saw many people suffering with this cryptic (maybe generic?) SIGSEGV error.

I lost two days just trying to track what was producing this kill signal. It traced some Dispose and Drain related functions on stacktrace, but nothing indicating what was wrong with the code. I think it had something to do with the garbage collector.

Just to summarize what I did to fix it. I was suspecting that the error was in a specific ViewController. I commented all its code, and when I ran it the error was gone. Then I uncommented and ran some parts, for some iterations, until I found what was producing that error:

    public override void ViewDidLoad ()
    {
        // … codes here ...
        base.ViewDidLoad ();
        this.View.Add(loadingOverlay); // <- why you no like this line??? 
        // … more codes here ...
    }

Well, the problem was that the loadingOverlay view was never being removed from this.View. So I changed it to something like:

    public override void ViewWillAppear (bool animated)
    {
        // ...
        this.View.Add(loadingOverlay); // add when appears
        // ...
    }

    public override void ViewWillDisappear (bool animated)
    {
        // ...
        loadingOverlay.RemoveFromSuperview(); // remove when disappears
        // ...
    }

I wonder why Xamarin.iOS or Objective-C just kills the app with SIGSEGV (???) without any useful info.

To finish this story, I tried to do many things to overcome that disposal issue, by changing the custom LoadingOverlay class (and without changing the view controller), but I had no success. So I made the following override on the custom component, only to make people aware of the risk of never removing it from its parent:

    public override void RemoveFromSuperview()
    {
        if (this.Superview != null)
        {
            base.RemoveFromSuperview();
        }

        if (!String.IsNullOrEmpty(Environment.StackTrace) && Environment.StackTrace.Contains("monotouch_release_managed_ref"))
        {
            // this SIGSEGV error occurs at least with Mono 3.6.0 + Xamarin.iOS 7.2.6.28
            Mvx.Error("\n" +
                "////////////////////////////////////////////////////////////////////////////////\n" +
                "   LoadingOverlay - RemoveFromSuperview called during garbage collection.\n" +
                "   SIGSEGV will possibly be triggered anytime soon.\n" +
                "   To prevent this error remove the LoadingOverlay object from its superview\n" +
                "   when the ViewController disapears.\n" +
                "   Farewell...\n" +
                "////////////////////////////////////////////////////////////////////////////////");
        }
    }

PS: I tried to post a question two days ago, with stacktrace, symbolicated crash reports, code snippet, but for some reason it didn't get to this forum.

Posts

  • adamkempadamkemp USInsider, Developer Group Leader mod

    You shouldn't have to remove a view from its superview in order to not crash.

    Do you have a Dispose method somewhere that calls RemoveFromSuperview? And are you calling Dispose somewhere in your code?

  • EricKinoshitaEricKinoshita BRMember ✭✭

    You shouldn't have to remove a view from its superview in order to not crash.

    Sorry, I had no choice :P

    Do you have a Dispose method somewhere that calls RemoveFromSuperview?

    No. I tried doing it to fix the SIGSEGV but I saw it got only worse.

    And are you calling Dispose somewhere in your code?

    Not in anything related to UI.

  • adamkempadamkemp USInsider, Developer Group Leader mod

    I suspect that you're doing something wrong. Could you post an example project that reproduces this crash?

  • EricKinoshitaEricKinoshita BRMember ✭✭

    Check the attachment.

  • adamkempadamkemp USInsider, Developer Group Leader mod

    This does feel like a bug to me. It's very similar to this bug:
    https://bugzilla.xamarin.com/show_bug.cgi?id=15316

    I think there are two slightly better workarounds for you. the first would be to just remove the loading view from its superview as soon as it's done loading. You will need to also be sure to remove it if someone tries to go back before it's finished also, but you have multiple things to worry about in that case (like stopping that asynchronous task that's going on in the background). I think this is the best fix because there's no reason to keep an extra view around when it's no longer visible and never will be again. (But maybe in your real app that's not true? I don't know.)

    The second workaround, which seemed to work for me, is to create a custom subclass of UITableView like this:

    [Register("MyTableView")]
    public MyTableView : UITableView
    {
        public MyTableView(IntPtr p ) : base(p) { }
    }
    

    Then in your storyboard go to the ThirdViewController, select the TableView, and change its custom class to "MyTableView". You may have to do this in Xcode because Xamarin's UI Designer kept generating the wrong code for this (it seemed to be trying to make the view controller be named "MyTableView", even though that's a different object).

    Using a custom class changes the way that the GC treats the object, and I think it happens to make these things be torn down in a different order. It may be just dumb luck that this works. I'm not sure. Someone like @RolfBjarneKvinge‌ could probably shed more light on this.

    I suggest that you also attach this example project to the bug report linked above.

  • EricKinoshitaEricKinoshita BRMember ✭✭
    edited August 2014

    But maybe in your real app that's not true?

    Yes, it has the minimum fraction of the real code, and placeholder data. To fix the error I remove the view on ViewDidDisappear (as just there I'm sure it won't be used again).

    I suggest that you also attach this example project to the bug report linked above.

    Doing it right now.

  • sschmidTUsschmidTU Member ✭✭

    In my case, i had an outdated double outlet in my storyboard for a button.
    One of the outlets (CloseButton, CloseAndDontShowAgainButton) refered to an old name of the button.
    It definitely pays to take a look at the storyboard (which is an xml) in a text editor, because XCode can mess up.

Sign In or Register to comment.