Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CGPattern causes "Attempting to JIT compile method" exception since VS 7.5 #13231

Closed
mandel-macaque opened this issue Feb 28, 2019 · 7 comments · Fixed by #14312 or xamarin/xamarin-android#3153

Comments

@mandel-macaque
Copy link
Contributor

@mandel-macaque mandel-macaque commented Feb 28, 2019

Running the attached application results in a run time error.

Application.Main(): Attempting to JIT compile method '(wrapper managed-to-native) CoreGraphics.ReleaseInfoCallback:wrapper_aot_native (object,intptr)' while running in aot-only mode. See https://developer.xamarin.com/guides/ios/advanced_topics/limitations/ for more information.

Steps to Reproduce

  1. Run the attached project on a device.
  2. Wait for crash.

JitErrorTest.zip

Current Behavior

Application crashes after running for a while. It is hard to know when it will happen.

Expected Behavior

Application not crashing.

On which platforms did you notice this

[x] iOS/macOs
[ ] Linux
[ ] Windows

Version Used:

Current xamarin master: 564628a289f807289ae6ef75e0bc10f3f0f89bec (hash)

@marek-safar

This comment has been minimized.

Copy link
Member

@marek-safar marek-safar commented Mar 1, 2019

@vargaz could you look into this regression?

@vargaz

This comment has been minimized.

Copy link
Member

@vargaz vargaz commented Mar 6, 2019

@rolfbjarne Did anything change around that area in x.ios ?

@rolfbjarne

This comment has been minimized.

Copy link
Member

@rolfbjarne rolfbjarne commented Mar 7, 2019

@vargaz no, the CGPattern code hasn't changed in years.

@vargaz

This comment has been minimized.

Copy link
Member

@vargaz vargaz commented Mar 8, 2019

@mandel-macaque I can't reproduce this, the app is supposed to run for a while, then crash ?

@mandel-macaque

This comment has been minimized.

Copy link
Contributor Author

@mandel-macaque mandel-macaque commented Mar 11, 2019

@Vargz correct, In my tests, I ran the application in an iPhone 8+ with iOS 12.1.4 (16D57). It takes an unknown about of time to crash. I created the issue following the information provided by a user in https://developercommunity.visualstudio.com/content/problem/463933/cgpattern-causes-attempting-to-jit-compile-method.html which followed an issue that was described in the forums (all the information of the original issue can be found in the developer community url).

@lewurm

This comment has been minimized.

Copy link
Member

@lewurm lewurm commented Mar 11, 2019

I can reproduce, it took around a minute on an iPhone 7. native stack trace in a debugger: https://gist.github.com/lewurm/2535b2a5d4edc9e25971351676994724

looks like we run out of some kind of trampoline, probably caused by this delegate in the repro:

using (CGPattern pattern = new CGPattern(rect, CGAffineTransform.MakeIdentity(), rect.Width, rect.Height, CGPatternTiling.NoDistortion, true, ctx =>
{
    ctx.SetStrokeColor(color.CGColor);
    ctx.SetLineWidth(2f);
    [...]
}))

I'm not familiar with this API: Is it possible to rewrite it so that the CGPattern object is only allocated once?

@marek-safar

This comment has been minimized.

Copy link
Member

@marek-safar marek-safar commented Mar 25, 2019

@vargaz @lewurm does it mean we have a leak somewhere that it does not reproduce reliably?

@marek-safar marek-safar assigned BrzVlad and unassigned vargaz Apr 24, 2019
BrzVlad added a commit to BrzVlad/mono that referenced this issue May 2, 2019
When passing a delegate to native code, we pass the delegate_trampoline which can be used to invoke the delegate from native code and we store this mapping (delegate_trampoline->delegate) in a hashtable so we can get a delegate for the delegate_trampoline, when marshalling the opposite way. If we are trying to marshal a ftnptr (for managed code) to a delegate and we don't find this mapping we can crash. This could happen if the finalization for some other delegate that uses the same ftnptr removes this entry from the table. We solve this by never freeing these entries. The first delegate-ftnptr pair will always be alive. This is easier, faster and potentially uses less memory than tracking in the hashtable every pair. There should be a small and limited set of methods marshalled to native.

