Last Comment Bug 677597 - [jsdbg2] Crash [@ JSObject::getParent]
: [jsdbg2] Crash [@ JSObject::getParent]
Status: RESOLVED FIXED
: crash, testcase
Product: Core
Classification: Components
Component: JavaScript Engine (show other bugs)
: Other Branch
: x86_64 Linux
: -- critical (vote)
: ---
Assigned To: general
:
:
Mentors:
Depends on:
Blocks: langfuzz
  Show dependency treegraph
 
Reported: 2011-08-09 10:42 PDT by Christian Holler (:decoder)
Modified: 2012-01-11 11:21 PST (History)
5 users (show)
See Also:
Crash Signature:
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---


Attachments

Description Christian Holler (:decoder) 2011-08-09 10:42:59 PDT
The following code crashes on jsdbg2 branch (revision f189dd6316eb, options -j -m -a -d):


var g = newGlobal('new-compartment');
g.eval("function f(frame) { n++; return 42; }");
var dbg = Debugger(g);
dbg.onEnterFrame = g.f;
dbg.onDebuggerStatement = function (frame) {
};
dbg.onExceptionUnwind = function (frame) {
    g.log += 'BAD';
};
g.eval("debugger; log += ' ok';");



Valgrind backtrace:

==3624== Invalid read of size 8
==3624==    at 0x41236A: JSObject::getParent() const (jsobj.h:761)
==3624==    by 0x4FF551: JSObject::getGlobal() const (jsobj.cpp:6413)
==3624==    by 0x5DAA55: js::Debugger::removeDebuggeeGlobal(JSContext*, js::GlobalObject*, js::detail::HashTable<js::GlobalObject* const, js::HashSet<js::GlobalObject*, js::DefaultHasher<js::GlobalObject*>, js::SystemAllocPolicy>::SetOps, js::SystemAllocPolicy>::Enum*, js::detail::HashTable<js::GlobalObject* const, js::HashSet<js::GlobalObject*, js::DefaultHasher<js::GlobalObject*>, js::SystemAllocPolicy>::SetOps, js::SystemAllocPolicy>::Enum*) (Debugger.cpp:1578)
==3624==    by 0x5D8F40: js::Debugger::sweepAll(JSContext*) (Debugger.cpp:1111)
==3624==    by 0x4BD63B: MarkAndSweep(JSContext*, JSCompartment*, JSGCInvocationKind, js::GCTimer&) (jsgc.cpp:2344)
==3624==    by 0x4BDB93: GCCycle(JSContext*, JSCompartment*, JSGCInvocationKind, js::GCTimer&) (jsgc.cpp:2643)
==3624==    by 0x4BDE78: js_GC(JSContext*, JSCompartment*, JSGCInvocationKind) (jsgc.cpp:2729)
==3624==    by 0x467FA2: js_DestroyContext(JSContext*, JSDestroyContextMode) (jscntxt.cpp:533)
==3624==    by 0x4302CD: JS_DestroyContext (jsapi.cpp:1002)
==3624==    by 0x4102BD: DestroyContext(JSContext*, bool) (js.cpp:5191)
==3624==    by 0x41147B: main (js.cpp:5643)
==3624==  Address 0x18002c is not stack'd, malloc'd or (recently) free'd
Comment 1 Jason Orendorff [:jorendorff] 2011-08-09 13:44:19 PDT
Slightly reduced:

var g = newGlobal('new-compartment');
g.eval("function f(frame) { DIE; }");
var dbg = Debugger(g);
dbg.onEnterFrame = g.f;
dbg.onExceptionUnwind = function (frame) {
    g.log += 'BAD';
};
g.eval("2 + 2");

The invariant being violated here is that for every ScriptDebugPrologue call there must be a matching (properly nested) ScriptDebugEpilogue call. Otherwise Debugger::frames can have a dangling frame pointer in it.
Comment 2 Jason Orendorff [:jorendorff] 2011-08-10 13:54:25 PDT
The parse tree is like:

(with 1
  (seq
    (var (name b 2))
    (for (in #null (name b 2) 3)
      (semi #null))))

Those two (name) nodes have distinct addresses (one is a clone of the other, I guess) but both refer to the same 2 node.
Comment 3 Jason Orendorff [:jorendorff] 2011-08-10 14:01:02 PDT
Sorry, that was intended for bug 672892.
Comment 4 Jim Blandy :jimb 2012-01-11 11:21:58 PST
This seems to have been fixed by changeset 746e5c170b36, fixing bug 672829.

Note You need to log in before you can comment on or make changes to this bug.