Xamarin-android: new() constraint and XElement doesn't work in Release mode

Created on 13 Jun 2020  路  13Comments  路  Source: xamarin/xamarin-android

I have found that when I try to use an XElement and a generic method with the new() constraint, the app terminates immediately in Release Mode

Not sure if this is an issue with Xamarin or what, but it has suddenly started giving me issues. Took me a while to track it down, but I can recreate the issues in these steps. Only crashes in release mode. Linking set to None does not fix the issue.

I've attached a demo project to reproduce
BreakingStuff.zip

Steps to Reproduce

  1. Create a new Android App
  2. Add references to System.Xml and System.Xml.Linq
  3. Create a generic method that takes in an XElement and has "where T : new()" as a constraint
  4. Call the method

Here's the code in the project I'm testing with

protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            Xamarin.Essentials.Platform.Init(this, savedInstanceState);

            XElement element = new XElement("Test");

            Log.WriteLine(LogPriority.Info, "TestApp", "About to call method");
            bool testBool = GetT<bool>(element, "TestBool");
            Log.WriteLine(LogPriority.Info, "TestApp", "method called");

            if (testBool == true)
            {
                return;
            }

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.activity_main);
        }

public T GetT<T>(XElement element, string attributeName) where T : new()
        {
            XAttribute xAttribute = element.Attribute(attributeName);

            if(xAttribute == null)
            {
                return new T();
            }

            return (T)Convert.ChangeType(xAttribute.Value, typeof(T), CultureInfo.InvariantCulture);
        }

Expected Behavior

The app runs in both Debug and Release mode

Actual Behavior

The app runs in Debug but in Release the app terminates unexpectedly, posts this in Logcat

Time Device Name Type PID Tag Message
06-13 14:53:33.886 Google Pixel 4 Error 14108 libc Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 14108 (anyname.testapp), pid 14108 (anyname.testapp)
06-13 14:53:33.886 Google Pixel 4 Info 14108 TestApp About to call method
06-13 14:53:33.751 Google Pixel 4 Warning 14108 monodroid Using runtime path: /data/app/com.companyname.testapp-rBJpyUGXti3LzAT4EXQu7Q==/lib/arm64
06-13 14:53:33.705 Google Pixel 4 Info 1341 ActivityManager Start proc 14108:com.companyname.testapp/u0a245 for activity {com.companyname.testapp/crc640aad9a0ab5a3b676.MainActivity}
06-13 14:53:33.666 Google Pixel 4 Info 1341 ActivityTaskManager START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.companyname.testapp/crc640aad9a0ab5a3b676.MainActivity} from uid 2000

Version Information

Visual Studio Community 2019
Version 16.6.2
image

Mono Runtime

All 13 comments

This appears to be an issue with the Mono JIT:

