Closed aarononeal closed 11 years ago
Here is one possible fix which makes the dynamic assembly transient instead of persistent. I don't know if you want to use this particular env var or another mechanism to toggle whether the dynamic assembly is transient.
An alternate solution might be to use NSHomeDirectory to get the sandboxed app location and specify an absolute path, but that requires a native call.
public DynamicAssembly (String assemblyName, String moduleName)
{
this.assemblyName = assemblyName;
this.moduleName = moduleName;
// Default mode is transient
AssemblyBuilderAccess access = AssemblyBuilderAccess.Run;
// If the environment variable is set then switch to persistent mode
String dump = Environment.GetEnvironmentVariable ("MONOBJC_DUMP_ASSEMBLY");
if (String.Equals (dump, "YES", StringComparison.OrdinalIgnoreCase) ||
String.Equals (dump, "TRUE", StringComparison.OrdinalIgnoreCase)) {
access = AssemblyBuilderAccess.RunAndSave;
}
// Define dynamic assembly
AssemblyName name = new AssemblyName {Name = this.assemblyName, Version = Assembly.GetExecutingAssembly().GetName().Version};
this.assembly = AppDomain.CurrentDomain.DefineDynamicAssembly (name, access);
// Define dynamic module
if (access == AssemblyBuilderAccess.Run) {
// Transient
this.module = this.assembly.DefineDynamicModule (this.moduleName);
} else {
// Persistent
this.module = this.assembly.DefineDynamicModule (this.moduleName, this.assemblyName + ".dll");
}
}
I updated this and added Pull #421.
I don't really understand the circumstances of the failure. Do you mean that a sandboxed application always crash or it crashes only when dumping the assemblies ?
I have successfully sandboxed some applications and I never encounter a crash.
It always crashes, you don't need to initiate an assembly dump. Dynamic assemblies right now are configured with RunAndSave, so it saves when defining the assembly before the first type is even added.
To be clear, the problem isn't dumping the assembly, it's where the assembly is being saved due to the fact that it relies on GetCurrentDirectory() which fails in the sandbox.
Since normal use of the bridge doesn't require persistent dynamic assemblies, the workaround I implemented in the pull was to just make dynamic assemblies transient that are created by the bridge unless the env var is set.
Humm, this is very strange. My understanding is that the dynamic assembly is only written to the disk if the Save method is called. When you run a non-sandboxed application, are the assemblies also dumped ?
PS: I have two applications in the MacAppStore and they do not exhibit the described behavior.
Here's a little more info from AssemblyBuilder.cs:
// don't call GetCurrentDirectory for Run-only builders (CAS may not like that)
if (IsSave && (directory == null || directory.Length == 0)) {
dir = Directory.GetCurrentDirectory ();
} else {
dir = directory;
}
It's not that it's persisting to disk, it's that it wants a directory for AssemblyDir. The call to GetCurrentDirectory() is failing in my environment.
Allright, I get it. I will try to reproduce.
By the way, I forgot to ask: iOS or OS X ?
It's OS X 10.8 running on Mono 2.6 and built with Mono 3.2.1 using the mcs -sdk:2 option, although you can't build Monobjc in that way without some other patches due to some recent .NET 4 dependencies (like ManualResetEventSlim). Those specifics aside, as the Mono comment points out, even in a newer environment CAS policy could still be configured to deny GetCurrentDirectory().
Also worth mentioning, I was launching the dev signed, sandboxed app from the build folder and not the system Applications folder where sandboxed apps have slightly elevated privileges. If you've been running your sandboxed app from the Applications folder, try moving it elsewhere to see if this repros. I'll test myself when I can to see if the launch location makes a difference, but I have to first prepare new Monobjc and app builds without the patch and that takes some doing.
I think it will be too time-consuming to try to reproduce. I have applied the pull request monobjc#421.
See this trace: