Skip to content

Commit d1e4319

Browse files
authored
When cloning method descs be careful with fields that have different offsets between the source and destination. (#115798)
* clean old locations when shifting data inside methoddesc * better fix * added a test * PR feedback * missing rename
1 parent 2f62903 commit d1e4319

File tree

4 files changed

+85
-7
lines changed

4 files changed

+85
-7
lines changed

src/coreclr/vm/methodtablebuilder.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7148,16 +7148,14 @@ VOID MethodTableBuilder::AllocAndInitMethodDescChunk(COUNT_T startIndex, COUNT_T
71487148
// and should not be used. We should go to the effort of having proper constructors
71497149
// in the MethodDesc class. </NICE>
71507150

7151-
memcpy(pUnboxedMD, pMD, pMD->SizeOf());
7152-
7153-
// Reset the chunk index
7154-
pUnboxedMD->SetChunkIndex(pChunk);
7155-
7156-
if (bmtGenerics->GetNumGenericArgs() == 0) {
7157-
pUnboxedMD->SetHasNonVtableSlot();
7151+
if (bmtGenerics->GetNumGenericArgs() == 0)
7152+
{
7153+
memcpy(pUnboxedMD, pMD, pMD->GetBaseSize());
71587154

71597155
// By settings HasNonVTableSlot, the following chunks of data have been shifted around.
71607156
// This is an example of the fragility noted in the memcpy comment above
7157+
pUnboxedMD->SetHasNonVtableSlot();
7158+
71617159
if (pUnboxedMD->HasNativeCodeSlot())
71627160
{
71637161
*pUnboxedMD->GetAddrOfNativeCodeSlot() = *pMD->GetAddrOfNativeCodeSlot();
@@ -7171,6 +7169,13 @@ VOID MethodTableBuilder::AllocAndInitMethodDescChunk(COUNT_T startIndex, COUNT_T
71717169
*pUnboxedMD->GetAddrOfAsyncMethodData() = *pMD->GetAddrOfAsyncMethodData();
71727170
}
71737171
}
7172+
else
7173+
{
7174+
memcpy(pUnboxedMD, pMD, pMD->SizeOf());
7175+
}
7176+
7177+
// Reset the chunk index
7178+
pUnboxedMD->SetChunkIndex(pChunk);
71747179

71757180
//////////////////////////////////////////////////////////
71767181
// Modify the original MethodDesc to be an unboxing stub
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
using System;
4+
using Xunit;
5+
using System.Threading.Tasks;
6+
7+
public interface I0
8+
{
9+
Task<bool> M8();
10+
}
11+
12+
public struct S1 : I0
13+
{
14+
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
15+
public async Task<bool> M8()
16+
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
17+
{
18+
return false;
19+
}
20+
}
21+
22+
public class Runtime_115667
23+
{
24+
[Fact]
25+
public static void TestEntryPoint()
26+
{
27+
System.Runtime.Loader.AssemblyLoadContext alc = new CollectibleALC();
28+
System.Reflection.Assembly asm = alc.LoadFromAssemblyPath(System.Reflection.Assembly.GetExecutingAssembly().Location);
29+
System.Reflection.MethodInfo mi = asm.GetType(typeof(Runtime_115667).FullName).GetMethod(nameof(MainInner));
30+
System.Type runtimeTy = asm.GetType(typeof(Runtime).FullName);
31+
mi.Invoke(null, new object[] { System.Activator.CreateInstance(runtimeTy) });
32+
}
33+
34+
public static void MainInner(IRuntime rt)
35+
{
36+
bool vr1 = new S1().M8().GetAwaiter().GetResult();
37+
}
38+
}
39+
40+
public interface IRuntime
41+
{
42+
void WriteLine<T>(string site, T value);
43+
}
44+
45+
public class Runtime : IRuntime
46+
{
47+
public void WriteLine<T>(string site, T value) => System.Console.WriteLine(value);
48+
}
49+
50+
public class CollectibleALC : System.Runtime.Loader.AssemblyLoadContext
51+
{
52+
public CollectibleALC() : base(true)
53+
{
54+
}
55+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<Optimize>True</Optimize>
4+
<CLRTestPriority>1</CLRTestPriority>
5+
</PropertyGroup>
6+
<ItemGroup>
7+
<Compile Include="test115667.cs" />
8+
</ItemGroup>
9+
<ItemGroup>
10+
<ProjectReference Include="$(TestSourceDir)Common/CoreCLRTestLibrary/CoreCLRTestLibrary.csproj" />
11+
</ItemGroup>
12+
</Project>

src/tests/issues.targets

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -952,6 +952,9 @@
952952
<ExcludeList Include="$(XunitTestBinBase)/JIT/Regression/JitBlue/Runtime_90219/Runtime_90219/**">
953953
<Issue>https://github.com/dotnet/runtimelab/issues/155: Assembly.Load</Issue>
954954
</ExcludeList>
955+
<ExcludeList Include="$(XunitTestBinBase)/Regressions/coreclr/GitHub_115667/**">
956+
<Issue>https://github.com/dotnet/runtimelab/issues/155: Assembly.Load</Issue>
957+
</ExcludeList>
955958
<ExcludeList Include="$(XunitTestBinBase)/reflection\DefaultInterfaceMethods\Emit\*">
956959
<Issue>https://github.com/dotnet/runtimelab/issues/155: Reflection.Emit</Issue>
957960
</ExcludeList>
@@ -3064,6 +3067,9 @@
30643067
<ExcludeList Include="$(XunitTestBinBase)/JIT/Regression/JitBlue/Runtime_90219/Runtime_90219/*">
30653068
<Issue>Loads an assembly from file</Issue>
30663069
</ExcludeList>
3070+
<ExcludeList Include="$(XunitTestBinBase)/Regressions/coreclr/GitHub_115667/**">
3071+
<Issue>Loads an assembly from file</Issue>
3072+
</ExcludeList>
30673073
</ItemGroup>
30683074

30693075
<!-- Apple mobile NativeAOT -->

0 commit comments

Comments
 (0)