06-16 10:05:01.703 10808 10808 I TestApp : About to call method
06-16 10:05:01.704 10808 10808 F         : * Assertion at /mnt/jenkins/workspace/archive-mono/2020-02/android/debug/mono/mini/method-to-ir.c:12332, condition `var->opcode == OP_REGOFFSET' not met
06-16 10:05:01.712  1910  1910 I WallpaperService: engine paused
--------- beginning of crash
06-16 10:05:01.718 10808 10808 F libc    : Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 10808 (anyname.testapp), pid 10808 (anyname.testapp)
06-16 10:05:01.727   667   667 E Layer   : [Surface(name=AppWindowToken{82aa8f7 token=Token{ae60cf6 ActivityRecord{8e69591 u0 com.companyname.testapp/crc640aad9a0ab5a3b676.MainActivity t3064}}})/@0xaa1bde7 - animation-leash#0] No local sync point found
06-16 10:05:01.727   667   667 I chatty  : uid=1000(system) /system/bin/surfaceflinger identical 1 line
06-16 10:05:01.727   667   667 E Layer   : [Surface(name=AppWindowToken{82aa8f7 token=Token{ae60cf6 ActivityRecord{8e69591 u0 com.companyname.testapp/crc640aad9a0ab5a3b676.MainActivity t3064}}})/@0xaa1bde7 - animation-leash#0] No local sync point found
06-16 10:05:01.727   667   667 E Layer   : [Surface(name=AppWindowToken{76543f6 token=Token{d944891 ActivityRecord{55e62b8 u0 com.google.android.apps.nexuslauncher/.NexusLauncherActivity t3062}}})/@0xcaa9c17 - animation-leash#0] No local sync point found
06-16 10:05:01.727   667   667 I chatty  : uid=1000(system) /system/bin/surfaceflinger identical 1 line
06-16 10:05:01.727   667   667 E Layer   : [Surface(name=AppWindowToken{76543f6 token=Token{d944891 ActivityRecord{55e62b8 u0 com.google.android.apps.nexuslauncher/.NexusLauncherActivity t3062}}})/@0xcaa9c17 - animation-leash#0] No local sync point found
06-16 10:05:01.758 10835 10835 I crash_dump64: obtaining output fd from tombstoned, type: kDebuggerdTombstone
06-16 10:05:01.759  1031  1031 I /system/bin/tombstoned: received crash request for pid 10808
06-16 10:05:01.761 10835 10835 I crash_dump64: performing dump of process 10808 (target tid = 10808)
06-16 10:05:01.766 10835 10835 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
06-16 10:05:01.767 10835 10835 F DEBUG   : Build fingerprint: 'google/crosshatch/crosshatch:10/QQ3A.200605.001/6392402:user/release-keys'
06-16 10:05:01.767 10835 10835 F DEBUG   : Revision: 'MP1.0'
06-16 10:05:01.767 10835 10835 F DEBUG   : ABI: 'arm64'
06-16 10:05:01.767 10835 10835 F DEBUG   : Timestamp: 2020-06-16 10:05:01+0200
06-16 10:05:01.767 10835 10835 F DEBUG   : pid: 10808, tid: 10808, name: anyname.testapp  >>> com.companyname.testapp <<<
06-16 10:05:01.767 10835 10835 F DEBUG   : uid: 10087
06-16 10:05:01.767 10835 10835 F DEBUG   : signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
06-16 10:05:01.767 10835 10835 F DEBUG   : Abort message: '* Assertion at /mnt/jenkins/workspace/archive-mono/2020-02/android/debug/mono/mini/method-to-ir.c:12332, condition `var->opcode == OP_REGOFFSET' not met
06-16 10:05:01.767 10835 10835 F DEBUG   : '
06-16 10:05:01.767 10835 10835 F DEBUG   :     x0  0000000000000000  x1  0000000000002a38  x2  0000000000000006  x3  0000007fdc83dbb0
06-16 10:05:01.767 10835 10835 F DEBUG   :     x4  0080000000000000  x5  0080000000000000  x6  0080000000000000  x7  0000000000008000
06-16 10:05:01.767 10835 10835 F DEBUG   :     x8  00000000000000f0  x9  f745f7175be18005  x10 0000000000000001  x11 0000000000000000
06-16 10:05:01.767 10835 10835 F DEBUG   :     x12 fffffff0fffffbdf  x13 0000000000000030  x14 ffffffffffffffff  x15 0029b9b212abde84
06-16 10:05:01.767 10835 10835 F DEBUG   :     x16 0000007ab9e228c0  x17 0000007ab9e000c0  x18 00000079d33af762  x19 0000000000002a38
06-16 10:05:01.767 10835 10835 F DEBUG   :     x20 0000000000002a38  x21 00000000ffffffff  x22 0000000000000001  x23 0000000000000000
06-16 10:05:01.767 10835 10835 F DEBUG   :     x24 0000004000000010  x25 0000000000000010  x26 00000079d3465868  x27 00000079d3465768
06-16 10:05:01.767 10835 10835 F DEBUG   :     x28 00000079d3465870  x29 0000007fdc83dc50
06-16 10:05:01.767 10835 10835 F DEBUG   :     sp  0000007fdc83db90  lr  0000007ab9db4f48  pc  0000007ab9db4f74
06-16 10:05:01.770 10835 10835 F DEBUG   : 
06-16 10:05:01.770 10835 10835 F DEBUG   : backtrace:
06-16 10:05:01.770 10835 10835 F DEBUG   :       #00 pc 0000000000081f74  /apex/com.android.runtime/lib64/bionic/libc.so (abort+160) (BuildId: 8de865099c99977483c8947f9b7937e9)
06-16 10:05:01.770 10835 10835 F DEBUG   :       #01 pc 0000000000506ec8  /data/app/com.companyname.testapp-avSiG-Eap2Vaelxx3m0xkA==/lib/arm64/libmonosgen-2.0.so (monoeg_assert_abort+64)

