forked from dotnet/android
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit 7ec2d9f
committed
[runtime] Fix segfault when accessing MonoImage in certain cases
Context: 7117414
7117414 introduced native code which queries
the Mono runtime to obtain an instance of `MonoClass` for a given
`MonoReflectionType` as well as the `MonoImage` associated with the
class. However, it appears that in certain cases the class pointer
stored `MonoReflectionType` doesn't lead us to getting a valid
`MonoImage` instance, causing a segfault similar to:
04-08 15:52:55.015 19030 19030 F libc : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x3000021 in tid 19030 (s.swipeviewdemo), pid 19030 (s.swipeviewdemo)
04-08 15:52:55.037 19061 19061 I crash_dump32: obtaining output fd from tombstoned, type: kDebuggerdTombstone
04-08 15:52:55.037 1834 1834 I /system/bin/tombstoned: received crash request for pid 19030
04-08 15:52:55.038 19061 19061 I crash_dump32: performing dump of process 19030 (target tid = 19030)
04-08 15:52:55.042 19061 19061 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
04-08 15:52:55.042 19061 19061 F DEBUG : Build fingerprint: 'google/sdk_gphone_x86/generic_x86:10/QSR1.191030.002/5978551:userdebug/dev-keys'
04-08 15:52:55.043 19061 19061 F DEBUG : Revision: '0'
04-08 15:52:55.043 19061 19061 F DEBUG : ABI: 'x86'
04-08 15:52:55.043 19061 19061 F DEBUG : Timestamp: 2020-04-08 15:52:55+0200
04-08 15:52:55.043 19061 19061 F DEBUG : pid: 19030, tid: 19030, name: s.swipeviewdemo >>> nl.versluis.swipeviewdemo <<<
04-08 15:52:55.043 19061 19061 F DEBUG : uid: 10135
04-08 15:52:55.043 19061 19061 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x3000021
04-08 15:52:55.043 19061 19061 F DEBUG : eax 03000005 ebx cb9f4d24 ecx 7191c13b edx 00000004
04-08 15:52:55.043 19061 19061 F DEBUG : edi 03000005 esi ffb22080
04-08 15:52:55.043 19061 19061 F DEBUG : ebp ffb22108 esp ffb2206c eip cbcfc1e4
04-08 15:52:55.077 19061 19061 F DEBUG :
04-08 15:52:55.077 19061 19061 F DEBUG : backtrace:
04-08 15:52:55.077 19061 19061 F DEBUG : #00 pc 001b41e4 /data/app/Mono.Android.DebugRuntime-umHhDz421s4-tshrHwha0w==/lib/x86/libmonosgen-32bit-2.0.so (mono_image_get_name+4)
04-08 15:52:55.077 19061 19061 F DEBUG : #1 pc 0000cac7 /data/app/nl.versluis.swipeviewdemo-jCFH_bcCNuFx1tLUhaJ4nw==/lib/x86/libmonodroid.so (xamarin::android::internal::EmbeddedAssemblies::typemap_managed_to_java(_MonoType*, _MonoClass*, unsigned char const*)+263) (BuildId: a2585ad379f788049e463af58c8686e9cdc1e778)
04-08 15:52:55.077 19061 19061 F DEBUG : #2 pc 0000c8cc /data/app/nl.versluis.swipeviewdemo-jCFH_bcCNuFx1tLUhaJ4nw==/lib/x86/libmonodroid.so (xamarin::android::internal::EmbeddedAssemblies::typemap_managed_to_java(_MonoReflectionType*, unsigned char const*)+124) (BuildId: a2585ad379f788049e463af58c8686e9cdc1e778)
04-08 15:52:55.077 19061 19061 F DEBUG : #3 pc 0001621a /data/app/nl.versluis.swipeviewdemo-jCFH_bcCNuFx1tLUhaJ4nw==/lib/x86/libmonodroid.so (xamarin::android::internal::MonodroidRuntime::typemap_managed_to_java(_MonoReflectionType*, unsigned char const*)+42) (BuildId: a2585ad379f788049e463af58c8686e9cdc1e778)
04-08 15:52:55.077 19061 19061 F DEBUG : dotnet#4 pc 000325af <anonymous:c7858000>
Investigating the issue I discovered that one of two things happened:
1. the returned `MonoImage` instance was invalid, or
2. the instance was valid but image name stored in `MonoImage` was
`null`
In case of 1. I would see something similar to this in the crash log:
04-08 15:52:55.015 19030 19030 I monodroid: const char *xamarin::android::internal::EmbeddedAssemblies::typemap_managed_to_java(MonoType *, MonoClass *, const uint8_t *)
04-08 15:52:55.015 19030 19030 I monodroid: type == 0xc6e60d3c, klass == 0xc6e60cb8, mvid == 0xc8c02d90
04-08 15:52:55.015 19030 19030 I monodroid: type name == Xamarin.Forms.Platform.Android.AppCompat.FormsFragmentPagerAdapter`1[Xamarin.Forms.Page]
04-08 15:52:55.015 19030 19030 I monodroid: calling mono_class_get_image (0xc6e60cb8)
04-08 15:52:55.015 19030 19030 I monodroid: image == 0x3000005
It would happen in 32-bit builds only, the 64-bit builds would lead to a
different issue, the 2. above:
04-08 16:05:13.446 28985 28985 I monodroid: const char *xamarin::android::internal::EmbeddedAssemblies::typemap_managed_to_java(MonoType *, MonoClass *, const uint8_t *)
04-08 16:05:13.447 28985 28985 I monodroid: type == 0x7ce3fecc78, klass == 0x7ce3fecb98, mvid == 0x7ce9404520
04-08 16:05:13.447 28985 28985 I monodroid: type name == Xamarin.Forms.Platform.Android.AppCompat.FormsFragmentPagerAdapter`1[Xamarin.Forms.Page]
04-08 16:05:13.447 28985 28985 I monodroid: calling mono_class_get_image (0x7ce3fecb98)
04-08 16:05:13.447 28985 28985 I monodroid: image == 0x7ce3fecbc8
04-08 16:05:13.447 28985 28985 I monodroid: image_name == <null>
Case 1. would result in a segfault inside the `mono_image_get_name`
call, because the pointer value was clearly invalid, while case 2. would
result in a crash inside `strlen` which was passed a `null` pointer.
I found out that the root cause was in the `mono_type_get_class` call
which is supposed to be used with great caution as it eventually calls
the `mono_type_get_class_internal` function which is supposed to be
called only for object types `MONO_TYPE_CLASS` and `MONO_TYPE_VALUETYPE`
but not `MONO_TYPE_GENERICINST` type which is precisely the type that
caused the crash. The fix is to call the `mono_class_from_mono_type`
function instead which, albeit slower, is safer and works correctly in
all cases.
Fixing this led to the next issue, a managed exception thrown after the
runtime failed to map managed type name to Java type name:
04-08 18:08:58.886 30726 30726 W monodroid-assembly: typemap: unable to find mapping to a Java type from managed type 'Xamarin.Forms.Platform.Android.AppCompat.FormsFragmentPagerAdapter`1[T], Xamarin.Forms.Platform.Android'
04-08 18:08:58.886 30726 30726 I monodroid-timing: Typemap.managed_to_java: end, total time; elapsed: 0s:0::33177
04-08 18:08:58.888 30726 30726 D Mono : DllImport attempting to load: '/system/lib64/liblog.so'.
04-08 18:08:58.889 30726 30726 D Mono : DllImport loaded library '/system/lib64/liblog.so'.
04-08 18:08:58.889 30726 30726 D Mono : DllImport searching in: '/system/lib64/liblog.so' ('/system/lib64/liblog.so').
04-08 18:08:58.889 30726 30726 D Mono : Searching for '__android_log_print'.
04-08 18:08:58.889 30726 30726 D Mono : Probing '__android_log_print'.
04-08 18:08:58.889 30726 30726 D Mono : Found as '__android_log_print'.
04-08 18:08:58.891 30726 30726 I MonoDroid: UNHANDLED EXCEPTION:
04-08 18:08:58.899 30726 30726 I MonoDroid: System.NotSupportedException: Cannot create instance of type 'Xamarin.Forms.Platform.Android.AppCompat.FormsFragmentPagerAdapter`1[[Xamarin.Forms.Page, Xamarin.Forms.Core, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null]]': no Java peer type found.
04-08 18:08:58.899 30726 30726 I MonoDroid: at Java.Interop.JniPeerMembers+JniInstanceMethods..ctor (System.Type declaringType) [0x0004b] in <514e1249792e47a180b3f1293306b972>:0
04-08 18:08:58.899 30726 30726 I MonoDroid: at Java.Interop.JniPeerMembers+JniInstanceMethods.GetConstructorsForType (System.Type declaringType) [0x00031] in <514e1249792e47a180b3f1293306b972>:0
04-08 18:08:58.899 30726 30726 I MonoDroid: at Java.Interop.JniPeerMembers+JniInstanceMethods.StartCreateInstance (System.String constructorSignature, System.Type declaringType, Java.Interop.JniArgumentValue* parameters) [0x00038] in <514e1249792e47a180b3f1293306b972>:0
04-08 18:08:58.899 30726 30726 I MonoDroid: at Android.Support.V4.App.FragmentPagerAdapter..ctor (Android.Support.V4.App.FragmentManager fm) [0x0005b] in <fefee6c2c695459088a9df092723e052>:0
04-08 18:08:58.899 30726 30726 I MonoDroid: at Xamarin.Forms.Platform.Android.AppCompat.FormsFragmentPagerAdapter`1[T]..ctor (Xamarin.Forms.MultiPage`1[T] page, Android.Support.V4.App.FragmentManager fragmentManager) [0x00000] in <9d12bb15abb54c508c4bee636d1b3a42>:0
04-08 18:08:58.899 30726 30726 I MonoDroid: at Xamarin.Forms.Platform.Android.AppCompat.TabbedPageRenderer.CreateFormsViewPager (Android.Content.Context context, Xamarin.Forms.TabbedPage tabbedPage) [0x00033] in <9d12bb15abb54c508c4bee636d1b3a42>:0
04-08 18:08:58.899 30726 30726 I MonoDroid: at Xamarin.Forms.Platform.Android.AppCompat.TabbedPageRenderer.OnElementChanged (Xamarin.Forms.Platform.Android.ElementChangedEventArgs`1[TElement] e) [0x001cd] in <9d12bb15abb54c508c4bee636d1b3a42>:0
04-08 18:08:58.899 30726 30726 I MonoDroid: at Xamarin.Forms.Platform.Android.VisualElementRenderer`1[TElement].SetElement (TElement element) [0x000c0] in <9d12bb15abb54c508c4bee636d1b3a42>:0
04-08 18:08:58.899 30726 30726 I MonoDroid: at Xamarin.Forms.Platform.Android.VisualElementRenderer`1[TElement].Xamarin.Forms.Platform.Android.IVisualElementRenderer.SetElement (Xamarin.Forms.VisualElement element) [0x00033] in <9d12bb15abb54c508c4bee636d1b3a42>:0
04-08 18:08:58.899 30726 30726 I MonoDroid: at Xamarin.Forms.Platform.Android.Platform.CreateRenderer (Xamarin.Forms.VisualElement element, Android.Content.Context context) [0x0001f] in <9d12bb15abb54c508c4bee636d1b3a42>:0
04-08 18:08:58.899 30726 30726 I MonoDroid: at Xamarin.Forms.Platform.Android.AppCompat.Platform.AddChild (Xamarin.Forms.Page page, System.Boolean layout) [0x0000d] in <9d12bb15abb54c508c4bee636d1b3a42>:0
04-08 18:08:58.899 30726 30726 I MonoDroid: at Xamarin.Forms.Platform.Android.AppCompat.Platform.SetPageInternal (Xamarin.Forms.Page newRoot) [0x00061] in <9d12bb15abb54c508c4bee636d1b3a42>:0
04-08 18:08:58.899 30726 30726 I MonoDroid: at Xamarin.Forms.Platform.Android.AppCompat.Platform.SetPage (Xamarin.Forms.Page newRoot) [0x000e6] in <9d12bb15abb54c508c4bee636d1b3a42>:0
04-08 18:08:58.899 30726 30726 I MonoDroid: at Xamarin.Forms.Platform.Android.FormsAppCompatActivity.InternalSetPage (Xamarin.Forms.Page page) [0x0003f] in <9d12bb15abb54c508c4bee636d1b3a42>:0
04-08 18:08:58.899 30726 30726 I MonoDroid: at Xamarin.Forms.Platform.Android.FormsAppCompatActivity.SetMainPage () [0x0000c] in <9d12bb15abb54c508c4bee636d1b3a42>:0
04-08 18:08:58.899 30726 30726 I MonoDroid: at Xamarin.Forms.Platform.Android.FormsAppCompatActivity.LoadApplication (Xamarin.Forms.Application application) [0x00140] in <9d12bb15abb54c508c4bee636d1b3a42>:0
04-08 18:08:58.899 30726 30726 I MonoDroid: at SwipeViewDemo.Droid.MainActivity.OnCreate (Android.OS.Bundle savedInstanceState) [0x00035] in <15e30af50bb64ff6b6d20ac6fd546763>:0
04-08 18:08:58.899 30726 30726 I MonoDroid: at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_savedInstanceState) [0x0000f] in <515e813169e54876823978ab785f569a>:0
04-08 18:08:58.899 30726 30726 I MonoDroid: at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.7(intptr,intptr,intptr)
Note that the type name as seen by the native code (via
`mono_get_type_name_full`) is
`Xamarin.Forms.Platform.Android.AppCompat.FormsFragmentPagerAdapter`1[T],
Xamarin.Forms.Platform.Android` while we should be looking for
`Xamarin.Forms.Platform.Android.AppCompat.FormsFragmentPagerAdapter`1`
instead. The discrepancy was caused by calling
`mono_get_type_name_full` with its format parameter set to
`MONO_TYPE_NAME_FORMAT_REFLECTION`, while what we needed to do is to
pass it the format value of `MONO_TYPE_NAME_FORMAT_FULL_NAME` which this
commit implements.1 parent 889820b commit 7ec2d9fCopy full SHA for 7ec2d9f
File tree
Expand file treeCollapse file tree
1 file changed
+2
-2
lines changedFilter options
- src/monodroid/jni
Expand file treeCollapse file tree
1 file changed
+2
-2
lines changedsrc/monodroid/jni/embedded-assemblies.cc
Copy file name to clipboardExpand all lines: src/monodroid/jni/embedded-assemblies.cc+2-2Lines changed: 2 additions & 2 deletions
Original file line number | Diff line number | Diff line change | |
---|---|---|---|
| |||
345 | 345 |
| |
346 | 346 |
| |
347 | 347 |
| |
348 |
| - | |
| 348 | + | |
349 | 349 |
| |
350 | 350 |
| |
351 | 351 |
| |
| |||
490 | 490 |
| |
491 | 491 |
| |
492 | 492 |
| |
493 |
| - | |
| 493 | + | |
494 | 494 |
| |
495 | 495 |
| |
496 | 496 |
| |
|
0 commit comments