0

Update: as pointed out in the comments, the code below refers to portable pdbs. Portable pdbs are not relevant to my situation, but the question might still be interesting to people using sandboxed application domains and portable pdbs.

I'm running code inside a restricted sandbox (AppDomain). Exceptions thrown from within this sandbox do not have line numbers attached. Lifting the CAS restrictions makes the line numbers appear, so it has to do with CAS. StackFrameHelper.InitializeSourceInfo seems to be responsible for providing line numbers. There's a conditional branch in there that gets executed for the restricted path and fails on the second Assertion (stacktrace.cs:135):

// need private reflection below + unmanaged code for the portable PDB access itself
// PERF: these demands are somewhat expensive so do the quick check first. We are aiming for
// ~50k traces/s at 5 frames/trace on decent 2017 era hardware to maintain rough performance
// parity with 4.7 implementation that didn't have Portable PDB support
if (!CodeAccessSecurityEngine.QuickCheckForAllDemands())
{
    new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Assert();
    new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();
}

This gives the following exception, however this is swallowed on line 205 and loading the pdb is simply skipped:

Stack walk modifier must be reverted before another modification of the same type can be performed.

According to the documentation and another question one can only have a single assertion active per frame. So the code above appears to be invalid, is this a programming error in mscorlib (4.8)?

In order to workaround this issue I have to prevent going into that branch. I can't seem to find the source for CodeAccessSecurityEngine.QuickCheckForAllDemands. It seems to be related to full trust, however the calling assembly is already fully trusted. Also asserting unrestricted access (new PermissionSet(PermissionState.Unrestricted).Assert()) before calling exception.ToString() doesn't have any effect. The AppDomain being configured as a sandbox, IsFullyTrusted returns false.

How to work around this possible bug?

Bouke
  • 11,768
  • 7
  • 68
  • 102
  • Portable pdbs, sigh, you certainly don't need them when you target 4.8. So edit app.config to IgnorePortablePDBsInStackTraces, https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/runtime/appcontextswitchoverrides-element – Hans Passant Oct 26 '21 at 16:43
  • @HansPassant thanks! So, line 109 and onwards are concerned with portable pdbs, which is not what I've got looking at the pdb file header. So now it just enters `StackTrace.GetStackFramesInternal` but still returns without line numbers. I can't seem to find the [IPermission](https://learn.microsoft.com/en-us/dotnet/api/system.security.ipermission?view=netframework-4.8) needed for the sandbox to get line numbers from the pdb. – Bouke Oct 26 '21 at 18:41
  • So as this question is apparently regarding portable pdbs, I've posted [a new question](https://stackoverflow.com/questions/69733474/missing-file-name-and-line-numbers-in-stack-trace-in-sandbox-appdomain) regarding stack traces for normal pdbs in sandboxed application domains. – Bouke Oct 27 '21 at 06:01

0 Answers0