Reproduced using the current tip of Xamarin.Android/master (xamarin/xamarin-android@9380073bfddd6e60f2fab52b588a645e2a1c4c87)

Could somebody extract a non-xam.android testcase from the current testcase ?

@vargaz here you are:

Mono (Linux): Mono JIT compiler version 6.13.0 (master/d2da9004266 Fri 22 May 16:12:11 CEST 2020)

using System;
using System.Globalization;
using System.Xml.Linq;

class test
{
    public T GetT<T> (XElement element, string attributeName) where T : new()
    {
        XAttribute xAttribute = element.Attribute (attributeName);

        if(xAttribute == null) {
            return new T();
        }

        return (T)Convert.ChangeType (xAttribute.Value, typeof(T), CultureInfo.InvariantCulture);
    }

    void Run ()
    {
        XElement element = new XElement ("Test");

        Console.WriteLine ("About to call method");
        bool testBool = GetT<bool>(element, "TestBool");
        Console.WriteLine ("method called");
    }

    static void Main ()
    {
        var t = new test ();
        t.Run ();
    }
}

And the crash I got:

About to call method
* Assertion at method-to-ir.c:12494, condition `var->opcode == OP_REGOFFSET' not met


=================================================================
    Native Crash Reporting
=================================================================
Got a SIGABRT while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries 
used by your application.
=================================================================

=================================================================
    Native stacktrace:
=================================================================
    0x55af27c1457b - mono : 
    0x55af27c1492d - mono : 
    0x55af27bc0e66 - mono : 
    0x55af27c13ac4 - mono : 
    0x7effc5347110 - /lib/x86_64-linux-gnu/libpthread.so.0 : 
    0x7effc518f781 - /lib/x86_64-linux-gnu/libc.so.6 : gsignal
    0x7effc517955b - /lib/x86_64-linux-gnu/libc.so.6 : abort
    0x55af27b7c42b - mono : 
    0x55af27e72785 - mono : 
    0x55af27e90c2e - mono : 
    0x55af27e9132b - mono : monoeg_assertion_message
    0x55af27e91370 - mono : mono_assertion_message_disabled
    0x55af27c58a58 - mono : 
    0x55af27c1aa21 - mono : 
    0x55af27c1bca6 - mono : 
    0x55af27b85442 - mono : 
    0x55af27bc47c6 - mono : 
    0x55af27bc5323 - mono : 
    0x40f02396 - Unknown

=================================================================
    Telemetry Dumper:
=================================================================
Pkilling 0x139636981462784x from 0x139636988254080x
Entering thread summarizer pause from 0x139636988254080x
Finished thread summarizer pause from 0x139636988254080x.
Failed to create breadcrumb file (null)/crash_hash_0xb9faadd8

Waiting for dumping threads to resume

=================================================================
    External Debugger Dump:
=================================================================
[New LWP 30296]
[New LWP 30297]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
0x00007effc5346a5e in __waitpid (pid=pid@entry=30299, stat_loc=stat_loc@entry=0x7fff56e891d4, options=options@entry=0) at ../sysdeps/unix/sysv/linux/waitpid.c:30
30  ../sysdeps/unix/sysv/linux/waitpid.c: No such file or directory.
  Id   Target Id                                       Frame 
* 1    Thread 0x7effc5151780 (LWP 30295) "mono"        0x00007effc5346a5e in __waitpid (pid=pid@entry=30299, stat_loc=stat_loc@entry=0x7fff56e891d4, options=options@entry=0) at ../sysdeps/unix/sysv/linux/waitpid.c:30
  2    Thread 0x7effc43ff700 (LWP 30296) "SGen worker" futex_wait_cancelable (private=0, expected=0, futex_word=0x55af28011028 <work_cond+40>) at ../sysdeps/unix/sysv/linux/futex-internal.h:80
  3    Thread 0x7effc4ad7700 (LWP 30297) "Finalizer"   futex_abstimed_wait_cancelable (private=0, abstime=0x0, clockid=0, expected=0, futex_word=0x55af280022e0 <finalizer_sem>) at ../sysdeps/unix/sysv/linux/futex-internal.h:208

Thread 3 (Thread 0x7effc4ad7700 (LWP 30297)):
#0  futex_abstimed_wait_cancelable (private=0, abstime=0x0, clockid=0, expected=0, futex_word=0x55af280022e0 <finalizer_sem>) at ../sysdeps/unix/sysv/linux/futex-internal.h:208
#1  do_futex_wait (sem=sem@entry=0x55af280022e0 <finalizer_sem>, abstime=0x0, clockid=0) at sem_waitcommon.c:112
#2  0x00007effc5345098 in __new_sem_wait_slow (sem=sem@entry=0x55af280022e0 <finalizer_sem>, abstime=0x0, clockid=0) at sem_waitcommon.c:184
#3  0x00007effc5345111 in __new_sem_wait (sem=sem@entry=0x55af280022e0 <finalizer_sem>) at sem_wait.c:42
#4  0x000055af27e0a908 in mono_os_sem_wait (flags=MONO_SEM_FLAGS_ALERTABLE, sem=0x55af280022e0 <finalizer_sem>) at ../../mono/utils/mono-os-semaphore.h:203
#5  mono_coop_sem_wait (flags=MONO_SEM_FLAGS_ALERTABLE, sem=0x55af280022e0 <finalizer_sem>) at ../../mono/utils/mono-coop-semaphore.h:41
#6  finalizer_thread (unused=unused@entry=0x0) at gc.c:970
#7  0x000055af27dc5e0e in start_wrapper_internal (stack_ptr=0x7effc4ad8000, start_info=0x0) at threads.c:1229
#8  start_wrapper (data=0x55af2821b4a0) at threads.c:1304
#9  0x00007effc533bf27 in start_thread (arg=<optimized out>) at pthread_create.c:479
#10 0x00007effc525131f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 2 (Thread 0x7effc43ff700 (LWP 30296)):
#0  futex_wait_cancelable (private=0, expected=0, futex_word=0x55af28011028 <work_cond+40>) at ../sysdeps/unix/sysv/linux/futex-internal.h:80
#1  __pthread_cond_wait_common (abstime=0x0, clockid=0, mutex=0x55af28011040 <lock>, cond=0x55af28011000 <work_cond>) at pthread_cond_wait.c:508
#2  __pthread_cond_wait (cond=cond@entry=0x55af28011000 <work_cond>, mutex=mutex@entry=0x55af28011040 <lock>) at pthread_cond_wait.c:638
#3  0x000055af27e69e33 in mono_os_cond_wait (mutex=0x55af28011040 <lock>, cond=0x55af28011000 <work_cond>) at ../../mono/utils/mono-os-mutex.h:219
#4  get_work (job=<synthetic pointer>, do_idle=<synthetic pointer>, work_context=<synthetic pointer>, worker_index=0) at sgen-thread-pool.c:165
#5  thread_func (data=<optimized out>) at sgen-thread-pool.c:196
#6  0x00007effc533bf27 in start_thread (arg=<optimized out>) at pthread_create.c:479
#7  0x00007effc525131f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Thread 1 (Thread 0x7effc5151780 (LWP 30295)):
#0  0x00007effc5346a5e in __waitpid (pid=pid@entry=30299, stat_loc=stat_loc@entry=0x7fff56e891d4, options=options@entry=0) at ../sysdeps/unix/sysv/linux/waitpid.c:30
#1  0x000055af27c147fa in dump_native_stacktrace (signal=signal@entry=0x55af27ebe7f5 "SIGABRT", mctx=mctx@entry=0x7fff56e89d40) at mini-posix.c:1061
#2  0x000055af27c1492d in mono_dump_native_crash_info (signal=signal@entry=0x55af27ebe7f5 "SIGABRT", mctx=mctx@entry=0x7fff56e89d40, info=info@entry=0x7fff56e8a030) at mini-posix.c:1105
#3  0x000055af27bc0e66 in mono_handle_native_crash (signal=0x55af27ebe7f5 "SIGABRT", mctx=mctx@entry=0x7fff56e89d40, info=info@entry=0x7fff56e8a030) at mini-exceptions.c:3442
#4  0x000055af27c13ac4 in sigabrt_signal_handler (_dummy=<optimized out>, _info=0x7fff56e8a030, context=0x7fff56e89f00) at mini-posix.c:235
#5  <signal handler called>
#6  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#7  0x00007effc517955b in __GI_abort () at abort.c:79
#8  0x000055af27b7c42b in monoeg_assert_abort () at goutput.c:57
#9  0x000055af27e72785 in mono_log_write_logfile (log_domain=<optimized out>, level=<optimized out>, hdr=<optimized out>, message=0x55af2829dff0 "* Assertion at method-to-ir.c:12494, condition `var->opcode == OP_REGOFFSET' not met\n") at mono-log-common.c:136
#10 0x000055af27e90c2e in monoeg_g_logstr (msg=<optimized out>, log_level=G_LOG_LEVEL_ERROR, log_domain=0x0) at goutput.c:151
#11 monoeg_g_logv_nofree (log_domain=log_domain@entry=0x0, log_level=log_level@entry=G_LOG_LEVEL_ERROR, format=format@entry=0x55af27f715f8 "* Assertion at %s:%d, condition `%s' not met\n", args=args@entry=0x7fff56e8a800) at goutput.c:166
#12 0x000055af27e9132b in monoeg_g_logv_nofree (args=0x7fff56e8a800, format=0x55af27f715f8 "* Assertion at %s:%d, condition `%s' not met\n", log_level=G_LOG_LEVEL_ERROR, log_domain=0x0) at goutput.c:201
#13 monoeg_assertion_message (format=format@entry=0x55af27f715f8 "* Assertion at %s:%d, condition `%s' not met\n") at goutput.c:201
#14 0x000055af27e91370 in mono_assertion_message (file=file@entry=0x55af27ebfaf4 "method-to-ir.c", line=line@entry=12494, condition=condition@entry=0x55af27eb9db7 "var->opcode == OP_REGOFFSET") at goutput.c:220
#15 0x000055af27c58a58 in mono_spill_global_vars (cfg=cfg@entry=0x55af28329230, need_local_opts=need_local_opts@entry=0x7fff56e8ac7c) at method-to-ir.c:11963
#16 0x000055af27c1aa21 in mini_method_compile (method=<optimized out>, opts=<optimized out>, domain=<optimized out>, flags=<optimized out>, parts=<optimized out>, aot_method_index=<optimized out>) at mini.c:3815
#17 0x000055af27c1bca6 in mono_jit_compile_method_inner (method=method@entry=0x55af2823fa00, target_domain=target_domain@entry=0x55af281dc1f0, opt=opt@entry=374434303, error=error@entry=0x7fff56e8af20) at mini.c:4062
#18 0x000055af27b85442 in mono_jit_compile_method_with_opt (method=method@entry=0x55af2823fa00, opt=<optimized out>, jit_only=jit_only@entry=0, error=error@entry=0x7fff56e8af20) at mini-runtime.c:2642
#19 0x000055af27b864e4 in mono_jit_compile_method (method=method@entry=0x55af2823fa00, error=error@entry=0x7fff56e8af20) at mini-runtime.c:2692
#20 0x000055af27bc47c6 in common_call_trampoline (regs=regs@entry=0x7fff56e8afe8, code=code@entry=0x4138d214 "H\277\060\301\262\304\377~", m=m@entry=0x55af2823fa00, vt=vt@entry=0x0, vtable_slot=<optimized out>, vtable_slot@entry=0x0, error=error@entry=0x7fff56e8af20) at mini-trampolines.c:635
#21 0x000055af27bc5323 in mono_magic_trampoline (regs=0x7fff56e8afe8, code=0x4138d214 "H\277\060\301\262\304\377~", arg=0x55af2823fa00, tramp=<optimized out>) at mini-trampolines.c:773
#22 0x0000000040f02396 in ?? ()
#23 0x000055af281fe6c5 in ?? ()
#24 0x000055af281dffe8 in ?? ()
#25 0x00007fff56e8b1b0 in ?? ()
#26 0x00007fff56e8afe8 in ?? ()
#27 0x000055af28206170 in ?? ()
#28 0x0000000000000000 in ?? ()
[Inferior 1 (process 30295) detached]

