On Tue, Dec 11, 2018 at 6:27 PM Kenton Varda <ken...@cloudflare.com> wrote:
> Hi Michael, > > Thanks for looking at this! > > I wish I could come up with a simple repro. Currently my only repro > involves running load test traffic (captured from production) through a > test instance for about a minute before the crash happens. > > My refactoring does a bunch of things differently from before and it's > hard to revert them one by one. There's one big main thing that is > different: Previously, for each wrapper, I'd create one weak persistent > handle for the purpose of receiving a callback to delete the object, and > then additional persistent handles for each reference held by some other > native object (which may or may not be weak depending on whether the holder > is itself GC traceable). In the new code, I instead keep only one > persistent handle per wrapper, and I separately track a "strong reference > count"; when the strong refcount becomes zero I call SetWeak(), and when it > becomes non-zero I call ClearWeak(). So the same handle may switch between > weak and non-weak. > > This transitioning between weak and non-weak seems like it could confuse > the scavenger *if* it happened during scavenging. However, AFAICT, there's > no way this could happen, since there are no callbacks into application > code during scavenging except for weak callbacks... and in my case, those > weak callbacks are actually never called during scavenging, because I have > a scavenge prologue callback that iterates over all weak handles to wrapper > objects and calls MarkActive() on them. > > I really hope that handles are only access from the same thread the GC is running on. Otherwise, you would need a v8::Locker to synchronize that access. Also, you are marking *all* handles with MarkActive()? That should essentially make all of the handles strong for the Scavenger. That contradicts with the crash happening after IterateNewSpaceWeakUnmodifiedRootsForPhantomHandles which deals with weak handles that are not marked as active. (Assuming you did not use MarkIndependent()). > I don't expect you to be able to figure this out for me, but do you have > any hints for debugging strategies I should try? > Essentially, it looks like you are scavenging a root node twice, which is why you already see it in ToSpace when it's getting added through the visitor. The relevant functions are in src/global-handles.{h,cc} and called throughout scavenging in this order: 1. IdentifyWeakUnmodifiedObjects <https://cs.chromium.org/chromium/src/v8/src/global-handles.cc?q=IdentifyWeakUnmodifiedObjects&sq=package:chromium&g=0&l=673>: Makes nodes active that V8 thinks should be active in addition to those that already had MarkActive() called on them. 2. IterateNewSpaceStrongAndDependentRoots <https://cs.chromium.org/chromium/src/v8/src/global-handles.cc?type=cs&q=IterateNewSpaceStrongAndDependentRoots&sq=package:chromium&g=0&l=646>: Scavenges strong handles and those that are active. 3. MarkNewSpaceWeakUnmodifiedObjectsPending <https://cs.chromium.org/chromium/src/v8/src/global-handles.cc?type=cs&q=MarkNewSpaceWeakUnmodifiedObjectsPending&sq=package:chromium&g=0&l=682>: Identifies nodes that require finalizers. 4. IterateNewSpaceWeakUnmodifiedRootsForFinalizers <https://cs.chromium.org/chromium/src/v8/src/global-handles.cc?type=cs&q=IterateNewSpaceWeakUnmodifiedRootsForFinalizers&sq=package:chromium&g=0&l=695>: Scavengers nodes that require finalizers. 5. IterateNewSpaceWeakUnmodifiedRootsForPhantomHandles <https://cs.chromium.org/chromium/src/v8/src/global-handles.cc?type=cs&q=IterateNewSpaceWeakUnmodifiedRootsForPhantomHandles&sq=package:chromium&g=0&l=710>: Resets weak handles or scavenges them. Scavenging here just means updating the forwarding pointer from FromSpace to ToSpace as the object itself has already been scavenged if we don't need to reset it. The sets of handles that are scavenged should be disjoint in 2), 4) and 5). Whenever a node is already pointing directly to ToSpace that should be a bug and some other method probably scavenged it in the same run before. The interesting part is then why multiple methods match the same node for scavenging. Cheers, -Michael -- -- v8-users mailing list v8-users@googlegroups.com http://groups.google.com/group/v8-users --- You received this message because you are subscribed to the Google Groups "v8-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to v8-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.