Bug 671113 - Poison JSScripts when freed to get more crash data (r=dmandelin)

This commit is contained in:
Bill McCloskey 2011-07-19 14:21:58 -07:00
Родитель 8aa36b3b5c
Коммит 1b7adf6bc0
5 изменённых файлов: 75 добавлений и 1 удалений

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

@ -559,6 +559,8 @@ JSCompartment::purge(JSContext *cx)
#endif
#ifdef JS_METHODJIT
js::CheckCompartmentScripts(this);
for (JSScript *script = (JSScript *)scripts.next;
&script->links != &scripts;
script = (JSScript *)script->links.next) {

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

@ -1679,8 +1679,12 @@ fun_trace(JSTracer *trc, JSObject *obj)
if (fun->atom)
MarkString(trc, fun->atom, "atom");
if (fun->isInterpreted() && fun->script())
if (fun->isInterpreted() && fun->script()) {
if (fun->script()->compartment != obj->compartment())
JS_Assert("compartment mismatch", __FILE__, __LINE__);
js_TraceScript(trc, fun->script());
}
}
static void

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

@ -2421,6 +2421,9 @@ MarkAndSweep(JSContext *cx, JSCompartment *comp, JSGCInvocationKind gckind GCTIM
printf("GC HEAP SIZE %lu\n", (unsigned long)rt->gcBytes);
}
#endif
for (JSCompartment **c = rt->compartments.begin(); c != rt->compartments.end(); c++)
js::CheckCompartmentScripts(*c);
}
#ifdef JS_THREADSAFE

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

@ -940,6 +940,7 @@ JSScript::NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natom
return NULL;
PodZero(script);
script->cookie1 = script->cookie2 = JS_SCRIPT_COOKIE;
script->length = length;
script->version = version;
new (&script->bindings) Bindings(cx, emptyCallShape);
@ -1082,6 +1083,7 @@ JSScript::NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natom
#endif
JS_APPEND_LINK(&script->links, &cx->compartment->scripts);
JS_ASSERT(script->getVersion() == version);
return script;
}
@ -1274,9 +1276,46 @@ js_CallDestroyScriptHook(JSContext *cx, JSScript *script)
JS_ClearScriptTraps(cx, script);
}
static void
volatile_memcpy(volatile char *dst, void *src, size_t n)
{
for (size_t i = 0; i < n; i++)
dst[i] = ((char *)src)[i];
}
static void
CheckScript(JSScript *script, JSScript *prev)
{
volatile char dbg1[sizeof(JSScript)], dbg2[sizeof(JSScript)];
if (script->cookie1 != JS_SCRIPT_COOKIE || script->cookie2 != JS_SCRIPT_COOKIE) {
volatile_memcpy(dbg1, script, sizeof(JSScript));
if (prev)
volatile_memcpy(dbg2, prev, sizeof(JSScript));
*(int*)0 = 0;
}
}
namespace js {
void
CheckCompartmentScripts(JSCompartment *comp)
{
JSScript *prev = NULL;
for (JSScript *script = (JSScript *)comp->scripts.next;
&script->links != &comp->scripts;
prev = script, script = (JSScript *)script->links.next)
{
CheckScript(script, prev);
}
}
} /* namespace js */
static void
DestroyScript(JSContext *cx, JSScript *script)
{
CheckScript(script, NULL);
if (script->principals)
JSPRINCIPALS_DROP(cx, script->principals);
@ -1332,6 +1371,7 @@ DestroyScript(JSContext *cx, JSScript *script)
script->pcCounters.destroy(cx);
memset(script, JS_FREE_PATTERN, script->totalSize());
cx->free_(script);
}
@ -1361,6 +1401,12 @@ js_DestroyCachedScript(JSContext *cx, JSScript *script)
void
js_TraceScript(JSTracer *trc, JSScript *script)
{
CheckScript(script, NULL);
JSRuntime *rt = trc->context->runtime;
if (rt->gcCheckCompartment && script->compartment != rt->gcCheckCompartment)
JS_Assert("compartment mismatch in GC", __FILE__, __LINE__);
JSAtomMap *map = &script->atomMap;
MarkAtomRange(trc, map->length, map->vector, "atomMap");

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

@ -420,6 +420,8 @@ class JSPCCounters {
}
};
static const uint32 JS_SCRIPT_COOKIE = 0xc00cee;
struct JSScript {
/*
* Two successively less primitive ways to make a new JSScript. The first
@ -444,6 +446,8 @@ struct JSScript {
jsbytecode *code; /* bytecodes and their immediate operands */
uint32 length; /* length of code vector */
uint32 cookie1;
private:
uint16 version; /* JS version under which script was compiled */
@ -528,6 +532,8 @@ struct JSScript {
/* array of execution counters for every JSOp in the script, by runmode */
JSPCCounters pcCounters;
uint32 cookie2;
public:
#ifdef JS_METHODJIT
// Fast-cached pointers to make calls faster. These are also used to
@ -732,6 +738,19 @@ js_DestroyScriptFromGC(JSContext *cx, JSScript *script);
extern void
js_DestroyCachedScript(JSContext *cx, JSScript *script);
namespace js {
/*
* This diagnostic function checks that a compartment's list of scripts
* contains only valid scripts. It also searches for the target script
* in the list. If expected is true, it asserts that the target script
* is found. If expected is false, it asserts that it's not found.
*/
void
CheckCompartmentScripts(JSCompartment *comp);
} /* namespace js */
extern void
js_TraceScript(JSTracer *trc, JSScript *script);