[Mono-bugs] [Bug 673828] New: handle_thunk: assertion failed in mini-arm.c when compiling Linq expression

bugzilla_noreply at novell.com bugzilla_noreply at novell.com
Mon Feb 21 11:17:26 EST 2011



           Summary: handle_thunk: assertion failed in mini-arm.c when
                    compiling Linq expression
    Classification: Mono
           Product: Mono: Runtime
           Version: 2.8.x
          Platform: Other
        OS/Version: Other
            Status: NEW
          Severity: Normal
          Priority: P5 - None
         Component: JIT
        AssignedTo: lupus at novell.com
        ReportedBy: clockworksaint at gmail.com
         QAContact: mono-bugs at lists.ximian.com
          Found By: ---
           Blocker: ---

Description of Problem:

An assertion failure occurs in handle_thunk in mini-arm.c while compiling a
Linq expression. This only happens if the JIT is attempting to patch a branch
instruction in a code chunk with an address >32MiB distant from all the code
chunks owned by the main code manager in the domain. Only code chunks in the
main code manager are searched when trying to find a suitable slot in a thunk

Steps to reproduce the problem:

1. Create Crasher.cs as follows:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

public static class Program
    static void Main()
        List<Func<int>> delegates = new List<Func<int>>();
        for (int i=0; i!=20000; ++i)
            Console.WriteLine("Iteration #{0}", i);
            int copy_of_i = i;
            Expression<Func<int>> expr = () => copy_of_i;

2. gmcs Crasher.cs
3. mono Crasher.exe

Actual Results:

Iteration #1
Iteration #6087
Iteration #6088
Iteration #6089
thunk failed for 0x404ddc80 from 0x42e0950c
ERROR:mini-arm.c:2579:handle_thunk: assertion failed: (pdata.found == 1)

  at (wrapper managed-to-native) System.Delegate.CreateDelegate_internal
(System.Type,object,System.Reflection.MethodInfo,bool) <0xffffffff>
  at System.Delegate.CreateDelegate
(System.Type,object,System.Reflection.MethodInfo,bool) <0x006c0>
  at System.Delegate.CreateDelegate
(System.Type,object,System.Reflection.MethodInfo) <0x0002f>
  at System.Reflection.Emit.DynamicMethod.CreateDelegate (System.Type,object)
  at System.Linq.Expressions.EmitContext.CreateDelegate
(System.Runtime.CompilerServices.ExecutionScope) <0x0003f>
  at System.Linq.Expressions.CompilationContext.CreateDelegate
(int,System.Runtime.CompilerServices.ExecutionScope) <0x00043>
  at System.Linq.Expressions.CompilationContext.CreateDelegate () <0x0003f>
  at System.Linq.Expressions.LambdaExpression.Compile () <0x00053>
  at System.Linq.Expressions.Expression`1<object>.Compile () <0x0001b>
  at Program.Main () <0x00103>
  at (wrapper runtime-invoke) object.runtime_invoke_void
(object,intptr,intptr,intptr) <0x0006b>

Native stacktrace:

Debug info from gdb:

[Thread debugging using libthread_db enabled]
[New Thread 0x40d35470 (LWP 28978)]
0x401311a4 in read () from /lib/libpthread.so.0
  2 Thread 0x40d35470 (LWP 28978)  0x4012fed8 in sem_wait@@GLIBC_2.4 () from
* 1 Thread 0x40365000 (LWP 28977)  0x401311a4 in read () from

Thread 2 (Thread 0x40d35470 (LWP 28978)):
#0  0x4012fed8 in sem_wait@@GLIBC_2.4 () from /lib/libpthread.so.0
#1  0x0017dfc8 in mono_sem_wait ()
#2  0x0010139c in ?? ()
#3  0x0010139c in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

Thread 1 (Thread 0x40365000 (LWP 28977)):
#0  0x401311a4 in read () from /lib/libpthread.so.0
#1  0x40131194 in read () from /lib/libpthread.so.0
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

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.


Expected Results:

No assertion. With sufficient memory, the test program should run to

How often does this happen? 

This program fails reliably for me at Iteration #6089 on Mono 2.6.7 and #6060
on Mono 2.8.2.

Additional Information:

$ uname -a
Linux sheeva003 #8 PREEMPT Wed Jan 26 14:57:57 GMT 2011 armv5tel

The device is a Sheevaplug running Debian Squeeze.

The test code here triggers the problem by simply keeping alive all the
dynamically compiled delegates - eventually a code chunk is bound to be
allocated at a sufficiently distant address to trigger the problem. When I
first encountered this bug it was not in such contrived code - there was no
great quantity of dynamically generated code being deliberately kept alive so
long. It seems that the problem was encountered more quickly because a native
library was allocating its own memory, but it was not an easily reduced repro.
The dynamic code was being generated by the Moq library, but it should
generally have been short-lived.

>From what I can tell, the root cause of the problem is that the *only* thunk
table guaranteed to be in range for a given instruction is the one that resides
in the same code chunk, but in the case of dynamically generated code it is not
considered as an option. I'm not sure if just considering it would be enough to
fix the problem - in this case the thunk table is only 32 bytes in size, large
enough for only two entries. (Each entry is 12 bytes.) I don't know how easy it
would be to exhaust those entries.

See also my discussion of this on the mono-devel mailing list:


Configure bugmail: https://bugzilla.novell.com/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.

More information about the mono-bugs mailing list