Bug 1491313. Add some MOZ_CRASH instrumentation to help figure out why ClearDocumentDependentSlots hits its MOZ_CRASH case. r=mccr8

We need the isDOMClass() checks in the Compartment code to pass tests, because
some of the jsapi tests explicitly test those failure codepaths.  But not with
DOM objects, which is what we're interested in here.

Differential Revision: https://phabricator.services.mozilla.com/D6047

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Boris Zbarsky 2018-09-18 02:31:03 +00:00
Родитель 6d56c9b541
Коммит 8e04fc97a0
4 изменённых файлов: 116 добавлений и 9 удалений

Просмотреть файл

@ -44,6 +44,7 @@
class nsGenericHTMLElement;
class nsIJSID;
class nsIDocument;
namespace mozilla {
@ -53,6 +54,7 @@ namespace dom {
class CustomElementReactionsStack;
class MessageManagerGlobal;
template<typename KeyType, typename ValueType> class Record;
class Location;
nsresult
UnwrapArgImpl(JSContext* cx, JS::Handle<JSObject*> src, const nsIID& iid,
@ -1060,8 +1062,30 @@ struct CheckWrapperCacheTracing<T, true>
void
AssertReflectorHasGivenProto(JSContext* aCx, JSObject* aReflector,
JS::Handle<JSObject*> aGivenProto);
#endif // DEBUG
template <class T>
MOZ_ALWAYS_INLINE void
CrashIfDocumentOrLocationWrapFailed()
{
// Do nothing.
}
template<>
MOZ_ALWAYS_INLINE void
CrashIfDocumentOrLocationWrapFailed<nsIDocument>()
{
MOZ_CRASH("Looks like bug 1488480/1405521, with WrapObject() on nsIDocument throwing");
}
template<>
MOZ_ALWAYS_INLINE void
CrashIfDocumentOrLocationWrapFailed<Location>()
{
MOZ_CRASH("Looks like bug 1488480/1405521, with WrapObject() on Location throwing");
}
template <class T, GetOrCreateReflectorWrapBehavior wrapBehavior>
MOZ_ALWAYS_INLINE bool
DoGetOrCreateDOMReflector(JSContext* cx, T* value,
@ -1084,6 +1108,7 @@ DoGetOrCreateDOMReflector(JSContext* cx, T* value,
// At this point, obj is null, so just return false.
// Callers seem to be testing JS_IsExceptionPending(cx) to
// figure out whether WrapObject() threw.
CrashIfDocumentOrLocationWrapFailed<T>();
return false;
}
@ -1113,19 +1138,35 @@ DoGetOrCreateDOMReflector(JSContext* cx, T* value,
rval.set(JS::ObjectValue(*obj));
if (js::GetObjectCompartment(obj) == js::GetContextCompartment(cx)) {
return TypeNeedsOuterization<T>::value ? TryToOuterize(rval) : true;
if (!TypeNeedsOuterization<T>::value) {
return true;
}
if (TryToOuterize(rval)) {
return true;
}
return false;
}
if (wrapBehavior == eDontWrapIntoContextCompartment) {
if (TypeNeedsOuterization<T>::value) {
JSAutoRealm ar(cx, obj);
return TryToOuterize(rval);
if (TryToOuterize(rval)) {
return true;
}
return false;
}
return true;
}
return JS_WrapValue(cx, rval);
if (JS_WrapValue(cx, rval)) {
return true;
}
MOZ_CRASH("Looks like bug 1488480/1405521, with JS_WrapValue failing");
return false;
}
} // namespace binding_detail

Просмотреть файл

@ -4015,6 +4015,14 @@ class CGClearCachedValueMethod(CGAbstractMethod):
saveMember = (
"JS::Rooted<JS::Value> oldValue(aCx, js::GetReservedSlot(obj, %s));\n" %
slotIndex)
if self.descriptor.name == "Document" or self.descriptor.name == "Location":
maybeCrash = dedent(
"""
MOZ_CRASH("Looks like bug 1488480/1405521, with the getter failing");
""")
else:
maybeCrash = ""
regetMember = fill(
"""
JS::Rooted<JS::Value> temp(aCx);
@ -4022,12 +4030,14 @@ class CGClearCachedValueMethod(CGAbstractMethod):
JSAutoRealm ar(aCx, obj);
if (!get_${name}(aCx, obj, aObject, args)) {
js::SetReservedSlot(obj, ${slotIndex}, oldValue);
$*{maybeCrash}
return false;
}
return true;
""",
name=self.member.identifier.name,
slotIndex=slotIndex)
slotIndex=slotIndex,
maybeCrash=maybeCrash)
else:
declObj = "JSObject* obj;\n"
noopRetval = ""
@ -6681,6 +6691,11 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
# threw an exception.
failed = ("MOZ_ASSERT(JS_IsExceptionPending(cx));\n" +
exceptionCode)
if descriptor.name == "Document" or descriptor.name == "Location":
failed = (
'MOZ_CRASH("Looks like bug 1488480/1405521, with getting the reflector failing");\n' +
failed)
else:
if descriptor.notflattened:
getIID = "&NS_GET_IID(%s), " % descriptor.nativeType
@ -7836,6 +7851,14 @@ class CGPerSignatureCall(CGThing):
"args.rval().isObject()")
postConversionSteps += freezeValue.define()
if self.descriptor.name == "Window":
maybeCrash = dedent(
"""
MOZ_CRASH("Looks like bug 1488480/1405521, with the other MaybeWrap failing");
""")
else:
maybeCrash = ""
# slotStorageSteps are steps that run once we have entered the
# slotStorage compartment.
slotStorageSteps= fill(
@ -7843,11 +7866,13 @@ class CGPerSignatureCall(CGThing):
// Make a copy so that we don't do unnecessary wrapping on args.rval().
JS::Rooted<JS::Value> storedVal(cx, args.rval());
if (!${maybeWrap}(cx, &storedVal)) {
$*{maybeCrash}
return false;
}
js::SetReservedSlot(slotStorage, slotIndex, storedVal);
""",
maybeWrap=getMaybeWrapValueFuncForType(self.idlNode.type))
maybeWrap=getMaybeWrapValueFuncForType(self.idlNode.type),
maybeCrash=maybeCrash)
checkForXray = mayUseXrayExpandoSlots(self.descriptor, self.idlNode)
@ -7885,6 +7910,14 @@ class CGPerSignatureCall(CGThing):
else:
conversionScope = "slotStorage"
if self.descriptor.name == "Window":
maybeCrash = dedent(
"""
MOZ_CRASH("Looks like bug 1488480/1405521, with the third MaybeWrap failing");
""")
else:
maybeCrash = ""
wrapCode = fill(
"""
{
@ -7900,13 +7933,18 @@ class CGPerSignatureCall(CGThing):
$*{slotStorageSteps}
}
// And now make sure args.rval() is in the caller realm.
return ${maybeWrap}(cx, args.rval());
if (${maybeWrap}(cx, args.rval())) {
return true;
}
$*{maybeCrash}
return false;
""",
conversionScope=conversionScope,
wrapCode=wrapCode,
postConversionSteps=postConversionSteps,
slotStorageSteps=slotStorageSteps,
maybeWrap=getMaybeWrapValueFuncForType(self.idlNode.type))
maybeWrap=getMaybeWrapValueFuncForType(self.idlNode.type),
maybeCrash=maybeCrash)
return wrapCode
def define(self):
@ -8938,6 +8976,14 @@ class CGSpecializedGetter(CGAbstractStaticMethod):
""",
slotIndex=memberReservedSlot(self.attr, self.descriptor))
if self.descriptor.name == "Window":
maybeCrash = dedent(
"""
MOZ_CRASH("Looks like bug 1488480/1405521, with cached value wrapping failing");
""")
else:
maybeCrash = ""
prefix += fill(
"""
MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
@ -8948,12 +8994,17 @@ class CGSpecializedGetter(CGAbstractStaticMethod):
args.rval().set(cachedVal);
// The cached value is in the compartment of slotStorage,
// so wrap into the caller compartment as needed.
return ${maybeWrap}(cx, args.rval());
if (${maybeWrap}(cx, args.rval())) {
return true;
}
$*{maybeCrash}
return false;
}
}
""",
maybeWrap=getMaybeWrapValueFuncForType(self.attr.type))
maybeWrap=getMaybeWrapValueFuncForType(self.attr.type),
maybeCrash=maybeCrash)
else:
prefix = ""

