Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

segfault/bus error in loop

#21

hi,

i have the following problem. i want to build a serverside JS framework ontop of cherrypy. here is the code that freezes when executing:

#!/bin/env python

import spidermonkey

rt = spidermonkey.Runtime()

class Session(object):
    def __init__(self):
        self.asdf = 0
        
    def set(self, key):
        return key

def app():
    cx = rt.new_context()
    cx.add_global('session', Session)
    
    data = cx.execute('new session().set(Math.random());')
    return [str(data)]

for i in range(1, 1000):
    print app()

the code freezes between the 10 to 15th execution. Sometime it segfaults, somtimes it only freezes ans sometimes i get an "Bus Error".

i have to get a fresh context on every request in order to get rid of the old code, that has been executed before. moving new_context() and add_global() out of the function solves the problem but then i have no clean environment to work with. is there a way to recycle an existing context in order skip creating a new one?

i'm using the latest trunk version on mac os x 10.5 with python 2.6.

thanks in advance,

cheers marc

Reported by marc · June 25th, 2009 @ 06:11 PM

State: resolved
Milestone: none
Assigned to: Paul J. Davis Paul J. Davis

Activity

  1. Paul J. Davis
    Paul J. Davis
    • Tag set to segfault, session-creation

    Marc,

    Interesting. I'll take a look tonight or tomorrowish when I get a chance. Off the top of my head there's no real good way to clean a context completely after use.

    There is another pattern that I've seen used to create a subcontext. This would basically be something along the lines of you create your context, add the Session global, and then use sub contexts on each request. I'm not sure how much that saves or even what the current issue is though, but it might be something I could add.

    I'll post more when after I peep some back traces.

    June 25th, 2009 @ 07:11 PM

  2. Paul J. Davis
    Paul J. Davis
    • Tag changed from segfault, session-creation to segfault, session-creation, wtf

    Looking into this suggests a fairly non-trivial bug somewhere. It appears to be deterministic though, so at least there's that.

    Initial inspection shows things deadlocking in garbage collection when cycling through the test case. The traceback shows a deadlock in JS_BeginRequest from jsobject's finalize method. No matter what I do it just appears to move the deadlock or create a segfault. I did a bit of auditing on the begin/end requests and found a mismatch, but after fixing it appears unrelated.

    When trying to address the possibly maybe related causes I end up just pushing a repeatable error to different parts of the code. As a result, my hunch is that this is some sort of memory error. I'm a bit disadvantaged investigating at the moment, but maybe something will come to me in a bit. For the time being this is the main stack trace I'm getting when running:

    Program received signal SIGINT, Interrupt.
    0x9208e46e in __semwait_signal ()
    0  0x9208e46e in __semwait_signal ()
    1  0x920b93e6 in _pthread_cond_wait ()
    2  0x920b8dcd in pthread_cond_wait$UNIX2003 ()
    3  0x0156d921 in PR_WaitCondVar ()
    4  0x0143fe86 in JS_BeginRequest (cx=0x480f420) at jsapi.c:823
    5  0x0143eac5 in get_py_obj [inlined] () at pyobject.c:222
    6  0x0143eac5 in js_finalize (jscx=0x480f420, jsobj=0xca8fb8) at pyobject.c:223
    7  0x014a7a95 in js_DropObjectMap [inlined] () at jsobj.c:2750
    8  0x014a7a95 in js_FinalizeObject (cx=0x480f420, obj=0x480f420) at jsobj.c:2753
    9  0x01483bd6 in js_GC (cx=0x480f420, gckind=GC_NORMAL) at jsgc.c:3028
    10 0x01446e28 in JS_MaybeGC (cx=0x480f420) at jsapi.c:1873
    11 0x0143aaf0 in Context_execute (self=0x1417f00, args=0x4, kwargs=0x0) at context.c:589
    

    Calum, if you can run the ./go command in the root directory to check the top of your stack trace that'd be great. You'll need to add this test case to trigger:

    import t
    
    class Session(object):
        def __init__(self):
            self.asdf = 0
    
        def set(self, key):
           return key
    
    @t.rt()
    def test_turnover(rt):
        for i in range(1000):
            cx = rt.new_context()
            cx.add_global('session', Session)
            data = cx.execute('new session().set(Math.random());')
            t.ne(data, None)
    

    Other things of interest: Putting the 'cx = rt.new_context()' statement outside the loop alleviates the issue. Looking at the create/destroy methods I don't see anything obvious. Also, I run these tests in a single process with nosetests so its a bit odd that just running a couple creates in a tight loop is triggering this when running the tests normally doesn't.

    I am perplexed.

    June 25th, 2009 @ 11:32 PM

  3. marc
    marc

    hi paul,

    thank for your effort to get into it and for investigating this strange behaviour.
    another funny thing is, that moving the

    rt = spidermonkey.Runtime()
    œœœ
    
    into the loop, results in a Bus Error after exactly 128 cycles.
    i'm sorry for just reporting this issue without directly submitting patches/solutions, but i'm not familar with c.
    
    thank you in advance.
    cheers from germany,
    
    marc
    

    June 26th, 2009 @ 04:38 AM

  4. marc
    marc

    ouch...sorry, i've forgotten to close the code-block :)

    June 26th, 2009 @ 04:39 AM

  5. Paul J. Davis
    Paul J. Davis
    • State changed from new to resolved

    (from [6d5e357f9cd4ae3cfaaf25aafbf6c121cf519ac2]) Fix segfaults when large numbers of contexts.

    Turns out that I had an error in my logic about how to reference count
    the python context object. I removed references to it from Python
    objects that are wrapped in the JavaScript VM. I'm more than 50% certain that
    this is correct as when the Python context dies, it'll destroy the
    JSContext* and along with it all references to Python objects that need
    refernces to the Context.

    [#21 segfault/bus error in loop state:resolved] http://github.com/davisp/python-spidermonkey/commit/6d5e357f9cd4ae3...

    June 26th, 2009 @ 07:46 PM

  6. Paul J. Davis
    Paul J. Davis

    marc,

    Can you pull github and double check that the error is fixed for you?

    Paul

    June 26th, 2009 @ 07:47 PM

  7. marc
    marc

    hi paul,

    okay i've tested it with the git version and it works like a charm. thank you for solving the problem so fast.

    cheers marc

    June 28th, 2009 @ 06:47 PM

  8. Paul J. Davis
    Paul J. Davis

    marc,

    Cool. I'll version bump and push to PyPI

    Paul

    June 28th, 2009 @ 07:24 PM

  9. Paul J. Davis

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.