Fixes mono#13231
monojenkins added a commit to monojenkins/mono that referenced this issue May 7, 2019
When passing a delegate to native code, we pass the delegate_trampoline which can be used to invoke the delegate from native code and we store this mapping (delegate_trampoline->delegate) in a hashtable so we can get a delegate for the delegate_trampoline, when marshalling the opposite way. If we are trying to marshal a ftnptr (for managed code) to a delegate and we don't find this mapping we can crash. This could happen if the finalization for some other delegate that uses the same ftnptr removes this entry from the table. We solve this by never freeing these entries. The first delegate-ftnptr pair will always be alive. This is easier, faster and potentially uses less memory than tracking in the hashtable every pair. There should be a small and limited set of methods marshalled to native.

Fixes mono#13231
monojenkins added a commit to monojenkins/mono that referenced this issue May 7, 2019
When passing a delegate to native code, we pass the delegate_trampoline which can be used to invoke the delegate from native code and we store this mapping (delegate_trampoline->delegate) in a hashtable so we can get a delegate for the delegate_trampoline, when marshalling the opposite way. If we are trying to marshal a ftnptr (for managed code) to a delegate and we don't find this mapping we can crash. This could happen if the finalization for some other delegate that uses the same ftnptr removes this entry from the table. We solve this by never freeing these entries. The first delegate-ftnptr pair will always be alive. This is easier, faster and potentially uses less memory than tracking in the hashtable every pair. There should be a small and limited set of methods marshalled to native.

Fixes mono#13231
marek-safar added a commit that referenced this issue May 31, 2019
When passing a delegate to native code, we pass the delegate_trampoline which can be used to invoke the delegate from native code and we store this mapping (delegate_trampoline->delegate) in a hashtable so we can get a delegate for the delegate_trampoline, when marshalling the opposite way. If we are trying to marshal a ftnptr (for managed code) to a delegate and we don't find this mapping we can crash. This could happen if the finalization for some other delegate that uses the same ftnptr removes this entry from the table. We solve this by never freeing these entries. The first delegate-ftnptr pair will always be alive. This is easier, faster and potentially uses less memory than tracking in the hashtable every pair. There should be a small and limited set of methods marshalled to native.

Fixes #13231
marek-safar added a commit that referenced this issue May 31, 2019
When passing a delegate to native code, we pass the delegate_trampoline which can be used to invoke the delegate from native code and we store this mapping (delegate_trampoline->delegate) in a hashtable so we can get a delegate for the delegate_trampoline, when marshalling the opposite way. If we are trying to marshal a ftnptr (for managed code) to a delegate and we don't find this mapping we can crash. This could happen if the finalization for some other delegate that uses the same ftnptr removes this entry from the table. We solve this by never freeing these entries. The first delegate-ftnptr pair will always be alive. This is easier, faster and potentially uses less memory than tracking in the hashtable every pair. There should be a small and limited set of methods marshalled to native.

Fixes #13231
marek-safar added a commit that referenced this issue May 31, 2019
When passing a delegate to native code, we pass the delegate_trampoline which can be used to invoke the delegate from native code and we store this mapping (delegate_trampoline->delegate) in a hashtable so we can get a delegate for the delegate_trampoline, when marshalling the opposite way. If we are trying to marshal a ftnptr (for managed code) to a delegate and we don't find this mapping we can crash. This could happen if the finalization for some other delegate that uses the same ftnptr removes this entry from the table. We solve this by never freeing these entries. The first delegate-ftnptr pair will always be alive. This is easier, faster and potentially uses less memory than tracking in the hashtable every pair. There should be a small and limited set of methods marshalled to native.

Fixes #13231
jonpryor added a commit to jonpryor/xamarin-android that referenced this issue May 31, 2019
jonpryor added a commit to xamarin/xamarin-android that referenced this issue Jun 1, 2019
jonpryor added a commit to xamarin/xamarin-android that referenced this issue Jun 1, 2019
EgorBo added a commit to EgorBo/mono that referenced this issue Jun 3, 2019
When passing a delegate to native code, we pass the delegate_trampoline which can be used to invoke the delegate from native code and we store this mapping (delegate_trampoline->delegate) in a hashtable so we can get a delegate for the delegate_trampoline, when marshalling the opposite way. If we are trying to marshal a ftnptr (for managed code) to a delegate and we don't find this mapping we can crash. This could happen if the finalization for some other delegate that uses the same ftnptr removes this entry from the table. We solve this by never freeing these entries. The first delegate-ftnptr pair will always be alive. This is easier, faster and potentially uses less memory than tracking in the hashtable every pair. There should be a small and limited set of methods marshalled to native.

Fixes mono#13231
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
6 participants
You can’t perform that action at this time.