Просмотреть файл

@ -92,6 +92,9 @@ JS::Compartment::wrap(JSContext* cx, JS::MutableHandleValue vp)
JS::RootedObject obj(cx, &vp.toObject());
if (!wrap(cx, &obj)) {
if (js::UncheckedUnwrap(&vp.toObject())->getClass()->isDOMClass()) {
MOZ_CRASH("Looks like bug 1488480/1405521, with the object version of Compartment::wrap failing");
}
return false;
}
vp.setObject(*obj);

Просмотреть файл

@ -237,11 +237,17 @@ Compartment::getNonWrapperObjectForCurrentCompartment(JSContext* cx, MutableHand
// see bug 809295.
auto preWrap = cx->runtime()->wrapObjectCallbacks->preWrap;
if (!CheckSystemRecursionLimit(cx)) {
if (obj->getClass()->isDOMClass()) {
MOZ_CRASH("Looks like bug 1488480/1405521, with system recursion limit failing in getNonWrapperObjectForCurrentCompartment");
}
return false;
}
if (preWrap) {
preWrap(cx, cx->global(), obj, objectPassedToWrap, obj);
if (!obj) {
if (UncheckedUnwrap(objectPassedToWrap)->getClass()->isDOMClass()) {
MOZ_CRASH("Looks like bug 1488480/1405521, with preWrap failing in getNonWrapperObjectForCurrentCompartment");
}
return false;
}
}
@ -269,6 +275,9 @@ Compartment::getOrCreateWrapper(JSContext* cx, HandleObject existing, MutableHan
auto wrap = cx->runtime()->wrapObjectCallbacks->wrap;
RootedObject wrapper(cx, wrap(cx, existing, obj));
if (!wrapper) {
if (key.toObject().getClass()->isDOMClass()) {
MOZ_CRASH("Looks like bug 1488480/1405521, with wrap() call failing in Compartment::getOrCreateWrapper");
}
return false;
}
@ -285,6 +294,9 @@ Compartment::getOrCreateWrapper(JSContext* cx, HandleObject existing, MutableHan
if (wrapper->is<CrossCompartmentWrapperObject>()) {
NukeCrossCompartmentWrapper(cx, wrapper);
}
if (obj->getClass()->isDOMClass()) {
MOZ_CRASH("Looks like bug 1488480/1405521, with hashtable ops failing in Compartment::getOrCreateWrapper");
}
return false;
}