=================================================================
    Basic Fault Address Reporting
=================================================================
Memory around native instruction pointer (0x7effc518f781):0x7effc518f771  d2 4c 89 ce bf 02 00 00 00 b8 0e 00 00 00 0f 05  .L..............
0x7effc518f781  48 8b 84 24 08 01 00 00 64 48 33 04 25 28 00 00  H..$....dH3.%(..
0x7effc518f791  00 75 20 44 89 c0 48 81 c4 18 01 00 00 c3 90 48  .u D..H........H
0x7effc518f7a1  8b 15 c9 06 18 00 f7 d8 41 b8 ff ff ff ff 64 89  ........A.....d.

=================================================================
    Managed Stacktrace:
=================================================================
     at <unknown> <0xffffffff>
     at test:Run <0x000a3>
     at test:Main <0x00047>
     at System.Object:runtime_invoke_void <0x00086>
=================================================================
Aborted

Can't reproduce it, could you attach the .exe ?

test.zip
@vargaz see build.sh, perhaps csc needs /optimize+ to generate the code that fails?

The IL looks invalid, the return new T() line is compiled to:

IL_0010:  call       !!0 [mscorlib]System.Activator::CreateInstance<!!0>()

But !!0 is instantiated with bool in this case.

Minimal testcase:

using System;

public class Test
{
    public static T GetT<T> () where T : new()
    {
            return new T();
    }

    public static void Main ()
    {
        GetT<bool> ();
    }
}

Looks like CreateInstance has an overload which works with valuetypes, so this does look like a JIT problem.

Introduced by 07fa0bd3b40d4831800e1da6f68556d690884119.

Thanks for the testcase.

thanks for this fix!!

_Release status update_

A new Preview version of Xamarin.Android has now been published that includes the fix for this item. The fix is not yet included in a Release version. I will update this again when a Release version is available that includes the fix.

Fix included in Xamarin.Android 11.0.0.3.

Fix included on Windows in Visual Studio 2019 version 16.7 Preview 4. To try the Preview version that includes the fix, check for the latest updates in Visual Studio Preview.

Fix included on macOS in Visual Studio 2019 for Mac version 8.7 Preview 4. To try the Preview version that includes the fix, check for the latest updates on the Preview updater channel.

_Release status update_

A new Release version of Xamarin.Android has now been published that includes the fix for this item.

Fix included in Xamarin.Android SDK version 11.0.0.3.

Fix included on Windows in Visual Studio 2019 version 16.7. To get the new version that includes the fix, check for the latest updates or install the most recent release from https://visualstudio.microsoft.com/downloads/.

Fix included on macOS in Visual Studio 2019 for Mac version 8.7. To get the new version that includes the fix, check for the latest updates on the Stable updater channel.

Was this page helpful?
0 / 5 - 0 ratings