我在锁定的 AppDomain 沙箱中运行代码。此 AppDomain 中抛出的异常不包括行号,即使 pdb 可用。尝试访问堆栈跟踪的代码是完全受信任的:程序集被签名并作为强程序集加载到应用程序域中。所以我希望堆栈跟踪包含文件名和行号。我不能将 AppDomain 标记为完全受信任,因为这会破坏沙盒的目的。如何让我的堆栈跟踪包含文件名和行号?
以下示例代码(基于此示例)显示了该问题。必须对包含的程序集进行签名,我已经在我的 github 上发布了示例应用程序。
using System;
using System.Security;
using System.Security.Policy;
namespace SandboxStacktrace
{
public class Worker : MarshalByRefObject
{
private static void Main()
{
var w = new Worker();
w.TestExceptionStacktrace();
var adSandbox = GetInternetSandbox();
var handle = Activator.CreateInstanceFrom(
adSandbox,
typeof(Worker).Assembly.ManifestModule.FullyQualifiedName,
typeof(Worker).FullName);
w = (Worker)handle.Unwrap();
w.TestExceptionStacktrace();
}
public void TestExceptionStacktrace()
{
var ad = AppDomain.CurrentDomain;
Console.WriteLine("\r\nApplication domain '{0}': IsFullyTrusted = {1}",
ad.FriendlyName, ad.IsFullyTrusted);
Console.WriteLine(" IsFullyTrusted = {0} for the current assembly",
typeof(Worker).Assembly.IsFullyTrusted);
Console.WriteLine(" IsFullyTrusted = {0} for mscorlib",
typeof(int).Assembly.IsFullyTrusted);
try
{
throw new Exception("Some exception");
}
catch (Exception e)
{
var trace = e.StackTrace;
Console.Write("Stack trace contains {0}line numbers:\r\n{1}\r\n",
trace.Contains("line") ? "" : "no ", trace);
}
}
// ------------ Helper method ---------------------------------------
private static AppDomain GetInternetSandbox()
{
// Create the permission set to grant to all assemblies.
var hostEvidence = new Evidence();
hostEvidence.AddHostEvidence(new Zone(
System.Security.SecurityZone.Internet));
var pset =
System.Security.SecurityManager.GetStandardSandbox(hostEvidence);
// Identify the folder to use for the sandbox.
var ads = new AppDomainSetup();
ads.ApplicationBase = System.IO.Directory.GetCurrentDirectory();
var fullTrustAssemblies = new[]
{
typeof(Worker).Assembly.Evidence.GetHostEvidence<StrongName>(),
};
// Create the sandboxed application domain.
return AppDomain.CreateDomain("Sandbox", hostEvidence, ads, pset, fullTrustAssemblies);
}
}
}
这段代码的输出是:
Application domain 'SandboxStacktrace.exe': IsFullyTrusted = True
IsFullyTrusted = True for the current assembly
IsFullyTrusted = True for mscorlib
Stack trace contains line numbers:
at SandboxStacktrace.Worker.NewMethod() in C:\Users\Bouke\Developer\SandboxStacktrace\Program.cs:line 44
Application domain 'Sandbox': IsFullyTrusted = False
IsFullyTrusted = True for the current assembly
IsFullyTrusted = True for mscorlib
Stack trace contains no line numbers:
at SandboxStacktrace.Worker.NewMethod()