xamarin / xamarin-macios

.NET for iOS, Mac Catalyst, macOS, and tvOS provide open-source bindings of the Apple SDKs for use with .NET managed languages such as C#
Other
2.49k stars 515 forks source link

UISearchBar crashes app on touch with UISearchController.SetSearchResultsUpdater #5024

Closed TBulicek closed 6 years ago

TBulicek commented 6 years ago

Steps to Reproduce

  1. var sc = new UISearchController(null);
  2. sc.SetSearchResultsUpdater(...);
  3. assign sc.SearchBar to some View
  4. build, run - sometimes it does not crash in Debug, so run in Release
  5. touch in the SearchBar - app should crash

Expected Behavior

Update action gets invoked on touch.

Actual Behavior

App crashes on touch in UISearchBar.

Additional important info: Only crashes on iOS 12. Similar crash in Bug 24505. App does not crash without "SetSearchResultsUpdater" Working "workaround": sc.SearchBar.TextChanged event handler.

wrapper_managed_to_native_UIKit_UIApplication_UIApplicationMain_int_string___intptr_intptr
NSInvalidArgumentException: -[UIKit_UISearchController___Xamarin_UISearchResultsUpdating updateSearchResultsForSearchController:]: unrecognized selector sent to instance 0x282a66ac0
Last Exception Backtrace

    CoreFoundation
    __exceptionPreprocess
    libobjc.A.dylib
    objc_exception_throw
    CoreFoundation
    -[NSObject(NSObject) doesNotRecognizeSelector:]
    CoreFoundation
    ___forwarding___
    CoreFoundation
    _CF_forwarding_prep_0
    UIKitCore
    -[UISearchController _performAutomaticPresentation]
    UIKitCore
    -[UISearchController _performAutomaticPresentation]
    UIKitCore
    -[UISearchController _searchBarTextDidBeginEditing:]
    UIKitCore
    -[UISearchBar(UISearchBarStatic) _searchFieldBeginEditing]
    UIKitCore
    -[UIApplication sendAction:to:from:forEvent:]
    UIKitCore
    -[UIControl sendAction:to:forEvent:]
    UIKitCore
    -[UIControl _sendActionsForEvents:withEvent:]
    UIKitCore
    -[UITextField _attachFieldEditor]
    UIKitCore
    -[UITextField _becomeFirstResponder]
    UIKitCore
    -[UISearchBarTextField _becomeFirstResponder]
    UIKitCore
    -[UITextField __resumeBecomeFirstResponder]
    UIKitCore
    -[UISearchBarTextField _becomeFirstResponder]
    UIKitCore
    _runAfterCACommitDeferredBlocks
    UIKitCore
    _cleanUpAfterCAFlushAndRunDeferredBlocks
    UIKitCore
    _afterCACommitHandler
    CoreFoundation
    __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
    CoreFoundation
    __CFRunLoopDoObservers
    CoreFoundation
    __CFRunLoopRun
    CoreFoundation
    CFRunLoopRunSpecific
    GraphicsServices
    GSEventRunModal
    UIKitCore
    UIApplicationMain
    WebISClient.IOS
    wrapper_managed_to_native_UIKit_UIApplication_UIApplicationMain_int_string___intptr_intptr
    WebISClient.IOS
    UIApplication.cs:79
    WebISClient.IOS
    UIApplication.cs:63
    WebISClient.IOS
    VykazPrace_IOS_Application_Main_string__ <unknown>:1
    WebISClient.IOS
    wrapper_runtime_invoke_object_runtime_invoke_dynamic_intptr_intptr_intptr_intptr
    WebISClient.IOS
    mono_jit_runtime_invoke mini-runtime.c:2805
    WebISClient.IOS
    mono_runtime_invoke_checked object.c:2922
    WebISClient.IOS
    mono_runtime_exec_main_checked object.c:0
    WebISClient.IOS
    mono_jit_exec driver.g.c:1210
    WebISClient.IOS
    xamarin_main monotouch-main.m:485
    WebISClient.IOS
    main main.m:96
    libdyld.dylib
    start

Environment

=== Visual Studio Community 2017 for Mac ===

Version 7.6.9 (build 22)
Installation UUID: fb39783e-7345-4075-b0eb-748a454faf2b
Runtime:
    Mono 5.12.0.309 (2018-02/39d89a335c8) (64-bit)
    GTK+ 2.24.23 (Raleigh theme)
    Xamarin.Mac 4.4.1.178 (master / eeaeb7e6)

    Package version: 512000309

=== NuGet ===

Version: 4.3.1.4445

=== .NET Core ===

Runtime: /usr/local/share/dotnet/dotnet
Runtime Versions:
    2.1.2
    2.0.5
    2.0.0
SDK: /usr/local/share/dotnet/sdk/2.1.302/Sdks
SDK Versions:
    2.1.302
    2.1.4
    2.0.0
MSBuild SDKs: /Library/Frameworks/Mono.framework/Versions/5.12.0/lib/mono/msbuild/15.0/bin/Sdks

=== Xamarin.Profiler ===

Version: 1.6.3
Location: /Applications/Xamarin Profiler.app/Contents/MacOS/Xamarin Profiler

=== Xamarin.Android ===

Not Installed

=== Apple Developer Tools ===

Xcode 10.0 (14320.25)
Build 10A255

=== Xamarin.Mac ===

Version: 5.0.0.0 (Visual Studio Community)
Hash: b40230c0
Branch: 
Build date: 2018-09-27 11:41:37-0400

=== Xamarin.iOS ===

Version: 12.0.0.15 (Visual Studio Community)
Hash: 84552a46
Branch: xcode10
Build date: 2018-09-17 21:54:33-0400

=== Xamarin Inspector ===

Version: 1.4.3
Hash: db27525
Branch: 1.4-release
Build date: Mon, 09 Jul 2018 21:20:18 GMT
Client compatibility: 1

=== Build Information ===

Release ID: 706090022
Git revision: 0a0ba3c4593e9adb1c6ff6324e641036146af376
Build date: 2018-10-05 16:38:51+00
Build branch: release-7.6
Xamarin extensions: f7856b13f2c03a58e08381d3a5970bba18f5c7d7

=== Operating System ===

Mac OS X 10.13.6
Darwin 17.7.0 Darwin Kernel Version 17.7.0
    Thu Jun 21 22:53:14 PDT 2018
    root:xnu-4570.71.2~1/RELEASE_X86_64 x86_64

Build Logs

buildLog.txt

Example Project (If Possible)

SearchBarTest.zip

spouliot commented 6 years ago

Thanks for providing a sample. I can duplicate the issue on a device in release mode.

From console

default 09:37:15.755336 -0400   SearchBarTest   Call host has no calls
default 09:37:15.759183 -0400   SearchBarTest   -[UIKit_UISearchController___Xamarin_UISearchResultsUpdating updateSearchResultsForSearchController:]: unrecognized selector sent to instance 0x281b26ac0
default 09:37:15.759264 -0400   SearchBarTest   
Unhandled Exception:
Foundation.MonoTouchException: Objective-C exception thrown.  Name: NSInvalidArgumentException Reason: -[UIKit_UISearchController___Xamarin_UISearchResultsUpdating updateSearchResultsForSearchController:]: unrecognized selector sent to instance 0x281b26ac0

and Symbolicated crash report

Note that iOS version specific issues (things that only happens in some iOS version) are often bugs inside iOS itself for which there's not much we can do.

spouliot commented 6 years ago

It does seems to be an issue on our side. I'll have to see why it works with older iOS versions...

spouliot commented 6 years ago

So we're not preserving a method that is called (from iOS / native) at runtime.

Workaround: Change

-    public partial class ViewController : UITableViewController
+    public partial class ViewController : UITableViewController, IUISearchResultsUpdating

and add

public void UpdateSearchResultsForSearchController (UISearchController searchController)
{
    throw new NotImplementedException ();
}

to your project. That will hint the linker that UpdateSearchResultsForSearchController and the related selector needs to be preserved.

Still unsure why it would work before iOS 12 (I'll test that in parallel with my fix).

spouliot commented 6 years ago

I get the same crash on iOS 9.3.5 so I'll assume it's not related to the iOS version but is the issue I identified earlier. It's possible that, in a larger application (not the test case) something else makes the linker preserve the method/selector so it does not show up.