Closed Bug 291439 Opened 20 years ago Closed 20 years ago

crash [@ js_SetClassPrototype] because proto isn't rooted in JS_InitClass across call to js_DefineFunction

Categories

(Core :: JavaScript Engine, defect, P3)

x86
Windows XP
defect

Tracking

()

RESOLVED FIXED
mozilla1.8beta2

People

(Reporter: timeless, Assigned: brendan)

Details

(Keywords: crash, js1.5)

Crash Data

Attachments

(1 file)

my tree isn't entirely current, but i'm fairly certain this isn't fixed yet. i can update early next week. I'm abusing too_much_gc by restricting the jsenvironment to about 2k. death is very simple: proto = js_NewObject(cx, clasp, parent_proto, obj); /* creates a happy proto with a map != 0; */ if (!proto) return NULL; if (!constructor) { } else { /* Define the constructor function in obj's scope. */ fun = js_DefineFunction(cx, obj, atom, constructor, nargs, 0); /* destroyed the proto, presumably because it wasn't rooted */ named = (fun != NULL); + proto->map 0x00000000 {nrefs=??? ops=??? nslots=??? ...} JSObjectMap * + fun 0x00baf020 {nrefs=0x00000001 object=0x00ba5bf0 {map=0x00bb1198 {nrefs=0x00000001 ops=0x100fd560 _js_ObjectOps nslots=0x00000005 ...} slots=0x00bac42c } u={native=0x10042550 Function(JSContext *, JSObject *, unsigned int, long *, long *) script=0x10042550 Function(JSContext *, JSObject *, unsigned int, long *, long *) } ...} JSFunction * the call to: > js3250.dll!js_SetClassPrototype(JSContext * cx=0x00bab178, JSObject * ctor=0x00ba5bf0, JSObject * proto=0x00ba5be8, unsigned int attrs=0x00000006) Line 3660 C crashes at: return OBJ_DEFINE_PROPERTY(cx, proto, ATOM_TO_JSID(cx->runtime->atomState .constructorAtom), OBJECT_TO_JSVAL(ctor), JS_PropertyStub, JS_PropertyStub, 0, NULL); because: + proto->map 0x00000000 {nrefs=??? ops=??? nslots=??? ...} JSObjectMap * and obj_define_property wants to use (proto)->map->ops->defineProperty which isn't very reachable > js3250.dll!JS_InitClass(JSContext * cx=0x00bab178, JSObject * obj=0x00ba5ba8, JSObject * parent_proto=0x00000000, JSClass * clasp=0x100ee810, int (JSContext *, JSObject *, unsigned int, long *, long *)* constructor=0x10042550, unsigned int nargs=0x00000001, JSPropertySpec * ps=0x100ee4a0, JSFunctionSpec * fs=0x100ef2e4, JSPropertySpec * static_ps=0x00000000, JSFunctionSpec * static_fs=0x00000000) Line 1969 C js3250.dll!js_InitFunctionClass(JSContext * cx=0x00bab178, JSObject * obj=0x00ba5ba8) Line 1864 + 0x29 C js3250.dll!InitFunctionAndObjectClasses(JSContext * cx=0x00bab178, JSObject * obj=0x00ba5ba8) Line 1135 + 0xd C js3250.dll!JS_ResolveStandardClass(JSContext * cx=0x00bab178, JSObject * obj=0x00ba5ba8, long id=0x00ba58a4, int * resolved=0x0012f448) Line 1422 + 0xb C xpc3250.dll!SafeGlobalResolve(JSContext * cx=0x00bab178, JSObject * obj=0x00ba5ba8, long id=0x00ba58a4) Line 126 + 0x16 C++ js3250.dll!js_LookupPropertyWithFlags(JSContext * cx=0x00bab178, JSObject * obj=0x00ba5ba8, long id=0x00bab808, unsigned int flags=0x00000000, JSObject * * objp=0x0012f58c, JSProperty * * propp=0x0012f57c) Line 2563 + 0x44 C js3250.dll!js_LookupProperty(JSContext * cx=0x00bab178, JSObject * obj=0x00ba5ba8, long id=0x00bab808, JSObject * * objp=0x0012f58c, JSProperty * * propp=0x0012f57c) Line 2421 + 0x1b C js3250.dll!js_GetProperty(JSContext * cx=0x00bab178, JSObject * obj=0x00ba5ba8, long id=0x00bab808, long * vp=0x0012f5b0) Line 2706 + 0x19 C xpc3250.dll!XPCWrappedNativeScope::SetGlobal(XPCCallContext & ccx={...}, JSObject * aGlobal=0x00ba5ba8) Line 190 + 0x20 C++ xpc3250.dll!XPCWrappedNativeScope::XPCWrappedNativeScope(XPCCallContext & ccx={...}, JSObject * aGlobal=0x00ba5ba8) Line 159 C++ xpc3250.dll!XPCWrappedNativeScope::GetNewOrUsed(XPCCallContext & ccx={...}, JSObject * aGlobal=0x00ba5ba8) Line 119 + 0x23 C++ xpc3250.dll!nsXPConnect::InitClasses(JSContext * aJSContext=0x00bab178, JSObject * aGlobalJSObj=0x00ba5ba8) Line 435 + 0xd C++ xpc3250.dll!XPCJSContextStack::GetSafeJSContext(JSContext * * aSafeJSContext=0x0012f708) Line 157 + 0x1d C++ xpc3250.dll!nsXPCThreadJSContextStackImpl::GetSafeJSContext(JSContext * * aSafeJSContext=0x0012f708) Line 333 C++ caps.dll!nsScriptSecurityManager::GetSafeJSContext() Line 229 + 0x1e C++ caps.dll!nsScriptSecurityManager::Init() Line 2818 + 0x8 C++ caps.dll!nsScriptSecurityManager::GetScriptSecurityManager() Line 2892 + 0x8 C++ caps.dll!Construct_nsIScriptSecurityManager(nsISupports * aOuter=0x00000000, const nsID & aIID={...}, void * * aResult=0x0012f8f4) Line 344 + 0x5 C++ xpcom_core.dll!nsGenericFactory::CreateInstance(nsISupports * aOuter=0x00000000, const nsID & aIID={...}, void * * aResult=0x0012f8f4) Line 82 + 0x15 C++ xpcom_core.dll!nsComponentManagerImpl::CreateInstanceByContractID(const char * aContractID=0x00d104c4, nsISupports * aDelegate=0x00000000, const nsID & aIID={...}, void * * aResult=0x0012f8f4) Line 1994 + 0x18 C++ xpcom_core.dll!nsComponentManagerImpl::GetServiceByContractID(const char * aContractID=0x00d104c4, const nsID & aIID={...}, void * * result=0x0012f95c) Line 2421 + 0x32 C++ xpcom_core.dll!CallGetService(const char * aContractID=0x00d104c4, const nsID & aIID={...}, void * * aResult=0x0012f95c) Line 93 C++ xpcom_core.dll!nsGetServiceByContractID::operator()(const nsID & aIID={...}, void * * aInstancePtr=0x0012f95c) Line 276 + 0x13 C++ xpc3250.dll!nsCOMPtr<nsIScriptSecurityManager>::assign_from_gs_contractid(nsGetServiceByContractID gs={...}, const nsID & aIID={...}) Line 1272 + 0x11 C++ xpc3250.dll!nsCOMPtr<nsIScriptSecurityManager>::nsCOMPtr<nsIScriptSecurityManager>(nsGetServiceByContractID gs={...}) Line 678 C++ xpc3250.dll!mozJSComponentLoader::ReallyInit() Line 433 C++ xpc3250.dll!mozJSComponentLoader::ModuleForLocation(const char * registryLocation=0x00bd07f8, nsIFile * component=0x00000000) Line 829 + 0x17 C++ xpc3250.dll!mozJSComponentLoader::GetFactory(const nsID & aCID={...}, const char * aLocation=0x00bd07f8, const char * aType=0x00bcbcf0, nsIFactory * * _retval=0x0012fb84) Line 384 + 0xe C++ xpcom_core.dll!nsFactoryEntry::GetFactory(nsIFactory * * aFactory=0x0012fb84, nsComponentManagerImpl * mgr=0x0038f380) Line 302 + 0x3a C++ xpcom_core.dll!nsComponentManagerImpl::CreateInstanceByContractID(const char * aContractID=0x00b9f8e8, nsISupports * aDelegate=0x00000000, const nsID & aIID={...}, void * * aResult=0x0012fbe4) Line 1989 + 0x10 C++ xpcom_core.dll!nsComponentManagerImpl::GetServiceByContractID(const char * aContractID=0x00b9f8e8, const nsID & aIID={...}, void * * result=0x0012fc4c) Line 2421 + 0x32 C++ xpcom_core.dll!CallGetService(const char * aContractID=0x00b9f8e8, const nsID & aIID={...}, void * * aResult=0x0012fc4c) Line 93 C++ xpcom_core.dll!nsGetServiceByContractIDWithError::operator()(const nsID & aIID={...}, void * * aInstancePtr=0x0012fc4c) Line 286 + 0x13 C++ xpcom_core.dll!nsCOMPtr_base::assign_from_gs_contractid_with_error(const nsGetServiceByContractIDWithError & gs={...}, const nsID & iid={...}) Line 141 + 0x10 C++ xpcom_core.dll!nsCOMPtr<nsISupports>::nsCOMPtr<nsISupports>(const nsGetServiceByContractIDWithError & gs={...}) Line 1007 C++ xpcom_core.dll!NS_CreateServicesFromCategory(const char * category=0x004ddbc0, nsISupports * origin=0x00000000, const char * observerTopic=0x004ddbb0) Line 817 C++ xpcom_core.dll!NS_InitXPCOM2_P(nsIServiceManager * * result=0x0012ff40, nsIFile * binDirectory=0x00000000, nsIDirectoryServiceProvider * appFileLocationProvider=0x00000000) Line 683 + 0x11 C++ xpcshell.exe!main(int argc=0x00000001, char * * argv=0x00387040, char * * envp=0x00382f88) Line 1499 + 0x22 C++ xpcshell.exe!mainCRTStartup() Line 398 + 0x11 C kernel32.dll!_BaseProcessStart@4() + 0x23
actual death is caused by: js3250.dll!js_GC(JSContext * cx=0x00bab178, unsigned int gcflags=0x00000005) Line ... C js3250.dll!js_NewGCThing(JSContext * cx=0x00bab178, unsigned int flags=0x00000004, unsigned int nbytes=0x00000018) Line 637 + 0xb C js3250.dll!AllocSlots(JSContext * cx=0x00bab178, long * slots=0x00000000, unsigned long nslots=0x00000005) Line 1797 + 0xf C js3250.dll!js_NewObject(JSContext * cx=0x00bab178, JSClass * clasp=0x100ee810, JSObject * proto=0x00000000, JSObject * parent=0x00ba5ba8) Line 1916 + 0xf C js3250.dll!js_NewFunction(JSContext * cx=0x00bab178, JSObject * funobj=0x00000000, int (JSContext *, JSObject *, unsigned int, long *, long *)* native=0x10042550, unsigned int nargs=0x00000001, unsigned int flags=0x00000000, JSObject * parent=0x00ba5ba8, JSAtom * atom=0x00bab678) Line 1909 + 0x14 C js3250.dll!js_DefineFunction(JSContext * cx=0x00bab178, JSObject * obj=0x00ba5ba8, JSAtom * atom=0x00bab678, int (JSContext *, JSObject *, unsigned int, long *, long *)* native=0x10042550, unsigned int nargs=0x00000001, unsigned int attrs=0x00000000) Line 1971 + 0x1f C > js3250.dll!JS_InitClass(JSContext * cx=0x00bab178, JSObject * obj=0x00ba5ba8, JSObject * parent_proto=0x00000000, JSClass * clasp=0x100ee810, int (JSContext *, JSObject *, unsigned int, long *, long *)* constructor=0x10042550, unsigned int nargs=0x00000001, JSPropertySpec * ps=0x100ee4a0, JSFunctionSpec * fs=0x100ef2e4, JSPropertySpec * static_ps=0x00000000, JSFunctionSpec * static_fs=0x00000000) Line 1968 + 0x1b C
Keywords: crash
I had a patch for this bug at one point. Ah, there it is in attachment 120665 [details] [diff] [review], from bug 123668: @@ -1833,20 +1858,30 @@ JS_InitClass(JSContext *cx, JSObject *ob if (!constructor) { /* Lacking a constructor, name the prototype (e.g., Math). */ named = OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, OBJECT_TO_JSVAL(proto), NULL, NULL, 0, NULL); if (!named) goto bad; ctor = proto; } else { - /* Define the constructor function in obj's scope. */ + /* + * Define the constructor function in obj's scope. The object newborn + * root pigeon-hole in cx will be overwritten with fun->object, so we + * must mark proto in case the GC-private allocation of fun->object's + * slots causes a last-ditch GC. + * YYY remove this when initial slots are fused with fun->object in one + * extended GC-thing allocation + */ + uint8 *flagp = js_GetGCThingFlags(proto); + *flagp |= GCF_MARK; fun = js_DefineFunction(cx, obj, atom, constructor, nargs, 0); + *flagp &= ~GCF_MARK; named = (fun != NULL); if (!fun) goto bad; /* * Remember the class this function is a constructor for so that * we know to create an object of this class when we call the * constructor. */ It's a hack, but it's cheaper and more isolated than pushing a local root scope. Shaver, what do you think? /be
Assignee: general → brendan
Status: UNCONFIRMED → NEW
Ever confirmed: true
Keywords: js1.5
Priority: -- → P3
Target Milestone: --- → mozilla1.8beta2
Can js_DefineFunction, perhaps with TOO_MUCH_GC in play, cause more than one GC? (I'm thinking of a callout to a script-running debugger, or even perhaps some clever getters and setters in the obj on which we're defining.) I agree that it's better than pushing a scope, but wonder if it's sufficient.
fun = (JSFunction *) js_NewGCThing(cx, GCX_PRIVATE, sizeof(JSFunction)); /* ... if (!funobj) */ funobj = js_NewObject(cx, &js_FunctionClass, NULL, parent); that looks like two gc's. for kicks, js_NewObject does: obj = (JSObject *) js_NewGCThing(cx, GCX_OBJECT, sizeof(JSObject)); /* ... */ newslots = AllocSlots(cx, NULL, nslots); And AllocSlots can trigger a GC, so i count at least three.
Right, that won't work! ;-) Old patch, obsoleted; nm. timeless's patch is pretty good, although awful is too much for me to swallow. I'll take it, though, and r/a=me check it in. Thanks, timeless! /be
Status: NEW → ASSIGNED
Comment on attachment 181529 [details] [diff] [review] i couldn't find anything to root proto As promised. /be
Attachment #181529 - Flags: review+
Attachment #181529 - Flags: approval1.8b2+
Comment on attachment 181529 [details] [diff] [review] i couldn't find anything to root proto >+ js_LeaveLocalRootScope(cx); ... >+ JS_LeaveLocalRootScope(cx); Is the js vs. JS difference intentional?
Fixed (I renamed awful to bad2, boring but consonant; I fixed the JS_ to be js_). /be
Status: ASSIGNED → RESOLVED
Closed: 20 years ago
Resolution: --- → FIXED
Flags: testcase-
Crash Signature: [@ js_SetClassPrototype]
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: