Bug 43404 - IOS Marshal.PtrToStructure System.ExecutionEngineException
Summary: IOS Marshal.PtrToStructure System.ExecutionEngineException
Status: ASSIGNED
Alias: None
Product: iOS
Classification: Xamarin
Component: Mono runtime / AOT compiler (show other bugs)
Version: XI 9.3 (xcode 7.1 previews)
Hardware: PC Windows
: --- minor
Target Milestone: Future Cycle (TBD)
Assignee: Zoltan Varga
URL:
Depends on:
Blocks:
 
Reported: 2016-08-16 07:48 UTC by Karl
Modified: 2017-05-08 16:37 UTC (History)
6 users (show)

See Also:
Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
Example it works on an ios simulator but not if you put it on an ipad (testing on ipad air 2) (159.68 KB, application/x-zip-compressed)
2016-08-17 10:27 UTC, Karl
Details
ide details (2.41 KB, text/plain)
2016-08-17 10:27 UTC, Karl
Details

Description Karl 2016-08-16 07:48:58 UTC
writing a program using Xamarin.Forms to run across both android and IOS, the following both code versions work on android, However throws a ExecutionEngineException when the second version is ran on IOS but the first one works.

protected static object ReadStruct(BinaryReader reader, Type structType, ChunkHeader chunkHeader)
{
    int size = Marshal.SizeOf(structType);
    if (size != chunkHeader.chunkSize) // check the actual size of this chunk object with the expected size from the stream
    {
        throw new IOException("Invalid file format, incorrect " + chunkHeader.chunkName + " chunk size (exp.: " + size + ", read: " + chunkHeader.chunkSize + ")");
    }

    byte[] data = reader.ReadBytes(size);
    IntPtr buffer = Marshal.AllocHGlobal(size);
    Marshal.Copy(data, 0, buffer, size);
 // the line that crashes follows this
    object structObject = Marshal.PtrToStructure(buffer, structType);
    Marshal.FreeHGlobal(buffer);
    return structObject;
}
The above code stays the same in both versions.

public struct OvdBChunk 
{
   // stuff in here but not important
}
The above sample works but for this and all future updates i will need to inherit the old versions as stuff may have been updated in newer devices so have been added to but will always keep the old stuff so i changed it to the following

public class OvdBChunk : OvdAChunk
{
   // stuff in here but not important
}
The structType in part is the part that is changing in the top code snippet.





suggest on here i report it as a bug
http://stackoverflow.com/questions/38953160/ios-marshal-ptrtostructure-system-executionengineexception?noredirect=1#comment65271293_38953160
Comment 1 Karl 2016-08-16 08:14:31 UTC
Slight bit i missed of origanl post

[StructLayout(Layou‌​tKind.Sequential, Pack = 1)]

is used for public class OvdBChunk : OvdAChunk   and   public struct OvdBChunk
Comment 2 Vincent Dondain [MSFT] 2016-08-17 09:22:41 UTC
Hi I've been trying to reproduce that bug based on the informations you gave us and I couldn't.

Could you please provide us:

- A proper test case sample so it's easily reproducible by any member of the team.
- Your XS about information to know the versions of the product you're using.
Comment 3 Karl 2016-08-17 10:27:35 UTC
Created attachment 17076 [details]
Example it works on an ios simulator but not if you put it on an ipad (testing on ipad air 2)
Comment 4 Karl 2016-08-17 10:27:54 UTC
Created attachment 17077 [details]
ide details
Comment 5 Karl 2016-09-08 16:15:36 UTC
Any news since i gave you the example to reproduce it?
Comment 6 Manuel de la Peña 2016-09-15 14:14:58 UTC
Hello,

The fact that the code works in the simulator and does not in the devices makes me believe that it is an issue with the linker. Have you tried using the Preserve attribute (https://developer.xamarin.com/api/type/MonoTouch.Foundation.PreserveAttribute/) in the class you are marshalling? In the example I can only see a use of the type in:

object structObject = Marshal.PtrToStructure(buffer, typeof(StructChunkA));

In my case I was not able to test your application in the simulator (it never launches) but might be due to my setup. Can you please add the attrbute and test it again?
Comment 7 Karl 2016-09-15 14:45:04 UTC
Hey, no joy unfortunately that didn't work
Comment 8 Manuel de la Peña 2016-09-15 14:47:10 UTC
Can you please let me know what is the example app suppose to do, in my case it does not even launch in the simulator, maybe if I know a little more I can "fix" my crash and look into your issue.
Comment 9 Karl 2016-09-15 14:57:09 UTC
It makes a byte array at the start for test data.

When one button is pressed it takes the byte array and makes the designated struct out of it then outputs success on screen.

When the other button is pressed it is suppose to take the byte array and make the designated class out of it then output success on screen, however it fails and outputs the error instead of success.
Comment 10 Manuel de la Peña 2017-01-18 11:08:25 UTC
I have tested the code in the following environments:

Debug - Simulator - Not Link - Works
Debug - Simulator - Link SDK - Works
Debug - iPhone SE - Not Link - Fails
Debug - iPhone SE - Link SDK - Fails

After the testing I'm assigning the bug to the AOT team.
Comment 11 Manuel de la Peña 2017-01-18 11:08:52 UTC
Also, confirmed the bug.
Comment 12 Zoltan Varga 2017-01-18 23:32:28 UTC
Xamarin.ios currently only supports Marshal.PtrToStructure () etc. on a subset of structures, the struct in your app is probably one which is not supported because it inherits from another structure, the pack directive, etc.
Comment 13 Zoltan Varga 2017-01-19 01:25:47 UTC
Also, it only works for structures, not classes.
Comment 14 Rodrigo Kumpera 2017-01-19 19:53:04 UTC
Hey Zoltan,

On Desktop, using Marshal.PtrToStructure with an invalid type (a class in this case) throws MarshalDirectiveException.

Can we get this behavior on device as well?
Comment 15 Zoltan Varga 2017-01-20 02:13:13 UTC
Passing a class type to PtrToStructure is not invalid.
Comment 16 Rodrigo Kumpera 2017-01-27 13:39:02 UTC
And that's the point, looks like mobile gives a different error than desktop.
Comment 17 Zoltan Varga 2017-01-27 13:58:03 UTC
I mean Marshal.PtrToStructure () doesn't throw MarshalDirectiveException for class types.
Comment 18 Rodrigo Kumpera 2017-02-07 18:50:54 UTC
FullAOT should match desktop behavior as close as possible.

Even if that means silently failing.

Can we match the JIT behavior by, IDK, catching the EEE?
Comment 19 Zoltan Varga 2017-02-07 19:39:00 UTC
So this particular case is not supported because AChunk is a class.
Comment 20 Manuel de la Peña 2017-05-08 16:17:31 UTC
@Zoltan, should we close this bug as invalid?
Comment 21 Zoltan Varga 2017-05-08 16:37:17 UTC
Probably, its not supported right now.

Note You need to log in before you can comment on or make changes to this bug.