First, the question: do CLR specifications guarantee that the code executing in multiple app domains within the same process will share the same address space? By "sharing the address space" I mean that pointers to memory allocated in one of the app domains will be valid for reading and writing across all app domains hosted inside the same process.
Consider this self-contained example illustrating the question: the program allocates a Worker
object in a separate app domain. The Worker
allocates a memory block for 10,000 integers, and fills it in with data. The program then calls across the app domain boundary to obtain the pointer to the allocated block, and verifies that it can read every one of the 10,000 items.
using System;
using System.Reflection;
using System.Runtime.InteropServices;
namespace crossapp {
public class Worker : MarshalByRefObject {
private readonly IntPtr myData;
public const int DataLength = 10000;
public Worker() {
Console.Error.WriteLine(
"Memory allocation happens in app domain '{0}'"
, Assembly.GetExecutingAssembly().FullName
);
myData = Marshal.AllocHGlobal(sizeof(int) * DataLength);
unsafe {
var ptr = (int*) myData.ToPointer();
for (var i = 0 ; i != DataLength ; i++) {
ptr[i] = 2*i + 1;
}
}
}
public IntPtr GetData() {
return myData;
}
}
class Program {
static void Main() {
var ad = AppDomain.CreateDomain("New domain");
var wrk = (Worker)ad.CreateInstanceAndUnwrap(
Assembly.GetExecutingAssembly().FullName
, "crossapp.Worker"
);
var data = wrk.GetData();
var badCount = 0;
unsafe {
var ptr = (int*)data.ToPointer();
for (var i = 0 ; i != Worker.DataLength ; i++) {
var expect = 2*i + 1;
if (ptr[i] != expect) {
Console.Error.WriteLine(
"Mismatch in position {0}: {1} != {2}"
, i, expect, ptr[i]
);
badCount++;
}
}
if (badCount == 0) {
Console.Error.WriteLine(
"All {0} items have matched."
, Worker.DataLength
);
} else {
Console.Error.WriteLine(
"Found {0} mismatches out of {1}."
, badCount
, Worker.DataLength
);
}
}
}
}
}
I ran this many times, and it worked every single time. Intuitively it should work: after all, app domains are within a single process, so they must share the same virtual address space. However, this feels like an exploit of a feature that Microsoft may take away at any time. Is there something in the specification of CLR that confirms or denies legitimacy of this trick?
Look at: Anyone can explain the major use of MarshalByRefObject . In your scenario, you are only passing a proxy and not the actual object and the memory is not being copied.
EDIT:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With