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

Failure to marshal out array of WinRT projected enum type #10010

Closed
TautvydasZilys opened this issue Mar 23, 2018 · 3 comments
Closed

Failure to marshal out array of WinRT projected enum type #10010

TautvydasZilys opened this issue Mar 23, 2018 · 3 comments

Comments

@TautvydasZilys
Copy link
Contributor

Given this C++ WinRT Component:

// DurationTypeArrayLeakComponent.idl
import "inspectable.idl";
import "Windows.UI.Xaml.idl";

namespace DurationTypeArrayLeakComponent
{
    runtimeclass DurationTypeHelper;

    [exclusiveto(DurationTypeHelper)]
    [uuid(835C87D2-8484-4BD7-AD1C-6AE857BDD1FC), version(1.0)]
    interface IDurationTypeHelperStatics : IInspectable
    {
        HRESULT CopyDurationTypesArray([in] UINT32 inTypesSize, [in, size_is(inTypesSize)] Windows.UI.Xaml.DurationType* inTypes, [in] UINT32 outTypesSize, [out, size_is(outTypesSize)] Windows.UI.Xaml.DurationType* outTypes);
    }

    [version(1.0)]
    [static(IDurationTypeHelperStatics, 1.0)]
    runtimeclass DurationTypeHelper
    {
    }
}
// DurationTypeHelper.h
#pragma once

#include "DurationTypeArrayLeakComponent_h.h"
#include <wrl.h>

namespace ABI
{
    namespace DurationTypeArrayLeakComponent
    {
        class DurationTypeHelper :
            public Microsoft::WRL::ActivationFactory<IDurationTypeHelperStatics>
        {
            InspectableClassStatic(RuntimeClass_DurationTypeArrayLeakComponent_DurationTypeHelper, BaseTrust);

        public:
            DurationTypeHelper();

            virtual HRESULT STDMETHODCALLTYPE CopyDurationTypesArray(UINT32 inTypesSize, ABI::Windows::UI::Xaml::DurationType* inTypes, UINT32 outTypesSize, ABI::Windows::UI::Xaml::DurationType* outTypes) override;
        };
    }
}
// DurationTypeHelper.cpp
#include "DurationTypeHelper.h"

using namespace ABI::DurationTypeArrayLeakComponent;
using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::UI::Xaml;

DurationTypeHelper::DurationTypeHelper()
{
}

HRESULT STDMETHODCALLTYPE DurationTypeHelper::CopyDurationTypesArray(UINT32 inTypesSize, DurationType* inTypes, UINT32 outTypesSize, DurationType* outTypes)
{
    if (inTypesSize != outTypesSize)
    {
        RoOriginateError(E_INVALIDARG, Microsoft::WRL::Wrappers::HStringReference(L"Array lengths must match.").Get());
        return E_INVALIDARG;
    }

    for (UINT32 i = 0; i < inTypesSize; i++)
        outTypes[i] = inTypes[i];

    return S_OK;
}

ActivatableStaticOnlyFactory(DurationTypeHelper)

This C# code throws exception on CoreCLR (and desktop .NET too):

using DurationTypeArrayLeakComponent;
using System;
using Windows.UI.Xaml;

namespace DurationTypeArrayLeak
{
    class Program
    {
        static void Main()
        {
            var types = new DurationType[]
            {
                DurationType.Automatic,
                DurationType.Forever,
                DurationType.TimeSpan,
                DurationType.Forever,
                DurationType.Automatic,
                DurationType.TimeSpan
            };

            var typesCopy = new DurationType[types.Length];
            DurationTypeHelper.CopyDurationTypesArray(types, typesCopy);

            for (int i = 0; i < types.Length; i++)
            {
                if (types[i] != typesCopy[i])
                    throw new Exception("Type was not copied correctly.");
            }
        }
    }
}

Full repro project: DurationTypeArrayLeak.zip

This doesn't happen on .NET Native. It seems the source of the problem is that the JIT passes 0 as array element size to MngdHiddenLengthArrayMarshaler::CreateMarshaler:

00007FFA4DB92BED  lea         rbx,[rsp+40h]  
00007FFA4DB92BF2  mov         qword ptr [rbp+90h],rsp  
00007FFA4DB92BF9  mov         rcx,rbx  
00007FFA4DB92BFC  mov         rdx,7FFAE9A3A9F8h  
00007FFA4DB92C06  xor         r8d,r8d  // <-------- here's the issue. Size should be 4.
00007FFA4DB92C09  mov         r9d,0FCh  
00007FFA4DB92C0F  call        MngdHiddenLengthArrayMarshaler::CreateMarshaler (07FFAAD10EEA0h)
@RussKeldorph
Copy link
Contributor

Starting with area-CodeGen bug please update if area-Interop or something else.

@jeffschwMSFT

@jkotas
Copy link
Member

jkotas commented Mar 23, 2018

This is interop bug

@msftgits msftgits transferred this issue from dotnet/coreclr Jan 31, 2020
@msftgits msftgits added this to the Future milestone Jan 31, 2020
@AaronRobinsonMSFT
Copy link
Member

WinRT scenarios have changed substantial in .NET 5.0. WinRT support in .NET 5.0 should look to the https://aka.ms/cswinrt toolset.

@ghost ghost locked as resolved and limited conversation to collaborators Dec 17, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants