Azure / azure-sdk-for-net

This repository is for active development of the Azure SDK for .NET. For consumers of the SDK we recommend visiting our public developer docs at https://learn.microsoft.com/dotnet/azure/ or our versioned developer docs at https://azure.github.io/azure-sdk-for-net.
MIT License
5.47k stars 4.8k forks source link

[BUG] Uploading blob on iOS throws System.ExecutionEngineException #33472

Open RenaudAvenas opened 1 year ago

RenaudAvenas commented 1 year ago

Library name and version

Azure.Storage.Blobs 12.14.1

Describe the bug

When we upload a file on physical iOS device, the System.ExecutionEngineException is thrown for this reason : Attempting to JIT compile method 'void Azure.Storage.PartitionedUploader`2<Azure.Storage.Blobs.Models.BlobUploadOptions, Azure.Storage.Blobs.Models.BlobContentInfo>:.ctor

I try to fix it by create a PartitionedUploader to force the compiler to generate the generic class but PartitionedUploader is internal.

Expected behavior

The blob is uploaded

Actual behavior

System.ExecutionEngineException is thrown

Reproduction Steps

Create an iOS application (Xamarin.iOS) => I have create an Xamarin.Forms app Write this code :

var blobContainer= new BlobContainerClient("connectionString", "test");
await blobContainer.CreateIfNotExistsAsync();
var stream = new MemoryStream(fileByteArray);

var blobClient = imageContainer.GetBlobClient("blobUrl");
await blobClient.UploadAsync(stream, true);

When executing, this code throws System.ExecutionEngineException

Environment

Visual Studio 17.4.4 Xamarin.Forms 5.0.0.2515 iOS 16.1

ghost commented 1 year ago

Thank you for your feedback. This has been routed to the support team for assistance.

navba-MSFT commented 1 year ago

@RenaudAvenas Thanks for reaching out to us and reporting this issue. Could you please let me know if the below sample also throws the same exception ?

using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;

private async void UploadBlob(string filePath)
{
    // Retrieve storage account information from connection string
    CloudStorageAccount storageAccount = CloudStorageAccount.Parse("<your_storage_connection_string>");

    // Create a blob client for interacting with the blob service
    CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

    // Get a reference to the container
    CloudBlobContainer container = blobClient.GetContainerReference("<your_container_name>");

    // Create the container if it doesn't already exist
    await container.CreateIfNotExistsAsync();

    // Get a reference to the blob
    CloudBlockBlob blockBlob = container.GetBlockBlobReference(Path.GetFileName(filePath));

    // Open the file and upload its data
    using (var fileStream = File.OpenRead(filePath))
    {
        await blockBlob.UploadFromStreamAsync(fileStream);
    }
}
RenaudAvenas commented 1 year ago

Hello,

Thanks for your answer. I try your code and it works but it use the deprecated nuget package. I will use the workaround for now.

navba-MSFT commented 1 year ago

@RenaudAvenas Thanks for the update. I am glad that you are now unblocked with the workaround.

@amnguye @seanmcc-msft Are you aware of this issue in v12 ? . We have isolated the issue, since v11 SDK seems to be working just fine.

ghost commented 1 year ago

Hi @RenaudAvenas. Thank you for opening this issue and giving us the opportunity to assist. We believe that this has been addressed. If you feel that further discussion is needed, please add a comment with the text “/unresolve” to remove the “issue-addressed” label and continue the conversation.

amnguye commented 1 year ago

I think this is due to the fact that iOS does not allow JITing code. @RenaudAvenas what's the full error message?

I haven't looked into the v11 SDK but I'm assuming the v11 SDK wasn't using any code that does Class<T> while the v12 SDK does Class<T> (e.g. PartitionedUploader<T,T>).

So when the code goes to create the PartionedUploader<Azure.Storage.Blobs.Models.BlobUploadOptions, Azure.Storage.Blobs.Models.BlobContentInfo> it throws this error cause iOS does not allow this.

RenaudAvenas commented 1 year ago

