Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Getting Access Violation in after AppDomain cycle #383

Closed
davidebbo opened this issue Jan 20, 2016 · 6 comments
Closed

Getting Access Violation in after AppDomain cycle #383

davidebbo opened this issue Jan 20, 2016 · 6 comments

Comments

@davidebbo
Copy link

When using Edge.js in ASP.NET, it works fine in the initial AppDomain. But if you then touch web.config or do some other action that cause an AppDomain cycle, it crashes on the next request.

This happens with a minimal one page ASP.NET app that uses Edge in the simplest way. Full repro can be found on https://github.com/davidebbo-test/EdgeCrashRepro.

The crash stack looks like this:

(2c3c.1d10): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=2483e8c0 ecx=0eab7553 edx=0adb46ad esi=0ad3e394 edi=0ad3e390
eip=00000000 esp=2483e850 ebp=2483e8a0 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010246
00000000 ??              ???
0:046> kb
ChildEBP RetAddr  Args to Child              
WARNING: Frame IP not in any known module. Following frames may be wrong.
2483e84c 0ea1d623 0e78acbf 0ecc5a44 00000070 0x0
2483e8a0 73211705 00000002 0ad3f348 00000002 node!v8::Unlocker::~Unlocker+0x191633
2483e8d4 0dffa85f 00000002 0ad3f348 721ed588 clr!PInvokeStackImbalanceHelper+0x22 [f:\dd\ndp\clr\src\vm\i386\asmhelpers.asm @ 1829]
2483e984 0dffa757 00000000 00000000 00000000 image0c4c0000!DomainBoundILStubClass.IL_STUB_PInvoke(Int32, System.String[])+0xd7
2483e9e0 7210f1cc 00000000 00000000 00000000 image0c4c0000!EdgeJs.Edge.<Func>b__1()+0xcf
2483e9ec 72109ca4 00000000 00000000 00000000 mscorlib_ni!System.Threading.ThreadHelper.ThreadStart_Context(System.Object)+0x70 [f:\dd\ndp\clr\src\BCL\system\threading\thread.cs @ 74]
2483ea50 72109be6 00000000 00000000 00000000 mscorlib_ni!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)+0xb4 [f:\dd\ndp\clr\src\BCL\system\threading\executioncontext.cs @ 954]
2483ea64 72109ba1 00000000 00000000 00000000 mscorlib_ni!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)+0x16 [f:\dd\ndp\clr\src\BCL\system\threading\executioncontext.cs @ 902]
2483ea80 7210f154 00000000 00000000 00000000 mscorlib_ni!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)+0x41 [f:\dd\ndp\clr\src\BCL\system\threading\executioncontext.cs @ 891]
2483ea98 73211396 00000000 00000000 00000000 mscorlib_ni!System.Threading.ThreadHelper.ThreadStart()+0x44 [f:\dd\ndp\clr\src\BCL\system\threading\thread.cs @ 111]

One theory is that there is some process global state that causes some lifetime management issue across AppDomains.

@tjanczuk
Copy link
Owner

Hi @davidebbo, I did not realize asp.net was cycling app domain rather than process. I can definitely see how spinning up a second app domain and running edge from there crashes the process. Node has an overarching assumption about being singleton per process (actually owning the process), so attempting to initialize it twice does not end well. When running Edge in a a CLR process there is a guard against double-initialization, but it is currently implemented in managed code: https://github.com/tjanczuk/edge/blob/master/src/double/dotnet/EdgeJs.cs#L59. I will need to see to how to refactor this logic to allow for multiple app domains.

@davidebbo
Copy link
Author

Ah, I see, it's a managed static so it doesn't survive appdomain cycles. But even if we were able to rely on a true process-wide global to avoid double init, would the V8 initialized in the first domain be able to work for the second domain? If it has any sort of back pointers to manage code objects living in the first domain, then it might be tricky.

@tjanczuk
Copy link
Owner

How does app domain recycling affect GC? At the time of recycling there may be some pending async calls issued from CLR to V8. If all managed objects in the recycled app domain are GCed without regard for those references, at the time V8 attempts to call back to CLR with completion we would likely see some AV.

@davidebbo
Copy link
Author

After the AppDomain shuts down, all objects that were in it are gone, and are probably GCed aggressively.

However, if there is a cleanup sequence that can cleanly disconnect everything from the AppDomain, we can make use of the IRegisteredObject pattern (doc). The idea is that when the AppDomain needs to shut down, any registered object gets a chance to clean up after itself before the shutdown.

Or even without building this pattern in Edge, if there was some way to call into Edge to explicitly tell it to disconnect, then the Web App author could call it themselves on AppDomain shutdown.

@davideicardi
Copy link

There is any workaround? This can be a really big problem...

@mmanela
Copy link

mmanela commented Aug 26, 2017

@tjanczuk
Is this the same issue I am hitting when trying to run Edge.js from inside of a XUnit.net test inside of VS?
Similiar to this one: (https://stackoverflow.com/questions/45232511/can-i-call-node-js-function-from-mstest)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants