This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author rupert.summerton
Recipients rupert.summerton
Date 2008-02-12.11:49:18
SpamBayes Score 3.1952826e-05
Marked as misclassified No
Message-id <1202817025.41.0.0817912479052.issue2077@psf.upfronthosting.co.za>
In-reply-to
Content
1. Description: The Python interpretor is crashing on shutdown due to a
segmentation fault:

Unhandled exception at 0x1e03d41f in python.exe: 0xC0000005: Access
violation reading location 0x0000002c.

2. Reproducibility: At least 10% on Windows XP Professional SP2, P4
3.20GHz, 2.00GB RAM, when running the attached module, threadpool.py.
(Running with Python 2.5.1). Unfortunately I cannot get the attached
test case to crash on Linux or Solaris. However, executing this code as
part of our Python test framework (see context below), with Python
2.4.1, what looks like the same crash produced the following backtrace:

#0  reset_exc_info (tstate=0x8254458) at
/tools/src/python/python-2.4.1/Python/ceval.c:2861
        tstate = (PyThreadState *) 0x8254458
        frame = (PyFrameObject *) 0x0
        tmp_type = (PyObject *) 0x82a3a18
        tmp_value = (PyObject *) 0x0
        tmp_tb = (PyObject *) 0x2
#1  0x080a9b56 in PyEval_EvalFrame (f=0x82a38ac) at
/tools/src/python/python-2.4.1/Python/ceval.c:2490
        stack_pointer = (PyObject **) 0x82a3a18
        next_instr = (unsigned char *) 0x81d4f1e ""
        opcode = 136660056
        oparg = 0
        why = WHY_RETURN
        err = 0
        x = (PyObject *) 0x810d940
        v = (PyObject *) 0x81d4f1e
        w = (PyObject *) 0xf6462fc0
        u = (PyObject *) 0xf642ec50
        t = (PyObject *) 0x0
        stream = (PyObject *) 0x0
        fastlocals = (PyObject **) 0x82a39f8
        freevars = (PyObject **) 0x82a3a18
        retval = (PyObject *) 0x810d940
        tstate = (PyThreadState *) 0x8254458
        co = (PyCodeObject *) 0xf6134c60
        instr_ub = -1
        instr_lb = 0
        instr_prev = -1
        first_instr = (unsigned char *) 0x81d4d9c "|"
        names = (PyObject *) 0xf63d762c
        consts = (PyObject *) 0xf6134c2c
#2  0x080aa263 in PyEval_EvalCodeEx (co=0xf6134c60, globals=0xf6075824,
locals=0x0, args=0x82c1080, argcount=2, kws=0x82c1088, kwcount=0,
defs=0xf6414298, 
    defcount=1, closure=0x0) at
/tools/src/python/python-2.4.1/Python/ceval.c:2730
        co = (PyCodeObject *) 0xf6134c60
        globals = (PyObject *) 0x8254458
        locals = (PyObject *) 0x82a38ac
        args = (PyObject **) 0x82c1080
        argcount = 2
        kws = (PyObject **) 0x82c1088
        kwcount = 0
        defs = (PyObject **) 0xf6414298
        defcount = 1
        closure = (PyObject *) 0x0
        f = (PyFrameObject *) 0x82a38ac
        retval = (PyObject *) 0x0
        fastlocals = (PyObject **) 0x82a39f8
        freevars = (PyObject **) 0x82a3a18
        tstate = (PyThreadState *) 0x8254458
        x = (PyObject *) 0x82a38ac
        u = (PyObject *) 0x82a38ac
#3  0x080acda7 in fast_function (func=0xf613e8b4, pp_stack=0xe951f3dc,
n=2, na=2, nk=0) at /tools/src/python/python-2.4.1/Python/ceval.c:3643
        func = (PyObject *) 0x82a38ac
        co = (PyCodeObject *) 0x8254458
        globals = (PyObject *) 0xf6075824
        argdefs = (PyObject *) 0x8254458
        d = (PyObject **) 0xf6414298
        nd = 1
#4  0x080ab08a in call_function (pp_stack=0xe951f3dc, oparg=1) at
/tools/src/python/python-2.4.1/Python/ceval.c:3568
        oparg = 136660056
        na = 2
        nk = 0
        n = 2
        pfunc = (PyObject **) 0x82c1080
        func = (PyObject *) 0xf613e8b4
        x = (PyObject *) 0x8172f54
        w = (PyObject *) 0x82a38ac
#5  0x080a9338 in PyEval_EvalFrame (f=0x82c0f1c) at
/tools/src/python/python-2.4.1/Python/ceval.c:2163
        sp = (PyObject **) 0x82c1088
        stack_pointer = (PyObject **) 0x82c1088
        next_instr = (unsigned char *) 0x81f58cc "\001q\225"
        opcode = 136660056
        oparg = 1
        why = WHY_NOT
        err = 0
        x = (PyObject *) 0x82a37ec
        v = (PyObject *) 0x81f58cc
        w = (PyObject *) 0xf6444de0
        u = (PyObject *) 0xf642ec50
        t = (PyObject *) 0x1
        stream = (PyObject *) 0x0
        fastlocals = (PyObject **) 0x82c1068
        freevars = (PyObject **) 0x82c1080
        retval = (PyObject *) 0x0
        tstate = (PyThreadState *) 0x8254458
        co = (PyCodeObject *) 0xf618c920
        instr_ub = -1
        instr_lb = 0
        instr_prev = -1
        first_instr = (unsigned char *) 0x81f57f4 "|"
        names = (PyObject *) 0xf63a484c
        consts = (PyObject *) 0xf6164a1c
#6  0x080aa263 in PyEval_EvalCodeEx (co=0xf618c920, globals=0xf5d658ac,
locals=0x0, args=0x827d690, argcount=1, kws=0x827d694, kwcount=1,
defs=0xf5d77e78, 
    defcount=2, closure=0x0) at
/tools/src/python/python-2.4.1/Python/ceval.c:2730
        co = (PyCodeObject *) 0xf618c920
        globals = (PyObject *) 0x8254458
        locals = (PyObject *) 0x82a38ac
        args = (PyObject **) 0x8136f18
        argcount = 1
        kws = (PyObject **) 0x827d694
        kwcount = 1
        defs = (PyObject **) 0xf5d77e78
        defcount = 2
        closure = (PyObject *) 0x0
        f = (PyFrameObject *) 0x82c0f1c
        retval = (PyObject *) 0x0
        fastlocals = (PyObject **) 0x82c1068
        freevars = (PyObject **) 0x82c1080
        tstate = (PyThreadState *) 0x8254458
        x = (PyObject *) 0x82a38ac
        u = (PyObject *) 0x82c0f1c
#7  0x080acda7 in fast_function (func=0xf616af7c, pp_stack=0xe951f5ac,
n=3, na=1, nk=1) at /tools/src/python/python-2.4.1/Python/ceval.c:3643
        func = (PyObject *) 0x82a38ac
        co = (PyCodeObject *) 0x8254458
        globals = (PyObject *) 0xf5d658ac
        argdefs = (PyObject *) 0x8254458
        d = (PyObject **) 0xf5d77e78
        nd = 2
#8  0x080ab08a in call_function (pp_stack=0xe951f5ac, oparg=256) at
/tools/src/python/python-2.4.1/Python/ceval.c:3568
        oparg = 136660056
        na = 1
        nk = 1
        n = 3
        pfunc = (PyObject **) 0x827d690
        func = (PyObject *) 0xf616af7c
        x = (PyObject *) 0x81284cc
        w = (PyObject *) 0x82a38ac
#9  0x080a9338 in PyEval_EvalFrame (f=0x827d534) at
/tools/src/python/python-2.4.1/Python/ceval.c:2163
        sp = (PyObject **) 0x827d69c
        stack_pointer = (PyObject **) 0x827d69c
        next_instr = (unsigned char *) 0x81f9e53 "}\002"
        opcode = 136660056
        oparg = 256
        why = WHY_NOT
        err = 0
        x = (PyObject *) 0x8136f18
        v = (PyObject *) 0x81f9e53
        w = (PyObject *) 0xf63cabe0
        u = (PyObject *) 0x18c
        t = (PyObject *) 0x100
        stream = (PyObject *) 0x0
        fastlocals = (PyObject **) 0x827d680
        freevars = (PyObject **) 0x827d690
        retval = (PyObject *) 0x0
        tstate = (PyThreadState *) 0x8254458
        co = (PyCodeObject *) 0xf613f8a0
        instr_ub = -1
        instr_lb = 0
        instr_prev = -1
        first_instr = (unsigned char *) 0x81f9d6c "z\n\003yò\002xë\002|"
        names = (PyObject *) 0xf63cc8c4
        consts = (PyObject *) 0xf6165e9c
#10 0x080acd43 in fast_function (func=0xf6171064, pp_stack=0xe951f6ec,
n=1, na=1, nk=0) at /tools/src/python/python-2.4.1/Python/ceval.c:3629
        retval = (PyObject *) 0x827d680
        fastlocals = (PyObject **) 0x827d680
        i = 136660056
        f = (PyFrameObject *) 0x827d534
        tstate = (PyThreadState *) 0x8254458
        stack = (PyObject **) 0x82a38ac
        func = (PyObject *) 0x82a38ac
        co = (PyCodeObject *) 0x8254458
        globals = (PyObject *) 0x827d680
        argdefs = (PyObject *) 0x8254458
        d = (PyObject **) 0x8254458
        nd = 0
#11 0x080ab08a in call_function (pp_stack=0xe951f6ec, oparg=0) at
/tools/src/python/python-2.4.1/Python/ceval.c:3568
        oparg = 136660056
        na = 1
        nk = 0
        n = 1
        pfunc = (PyObject **) 0x827b2a8
        func = (PyObject *) 0xf6171064
        x = (PyObject *) 0x7f
        w = (PyObject *) 0x82a38ac
#12 0x080a9338 in PyEval_EvalFrame (f=0x827b14c) at
/tools/src/python/python-2.4.1/Python/ceval.c:2163
        sp = (PyObject **) 0x827b2ac
        stack_pointer = (PyObject **) 0x827b2ac
        next_instr = (unsigned char *) 0x81d4b2f "\001Wn)\001\004t\021"
        opcode = 136660056
        oparg = 0
        why = WHY_NOT
        err = 0
        x = (PyObject *) 0xf5e7cd4c
        v = (PyObject *) 0x81d4b2f
        w = (PyObject *) 0xf61360e0
        u = (PyObject *) 0xf5e87f4c
        t = (PyObject *) 0x0
        stream = (PyObject *) 0x0
        fastlocals = (PyObject **) 0x827b298
        freevars = (PyObject **) 0x827b2a8
        retval = (PyObject *) 0x0
        tstate = (PyThreadState *) 0x8254458
        co = (PyCodeObject *) 0xf61386e0
        instr_ub = -1
        instr_lb = 0
        instr_prev = -1
        first_instr = (unsigned char *) 0x81d4a84 "zõ\001t"
        names = (PyObject *) 0xf643295c
        consts = (PyObject *) 0xf613a0cc
#13 0x080aa263 in PyEval_EvalCodeEx (co=0xf61386e0, globals=0xf6075824,
locals=0x0, args=0xf5de6f38, argcount=1, kws=0x0, kwcount=0, defs=0x0,
defcount=0, 
    closure=0x0) at /tools/src/python/python-2.4.1/Python/ceval.c:2730
        co = (PyCodeObject *) 0xf61386e0
        globals = (PyObject *) 0x8254458
        locals = (PyObject *) 0x82a38ac
        args = (PyObject **) 0xf5de6f38
        argcount = 1
        kws = (PyObject **) 0x0
        kwcount = 0
        defs = (PyObject **) 0x0
        defcount = 0
        closure = (PyObject *) 0x0
        f = (PyFrameObject *) 0x827b14c
        retval = (PyObject *) 0x0
        fastlocals = (PyObject **) 0x827b298
        freevars = (PyObject **) 0x827b2a8
        tstate = (PyThreadState *) 0x8254458
        x = (PyObject *) 0x82a38ac
        u = (PyObject *) 0x827b14c
#14 0x080ee2b7 in function_call (func=0xf613edbc, arg=0xf5de6f2c,
kw=0x0) at /tools/src/python/python-2.4.1/Objects/funcobject.c:548
        result = (PyObject *) 0x0
        argdefs = (PyObject *) 0x0
        d = (PyObject **) 0x0
        k = (PyObject **) 0x0
        nk = 136660056
        nd = 0
#15 0x0805a7f4 in PyObject_Call (func=0xf613edbc, arg=0xf5de6f2c,
kw=0x0) at /tools/src/python/python-2.4.1/Objects/abstract.c:1751
        result = (PyObject *) 0xf5de6f2c
        func = (PyObject *) 0x8254458
        call = 0x82a38ac
#16 0x08061497 in instancemethod_call (func=0xf613edbc, arg=0xf642902c,
kw=0x0) at /tools/src/python/python-2.4.1/Objects/classobject.c:2431
        arg = (PyObject *) 0xf5de6f2c
        self = (PyObject *) 0x0
        class = (PyObject *) 0xf5de6f2c
        result = (PyObject *) 0xf5de6f2c
#17 0x0805a7f4 in PyObject_Call (func=0xf5e858c4, arg=0xf642902c,
kw=0x0) at /tools/src/python/python-2.4.1/Objects/abstract.c:1751
        result = (PyObject *) 0xf642902c
        func = (PyObject *) 0x8254458
        call = 0x82a38ac
        co = (PyCodeObject *) 0xf61386e0
        instr_ub = -1
        instr_lb = 0
        instr_prev = -1
        first_instr = (unsigned char *) 0x81d4a84 "zõ\001t"
        names = (PyObject *) 0xf643295c
        consts = (PyObject *) 0xf613a0cc
#13 0x080aa263 in PyEval_EvalCodeEx (co=0xf61386e0, globals=0xf6075824,
locals=0x0, args=0xf5de6f38, argcount=1, kws=0x0, kwcount=0, defs=0x0,
defcount=0, 
    closure=0x0) at /tools/src/python/python-2.4.1/Python/ceval.c:2730
        co = (PyCodeObject *) 0xf61386e0
        globals = (PyObject *) 0x8254458
        locals = (PyObject *) 0x82a38ac
        args = (PyObject **) 0xf5de6f38
        argcount = 1
        kws = (PyObject **) 0x0
        kwcount = 0
        defs = (PyObject **) 0x0
        defcount = 0
        closure = (PyObject *) 0x0
        f = (PyFrameObject *) 0x827b14c
        retval = (PyObject *) 0x0
        fastlocals = (PyObject **) 0x827b298
        freevars = (PyObject **) 0x827b2a8
        tstate = (PyThreadState *) 0x8254458
        x = (PyObject *) 0x82a38ac
        u = (PyObject *) 0x827b14c
#14 0x080ee2b7 in function_call (func=0xf613edbc, arg=0xf5de6f2c,
kw=0x0) at /tools/src/python/python-2.4.1/Objects/funcobject.c:548
        result = (PyObject *) 0x0
        argdefs = (PyObject *) 0x0
        d = (PyObject **) 0x0
        k = (PyObject **) 0x0
        nk = 136660056
        nd = 0
#15 0x0805a7f4 in PyObject_Call (func=0xf613edbc, arg=0xf5de6f2c,
kw=0x0) at /tools/src/python/python-2.4.1/Objects/abstract.c:1751
        result = (PyObject *) 0xf5de6f2c
        func = (PyObject *) 0x8254458
        call = 0x82a38ac
#16 0x08061497 in instancemethod_call (func=0xf613edbc, arg=0xf642902c,
kw=0x0) at /tools/src/python/python-2.4.1/Objects/classobject.c:2431
        arg = (PyObject *) 0xf5de6f2c
        self = (PyObject *) 0x0
        class = (PyObject *) 0xf5de6f2c
        result = (PyObject *) 0xf5de6f2c
#17 0x0805a7f4 in PyObject_Call (func=0xf5e858c4, arg=0xf642902c,
kw=0x0) at /tools/src/python/python-2.4.1/Objects/abstract.c:1751
        result = (PyObject *) 0xf642902c
        func = (PyObject *) 0x8254458
        call = 0x82a38ac
---Type <return> to continue, or q <return> to quit---
#18 0x080ac52b in PyEval_CallObjectWithKeywords (func=0xf5e858c4,
arg=0xf642902c, kw=0x0) at
/tools/src/python/python-2.4.1/Python/ceval.c:3419
        arg = (PyObject *) 0xf642902c
        kw = (PyObject *) 0x0
        result = (PyObject *) 0x0
#19 0x080d0c86 in t_bootstrap (boot_raw=0x82543f8) at
/tools/src/python/python-2.4.1/Modules/threadmodule.c:432
        boot_raw = (void *) 0x82543f8
        gstate = PyGILState_UNLOCKED
        res = (PyObject *) 0x82a38ac
#20 0xf65cede8 in start_thread () from /lib/tls/libpthread.so.0
No symbol table info available.
#21 0xf654693a in clone () from /lib/tls/libc.so.6


3. Context: We have an automated test framework written in Python. To
speed up execution it has been multi-threaded so that tests can be run
in parallel. Rather than re-invent the wheel we simply used this
threadpool (http://chrisarndt.de/en/software/python/threadpool/), work
requests essentially being calls to a method that runs an individual
test case. However, we have substantially modified the code to add
functionality. Specifically, we need to find a way to limit the number
of tests that can run concurrently because: (1) different tests place
different loads on a machine, and (2) different machines have different
capacities (CPUs, memory, etc.).  We do this by associating a cost with
each work request, and by using the number of CPUs on the machine as a
limit (crude, but reasonably effective) -- if running the next job would
exceed the cost limit, the thread sleeps, and then checks again. In
order to verify that this cost logic works, we have also added some
logging code that can be activated by setting a flag. The other
significant modification has been to extend the Python Queue module to
add a peek method, because peeking at the front of the job queue to
determine the cost of the next job, and not removing it until there is
sufficient capacity to run it, speeds up the execution of tests. The
crash in the Python interpretor occurs only when (1) the cost logging is
switched on AND (2) the module peekablequeue is used instead of the
built in Queue module. I am quite willing to believe that these
modifications could be better implemented, but however bad the code, the
Python interpretor should not crash.
History
Date User Action Args
2008-02-12 11:50:25rupert.summertonsetspambayes_score: 3.19528e-05 -> 3.1952826e-05
recipients: + rupert.summerton
2008-02-12 11:50:25rupert.summertonsetspambayes_score: 3.19528e-05 -> 3.19528e-05
messageid: <1202817025.41.0.0817912479052.issue2077@psf.upfronthosting.co.za>
2008-02-12 11:49:21rupert.summertonlinkissue2077 messages
2008-02-12 11:49:18rupert.summertoncreate