Yes I think too, the whole exception message is : BlockBlobClient.GetPartitionedUploader (Azure.Storage.StorageTransferOptions transferOptions, Azure.Storage.UploadTransferValidationOptions validationOptions, System.Buffers.ArrayPool1[T] arrayPool, System.String operationName) System.ExecutionEngineException: Attempting to JIT compile method 'void Azure.Storage.PartitionedUploader2<Azure.Storage.Blobs.Models.BlobUploadOptions, Azure.Storage.Blobs.Models.BlobContentInfo>:.ctor (Azure.Storage.PartitionedUploader2/Behaviors<Azure.Storage.Blobs.Models.BlobUploadOptions, Azure.Storage.Blobs.Models.BlobContentInfo>,Azure.Storage.StorageTransferOptions,Azure.Storage.UploadTransferValidationOptions,System.Buffers.ArrayPool1,string)' while running in aot-only mode. See https://docs.microsoft.com/xamarin/ios/internals/limitations for more information.

The stack trace is : Azure.Storage.Blobs.Specialized BlockBlobClient.GetPartitionedUploader (Azure.Storage.StorageTransferOptions transferOptions, Azure.Storage.UploadTransferValidationOptions validationOptions, System.Buffers.ArrayPool1[T] arrayPool, System.String operationName) Azure.Storage.Blobs BlobClient.GetPartitionedUploader (Azure.Storage.StorageTransferOptions transferOptions, Azure.Storage.UploadTransferValidationOptions validationOptions, System.Buffers.ArrayPool1[T] arrayPool, System.String operationName) Azure.Storage.Blobs BlobClient.StagedUploadInternal (System.IO.Stream content, Azure.Storage.Blobs.Models.BlobUploadOptions options, System.Boolean async, System.Threading.CancellationToken cancellationToken)

navba-MSFT commented 1 year ago

@RenaudAvenas Thanks for sharing the exception callstack. I hope you are unblocked now with my above workaround of using v11 SDK.

@amnguye To me this issue seems to be IOS specific and not related Azure.Storage.Blobs SDK. Could you please let me know your thoughts ?

ghost commented 1 year ago

Hi @RenaudAvenas. Thank you for opening this issue and giving us the opportunity to assist. We believe that this has been addressed. If you feel that further discussion is needed, please add a comment with the text “/unresolve” to remove the “issue-addressed” label and continue the conversation.

amnguye commented 1 year ago

It is an IOS specific error however we need to resolve why the SDK isn't getting along with Xamarin / iOS. I think it maybe be due to the version of .NET being used. I think if you were to downgrade to .NET 3.1 we might not see this problem. However I can't recommend that either as .NET 3.1 is out of support.

ghost commented 1 year ago

Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc @xgithubtriage.

Issue Details
### Library name and version Azure.Storage.Blobs 12.14.1 ### Describe the bug When we upload a file on physical iOS device, the System.ExecutionEngineException is thrown for this reason : Attempting to JIT compile method 'void Azure.Storage.PartitionedUploader`2:.ctor I try to fix it by create a PartitionedUploader to force the compiler to generate the generic class but PartitionedUploader is internal. ### Expected behavior The blob is uploaded ### Actual behavior System.ExecutionEngineException is thrown ### Reproduction Steps Create an iOS application (Xamarin.iOS) => I have create an Xamarin.Forms app Write this code : ``` var blobContainer= new BlobContainerClient("connectionString", "test"); await blobContainer.CreateIfNotExistsAsync(); var stream = new MemoryStream(fileByteArray); var blobClient = imageContainer.GetBlobClient("blobUrl"); await blobClient.UploadAsync(stream, true); ``` When executing, this code throws `System.ExecutionEngineException` ### Environment Visual Studio 17.4.4 Xamarin.Forms 5.0.0.2515 iOS 16.1
Author: RenaudAvenas
Assignees: navba-MSFT
Labels: `Storage`, `Service Attention`, `Client`, `customer-reported`, `bug`, `needs-team-attention`
Milestone: -
navba-MSFT commented 1 year ago

It is an IOS specific error however we need to resolve why the SDK isn't getting along with Xamarin / iOS. I think it maybe be due to the version of .NET being used. I think if you were to downgrade to .NET 3.1 we might not see this problem. However I can't recommend that either as .NET 3.1 is out of support.

Thanks @amnguye for your reply.

I am adding Service team to take this forward.