Assertion failure: requestDebit <= rt->requestCount in jsgc.c when destroying context

UNCONFIRMED
Unassigned

Status

()

UNCONFIRMED
9 years ago
4 years ago

People

(Reporter: gwurk, Unassigned)

Tracking

Firefox Tracking Flags

(Not tracked)

Details

(Reporter)

Description

9 years ago
User-Agent:       Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.9 Safari/533.2
Build Identifier: 

I first noticed this problem in SpiderMonkey 1.8.0-rc1, although I think the bug exists in earlier versions as well. When running with JS_THREADSAFE enabled, and DEBUG turned on, I get this error when I JS_DestroyContext() a context from inside a request:

Assertion failure: requestDebit <= rt->requestCount, at jsgc.c:3089

Here is a short test case to reproduce the failure:

    #include "jsapi.h"

    int main() {
      JSRuntime* rt1 = JS_NewRuntime(10000);
      JSContext* cx1 = JS_NewContext(rt1, 8192);
      JS_BeginRequest(cx1);

      // while inside a request on cx1, destroy another context in a 
      // different runtime:
      JSRuntime* rt2 = JS_NewRuntime(10000);
      JSContext* cx2 = JS_NewContext(rt2, 8192);
      JS_DestroyContext(cx2);  // fails here

      return 0;
    }

Here's why I think this bug is happening: In js_GC(), you count up all the contexts that are inside active requests like this:

        head = &cx->thread->contextList;
        for (link = head->next; link != head; link = link->next) {
            acx = CX_FROM_THREAD_LINKS(link);
            JS_ASSERT(acx->thread == cx->thread);
            if (acx->requestDepth)
                requestDebit++;
        }

requestDebit holds the number of contexts with active requests from ALL runtimes in the thread. In the test case above, cx1 has one active request. But then you assert that:

        JS_ASSERT(requestDebit <= rt->requestCount);

This compares requestDebit against the current runtime only (rt2 in the test case), which happens to have no active requests, triggering the failure.

Reproducible: Always
(Assignee)

Updated

4 years ago
Assignee: general → nobody
You need to log in before you can comment on or make changes to this bug.