classification
Title: invalid exception context
Type: crash Stage:
Components: Interpreter Core Versions: Python 3.0
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: amaury.forgeotdarc, benjamin.peterson, haypo, pitrou
Priority: release blocker Keywords: needs review, patch

Created on 2008-08-20 02:33 by haypo, last changed 2008-08-29 07:14 by amaury.forgeotdarc. This issue is now closed.

Files
File name Uploaded Description Edit
lostcontext.py amaury.forgeotdarc, 2008-08-20 21:21
3611.patch benjamin.peterson, 2008-08-20 23:19
lostcontext2.py amaury.forgeotdarc, 2008-08-21 18:18
pyerr_setobject_reentrant.patch haypo, 2008-08-21 23:26 Fix PyErr_SetObject() to be re-entrant
pyerr_setobject_reentrant-v2.patch haypo, 2008-08-21 23:54 New version of my previous patch: fix PyErr_SetObject() to be re-entrant
pyerr_seterror_protect.py amaury.forgeotdarc, 2008-08-22 10:07
Messages (41)
msg71503 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2008-08-20 02:33
After few seconds (30 sec to 5 minutes), my program (Fusil) crashs at:

PyEval_EvalFrameEx (f=0x85b4324, throwflag=0) at Python/ceval.c:2459
    Py_CLEAR(tstate->exc_traceback);

It crashs because tstate->exc_traceback points to a zombi object:
{_ob_next = 0xdbdbdbdb, _ob_prev = 0xdbdbdbdb, ob_refcnt = -606348326, 
ob_type = 0xdbdbdbdb}

(refcnt is 0xdbdbdbdb-1)

I'm using py3k rev 65882 compiled with CFLAGS "-O0 -ggdb" 
and --with-pydebug. Sorry, I don't have more informations yet and I 
can't explain how to reproduce the bug :-/
msg71505 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2008-08-20 02:38
The crash is on ProcError exception raising (line 21):

    20      except IOError as err:
    21          raise ProcError("Unable to open %r: %s" % (filename, 

---

(gdb) where
#0  0x0805bcc7 in PyObject_Hash (v=0x8691034) at Objects/object.c:796
#1  0x08062125 in set_contains_key (so=0x856ec6c, key=0x8691034) at 
Objects/setobject.c:682
#2  0x0806659f in PySet_Contains (anyset=0x856ec6c, key=0x8691034) at 
Objects/setobject.c:2263
#3  0x080def3a in print_exception_recursive (f=0xb7bea654, 
value=0x8656814, seen=0x856ec6c) at Python/pythonrun.c:1432
#4  0x080df0ea in PyErr_Display (exception=0x84542ac, value=0x8656814, 
tb=0x865bc34) at Python/pythonrun.c:1470
#5  0x080e68f6 in sys_excepthook (self=0xb7e013b4, args=0x865b334) at 
Python/sysmodule.c:119
#6  0x08161d29 in PyCFunction_Call (func=0xb7e016c4, arg=0x865b334, 
kw=0x0) at Objects/methodobject.c:81
#7  0x08118cc5 in PyObject_Call (func=0xb7e016c4, arg=0x865b334, 
kw=0x0) at Objects/abstract.c:2181
#8  0x080b2ea8 in PyEval_CallObjectWithKeywords (func=0xb7e016c4, 
arg=0x865b334, kw=0x0) at Python/ceval.c:3283
#9  0x080de463 in PyErr_PrintEx (set_sys_last_vars=1) at 
Python/pythonrun.c:1258
#10 0x080de06f in PyErr_Print () at Python/pythonrun.c:1150
#11 0x080e0007 in Py_FatalError (msg=0xbf9a1498 "Python/ceval.c:2459 
object at 0x865b6b4 has negative ref count -606348326")
    at Python/pythonrun.c:1863
#12 0x0805a821 in _Py_NegativeRefcount 
(fname=0x8197098 "Python/ceval.c", lineno=2459, op=0x865b6b4) at 
Objects/object.c:194
#13 0x080b004f in PyEval_EvalFrameEx (f=0x85b4324, throwflag=0) at 
Python/ceval.c:2459
(...)

(gdb) frame 13
#13 0x080b004f in PyEval_EvalFrameEx (f=0x85c9794, throwflag=0) at 
Python/ceval.c:2459
2459                                            
Py_CLEAR(tstate->exc_traceback);

(gdb) pystack
/home/haypo/ptrace/ptrace/linux_proc.py (21): openProc
/home/haypo/ptrace/ptrace/linux_proc.py (24): readProc
/home/haypo/ptrace/ptrace/linux_proc.py (31): readProcessProc
/home/haypo/ptrace/ptrace/linux_proc.py (74): readProcessStat
(...)

---

linux_proc.py code near line 21:
    (...)
     7  class ProcError(Exception):
     8      pass
    (...)
    16  def openProc(path):
    17      try:
    18          filename = procFilename(path)
    19          return open(filename)
    20      except IOError as err:
    21          raise ProcError("Unable to open %r: %s" % (filename, 
err))
    (...)
    29  def readProcessProc(pid, key):
    30      try:
    31          return readProc(path_join(str(pid), str(key)))
    32      except ProcError as error:
    33          raise ProcError("Process %s doesn't exist: %s" % (
    34              pid, error))
    (...)
    73  def readProcessStat(pid):
    74      stat = readProcessProc(pid, 'stat')
    75      return ProcessState(stat)
    76
msg71506 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2008-08-20 02:45
I also noticed a crash in PyErr_SetObject(): in block <line 68..86>, 
tstate->exc_value value may changes and so it's possible that 
tstate->exc_value becomes NULL. I added a test to avoid this crash:

Index: Python/errors.c
===================================================================
--- Python/errors.c     (révision 65899)
+++ Python/errors.c     (copie de travail)
@@ -88,7 +88,7 @@
                   This is O(chain length) but context chains are
                   usually very short. Sensitive readers may try
                   to inline the call to PyException_GetContext. */
-               if (tstate->exc_value != value) {
+               if (tstate->exc_value != value && tstate->exc_value != 
NULL) {
                        PyObject *o = tstate->exc_value, *context;
                        while ((context = PyException_GetContext(o))) 
{
                                Py_DECREF(context);
msg71522 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2008-08-20 09:02
> I also noticed a crash in PyErr_SetObject(): in block <line 68..86>, 
> tstate->exc_value value may changes and so it's possible that 
> tstate->exc_value becomes NULL. 

How can tstate->exc_value become NULL at that point? Could you investigate?
msg71548 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2008-08-20 14:58
> How can tstate->exc_value become NULL at that point? [error.c:86]
> Could you investigate?

PyEval_CallObject(exception, args) may calls PyErr_SetObject(). Since 
the same thread state is the same, tstate->exc_value also changes 
during this call.
msg71551 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2008-08-20 15:24
Selon STINNER Victor <report@bugs.python.org>:
>
> > How can tstate->exc_value become NULL at that point? [error.c:86]
> > Could you investigate?
>
> PyEval_CallObject(exception, args) may calls PyErr_SetObject(). Since
> the same thread state is the same, tstate->exc_value also changes
> during this call.

Hmm, indeed.
However, I don't see why your Python code triggers that. Does instantiating the
ProcError object somehow fail, and for what reason? Or did you witness it in
other circumstances?

As for the original problem ("tstate->exc_traceback points to a zombi object")
it would be nice to have a small snippet of Python code to reproduce it. Is it
possible for you to do that?
msg71552 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2008-08-20 15:44
I retract what I said above. PyErr_SetObject() and friends only change
tstate->curexc_* variables, not tstate->exc_*.

The former (tstate->curexc_*) contain the current, pending (uncaught)
exception state of the thread. The latter (tstate->exc_*) contain the
exception currently handled by an "except" statement in Python code. 

So, theoretically, there is no way calling PyEval_CallObject() can
change tstate->exc_value:
- if it raises an exception or calls code that raises an exception
without catching it, the exception ends up in tstate->curexc_*, not in
tstate->exc_*
- if it calls code that raises an exception /and catches it/, exception
stacking means the exception should be discarded after the end of the
"except" block and the last tstate->exc_* values restored.

Of course, there may be bugs in the implementation of the above. The
best way to find out would be to have a small snippet of Python code
reproducing the problem. :-)
msg71553 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2008-08-20 16:01
About the PyEval_CallObject() call in errors.c, here is an example:
   Call exception<0x81dcee0>(args<0x8751dc4>)
with exception=
   object  : <class 'AttributeError'>
   type    : type
   refcount: 6
   address : 0x81dcee0
and args=
   object  : ("type object 'ProcError' has no 
attribute '__subclasscheck__'",)
   type    : tuple
   refcount: 1
   address : 0x8751dc4

This exception may comes from PyObject_IsSubclass() which calls 
PyObject_GetAttr(cls, "__subclasscheck__").
msg71557 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2008-08-20 16:49
[...]
>
> This exception may comes from PyObject_IsSubclass() which calls
> PyObject_GetAttr(cls, "__subclasscheck__").

If you look at the code for PyObject_IsSubclass(), there is a pair of
PyErr_Fetch / PyErr_Restore calls around PyObject_GetAttr(cls,
"__subclasscheck__"). So this exception should vanish immediately rather than
stay around.
msg71558 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2008-08-20 17:10
I'm unable to write a short Python script to reproduce the bug. So 
download the full program:
   http://neudorf.hachoir.org/tmp/fusil3000.tar.gz

Run in with:
   $ gdb python3.0
   (gdb) run fusil-python --fast
msg71569 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2008-08-20 19:50
The problem comes when PyErr_SetObject triggers garbage collection which
runs python code (finalizers...).

I could reproduce the crash several times, and each time garbage
collection was triggered by the normalization of the exception (the call
to PyEval_CallObject(exception, args)).

An obvious fix is to save exc_value near the "/* Implicit exception
chaining */" comment.

However, I fear that there are other places where exc_value is reset,
and "exception chaining" may break in subtle ways.
msg71570 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2008-08-20 20:03
> The problem comes when PyErr_SetObject triggers garbage collection which
> runs python code (finalizers...).

Mmmh, normally this shouldn't change the value of tstate->exc_value once
that Python code returns. That's what exception stacking is for.

Having a snippet deterministically reproducing the problem would really
help in any case.

> An obvious fix is to save exc_value near the "/* Implicit exception
> chaining */" comment.

Well, it may be a fix for the crash but I'm not sure it makes the
semantics correct. If tstate->exc_value was really changed, there is a
reason and I'm not sure it should be ignored.
msg71574 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2008-08-20 21:21
> Having a snippet deterministically reproducing the problem 
> would really help in any case.
Here you are. Don't ask how I found this.

The attached script, when run, prints

(KeyError(), ValueError())
(KeyError(), None)

The current exception context (tstate->exc_value) is lost when a
generator is deleted, if it was paused inside a "try" block.

This is the cause of the crash: the gc runs inside PyErr_SetObject and
collects such a generator.
msg71575 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2008-08-20 21:21
It looks that the problem is that PyErr_SetObject() is not re-entrant.
The crash occurs when PyErr_SetObject() is called (indirectly) by 
PyErr_SetObject(): tstate->exc_value value is changed (set to NULL).

As noticed by amaury.forgeotdarc, the problem is linked to be garbage 
collector: the crash occurs when the garbage collector calls a 
destructor which will reuse PyErr_SetObject().
msg71579 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2008-08-20 21:58
Great job amaury! So in ceval, here is the block responsible to clear 
the execution informations:

Index: Python/ceval.c
===================================================================
--- Python/ceval.c      (révision 65915)
+++ Python/ceval.c      (copie de travail)
@@ -2453,11 +2453,6 @@

                        if (b->b_type == EXCEPT_HANDLER) {
                                UNWIND_EXCEPT_HANDLER(b);
-                               if (why == WHY_EXCEPTION) {
-                                       Py_CLEAR(tstate->exc_type);
-                                       Py_CLEAR(tstate->exc_value);
-                                       
Py_CLEAR(tstate->exc_traceback);
-                               }
                                continue;
                        }
                        UNWIND_BLOCK(b);

Without these 5 lines, the bug disappears and it looks (i tried few 
tests) that CPython is still ok.
msg71587 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2008-08-20 22:54
Unfortunately, removing those lines causes a RuntimeError about
exceeding the recursion limit for about 1/3 of the tests.
msg71589 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2008-08-20 22:59
Can you try with the following patch,
"throwflag" is specific to a generator being deleted.

Index: Python/ceval.c
===================================================================
--- Python/ceval.c      (revision 65919)
+++ Python/ceval.c      (working copy)
@@ -2453,7 +2453,7 @@

                        if (b->b_type == EXCEPT_HANDLER) {
                                UNWIND_EXCEPT_HANDLER(b);
-                               if (why == WHY_EXCEPTION) {
+                               if (why == WHY_EXCEPTION && !throwflag) {
                                        Py_CLEAR(tstate->exc_type);
                                        Py_CLEAR(tstate->exc_value);
                                        Py_CLEAR(tstate->exc_traceback);
msg71591 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2008-08-20 23:09
And if it doesn't work, try the following instead:

if (why == WHY_EXCEPTION) {
	PyObject *tmp1, *tmp2, *tmp3;
	tmp1 = tstate->exc_type;
	tmp2 = tstate->exc_value;
	tmp3 = tstate->exc_traceback;
	tstate->exc_type = NULL;
	tstate->exc_value = NULL;
	tstate->exc_traceback = NULL;
	Py_XDECREF(tmp1);
	Py_XDECREF(tmp2);
	Py_XDECREF(tmp3);
}
msg71592 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2008-08-20 23:13
This last proposal does not correct the behaviour of lostcontext.py.
msg71593 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2008-08-20 23:19
Here's Amaury's patch and a unittest based on lostcontext.py.
msg71594 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2008-08-20 23:24
Short patch review: __context__ tests are mostly found in test_raise.py
(class TestContext)

test_exceptions.py seems to only deal with the exception object.
msg71595 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2008-08-20 23:24
Patch was applied in r65921.
msg71596 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2008-08-20 23:25
Ok. I'll move the test after the betas.
msg71657 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2008-08-21 16:26
The bug is not closed :-/ With py3k trunk, I still get a crash. So I 
added a flag to detect inner calls. Here is an example of inner call 
backtrace:

(gdb) where
(...)
#2  0xb7df4201 in abort () from /lib/tls/i686/cmov/libc.so.6
#3  0x080a23a9 in PyErr_SetObject (exception=0x818b760, 
value=0xb75a3694) at Python/errors.c:61
#4  0x08094048 in do_raise (exc=0xb75a3694, cause=0x0) at 
Python/ceval.c:2928
#5  0x0808fa70 in PyEval_EvalFrameEx (f=0x83557d4, throwflag=0) at 
Python/ceval.c:1510
(...)
#23 0x08094bd8 in PyEval_CallObjectWithKeywords (func=0xb7a6c96c, 
arg=0xb7c6802c, kw=0x0) at Python/ceval.c:3283
#24 0x0806befd in slot_tp_del (self=0xb759d44c) at 
Objects/typeobject.c:5268
(...)
#26 0x0811f05d in PyDict_Clear (op=0xb7595e84) at 
Objects/dictobject.c:846
#27 0x08121112 in dict_tp_clear (op=0xb7595e84) at 
Objects/dictobject.c:1841
#28 0x080c81e9 in delete_garbage (collectable=0xbfcc75c4, 
old=0x8179434) at Modules/gcmodule.c:684
(...)
#31 0x080c9000 in _PyObject_GC_Malloc (basicsize=28) at 
Modules/gcmodule.c:1333
#32 0x08060aee in PyType_GenericAlloc (type=0x818b0a0, nitems=0) at 
Objects/typeobject.c:667
(...)
#37 0x080a24cc in PyErr_SetObject (exception=0x818b0a0, 
value=0xb75acea0) at Python/errors.c:87
(...)
#44 0x080912f7 in PyEval_EvalFrameEx (f=0x83660e4, throwflag=0) at 
Python/ceval.c:1940
(...)

First Python stack:

(gdb) pystack
/home/haypo/prog/py3k/Lib/io.py (1074): _flush_unlocked
/home/haypo/prog/py3k/Lib/io.py (1070): flush
/home/haypo/prog/py3k/Lib/io.py (1454): flush
/home/haypo/prog/py3k/Lib/io.py (1459): close
/home/haypo/prog/py3k/Lib/io.py (390): __del__
/home/haypo/fusil3000/fusil/process/cpu_probe.py (30): live
/home/haypo/fusil3000/fusil/mas/univers.py (15): executeAgent
(...)

Second Python stack:

(gdb) pystack
/home/haypo/fusil3000/fusil/process/cpu_probe.py (30): live
/home/haypo/fusil3000/fusil/mas/univers.py (15): executeAgent
/home/haypo/fusil3000/fusil/mas/univers.py (24): execute
/home/haypo/fusil3000/fusil/application.py (196): executeProject
(...)

So the real fix is to make PyErr_SetObject() re-entrant.
msg71658 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2008-08-21 17:14
On a Windows box, I manage to make the following script reliably hang on
a non-debug build of beta3. This can be a good base for further diagnosing.


def f():
    class Bug:
        def __del__(self):
            1/0

    import gc
    trash = [Bug()]
    trash.append(trash)
    try:
        gc.collect()
        gc.set_threshold(1, 1, 1)
        del trash
        len()
    except TypeError:
        raise

if __name__ == "__main__":
    f()
msg71659 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2008-08-21 17:16
Here is a new snippet with strange exception handling:
--------------------- 8< -------------------------
from gc import collect
import _weakref

class FuzzingUserClass:
    pass

obj = _weakref.ref(FuzzingUserClass)

# Exception not raised??
obj.__init__(
    0,
    0,
    0,
)

# Exception catched here??
collect()
--------------------- 8< -------------------------

Result:
    Exception TypeError: '__init__ expected at most 2 arguments, 
    got 3' in 'garbage collection' ignored
    Fatal Python error: unexpected exception during garbage collection
    Abandon (core dumped)

The exception is raised in Objects/weakrefobject.c:
  weakref___init__() 
  => parse_weakref_init_args() 
  => PyArg_UnpackTuple() *here*
msg71661 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2008-08-21 17:19
Haypo, this is a separate bug I think. Please open a new ticket :)
msg71663 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2008-08-21 17:25
@pitrou: Ok, done (issue #3634). We were right, it's a different bug.
msg71664 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2008-08-21 17:43
Antoine, your script hangs at the end due to the io.py deadlock (see #3618)

- at the end of the script, flush_io() is called
- this enters code in io.py
- here, garbage collection occurs (thanks to low thresholds)
- the Bug() instance is collected
- the exception is handled by a PyErr_WriteUnraisable
- which tries to print
msg71665 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2008-08-21 18:18
I found another way to loose the current exception context; see
lostcontext2.py

Completely removing the block starting with
       if (why == WHY_EXCEPTION && !throwflag) {
corrects the script;

but according to Benjamin: """removing those lines causes a RuntimeError
about exceeding the recursion limit for about 1/3 of the tests."""

So a better fix must be found. At least we have the unit test :-).
msg71698 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2008-08-21 23:26
It's now known that PyErr_SetObject() have to be re-entrant because of 
the garbage collector interaction. As I wrote in my comments, tstate 
may be changed during PyEval_CallObject() call. The problem is to 
known which values have to be protected during PyErr_SetObject() 
re-entrant call... I tried to save/restore tstate->exc_value if it's 
value changes, but I'm not sure that it's enough.
msg71704 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2008-08-21 23:54
Ok, it was not enough: exc_{type,value,traceback} have to be 
saved/restored. So here is a new patch. I doesn't change Python 
behaviour for previous pitrou snippet (msg71658): it doesn't crash 
here and display two errors.

I think that this issue mix differents bugs:
 (1) lostcontext.py fixed by « if (why == WHY_EXCEPTION 
&& !throwflag) »
 (2) pitrou snippet
 (3) PyErr_SetObject() is no re-entrant: not fixed yet (please review 
my new patch attached to this comment ;-))
msg71711 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2008-08-22 00:53
With my last patch (pyerr_setobject_reentrant-v2.patch) my program 
works fine! I known that PyErr_SetObject() makes re-entrant calls 
every ~30 seconds, so the code is tested ;-)
msg71739 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2008-08-22 10:07
Victor, your patch addresses the symptom of the problem, not the cause.

The cause is that in some cases, the exception context chain is lost. Of
course what could be a minor annoyance becomes dramatic when this
precisely happens in code that makes use of this context.

IMO, PyErr_SetObject should not restore the previous exc_* members; it's
not its job to correct others' mistakes.
I join a patch that only protects it from crashing in this case: it just
saves exc_value in a local variable.

The bug shown by lostcontext2.py is still unresolved, but at least it
won't crash the interpreter.
msg71740 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2008-08-22 10:22
Agreed with Amaury, it's not PyErr_SetObject's job to try to
save/restore the tstate->exc_* variables. We'll probably have to live
with the small context-losing glitches in 3.0.

For 3.1, a radical solution would be to drop the "exception
normalization" misfeature (which is a source of complications and
potential bugs) and always instantiate exception objects as soon as they
are raised rather than lazily. We need to make sure the performance loss
is reasonable though.
msg71741 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2008-08-22 10:31
Hmm, answering to myself, I don't think dropping exception normalization
would solve the problem, it would just let it occur in a different place...
msg71793 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2008-08-22 23:24
Benjamin,

I am testing the patch proposed earlier by Victor in
http://bugs.python.org/msg71579 (who might be the correct one, after all),
and I don't see the problems you mentioned. 
I run the test suite without problem, on winXP & Linux Debian x86.

Can you please try again?
msg71794 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2008-08-22 23:29
I can't reproduce it either. I suspect that I removed the wrong lines
initially and caused other problems. :) Sorry for the false alarm.
msg72041 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2008-08-27 20:52
Some progress:
The lines suppressed by the patch at http://bugs.python.org/msg71579
either do nothing (because e.g exc_type is already NULL or None),
or happen to be in a case similar to the script "lostcontext2.py"
(Most of the time, the flush() function in io.py).

So again, I think these lines should be suppressed.
The test suite still pass, and all the "-R::" I ran did return identical
result.
Can this patch go in?
msg72043 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2008-08-27 21:36
> Can this patch go in?

I'm ok for it.
msg72120 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2008-08-29 07:14
Committed as r66056.
History
Date User Action Args
2008-08-29 07:14:24amaury.forgeotdarcsetstatus: open -> closed
resolution: fixed
messages: + msg72120
2008-08-27 21:36:16pitrousetmessages: + msg72043
2008-08-27 20:52:37amaury.forgeotdarcsetmessages: + msg72041
2008-08-22 23:29:11benjamin.petersonsetmessages: + msg71794
2008-08-22 23:24:14amaury.forgeotdarcsetmessages: + msg71793
2008-08-22 10:31:47pitrousetmessages: + msg71741
2008-08-22 10:22:09pitrousetmessages: + msg71740
2008-08-22 10:07:55amaury.forgeotdarcsetfiles: + pyerr_seterror_protect.py
messages: + msg71739
2008-08-22 00:57:00benjamin.petersonsetkeywords: + needs review
2008-08-22 00:53:13hayposetmessages: + msg71711
2008-08-21 23:54:22hayposetfiles: + pyerr_setobject_reentrant-v2.patch
messages: + msg71704
2008-08-21 23:26:20hayposetfiles: + pyerr_setobject_reentrant.patch
messages: + msg71698
2008-08-21 18:18:12amaury.forgeotdarcsetfiles: + lostcontext2.py
messages: + msg71665
2008-08-21 17:43:47amaury.forgeotdarcsetmessages: + msg71664
2008-08-21 17:25:50hayposetmessages: + msg71663
2008-08-21 17:19:32pitrousetmessages: + msg71661
2008-08-21 17:16:29hayposetmessages: + msg71659
2008-08-21 17:14:31pitrousetmessages: + msg71658
2008-08-21 16:28:28benjamin.petersonsetstatus: closed -> open
resolution: accepted -> (no value)
2008-08-21 16:26:59hayposetmessages: + msg71657
2008-08-21 00:58:37barrysetstatus: open -> closed
2008-08-20 23:25:46benjamin.petersonsetmessages: + msg71596
2008-08-20 23:24:52benjamin.petersonsetmessages: + msg71595
2008-08-20 23:24:45amaury.forgeotdarcsetmessages: + msg71594
2008-08-20 23:21:53barrysetresolution: accepted
2008-08-20 23:19:56benjamin.petersonsetfiles: + 3611.patch
keywords: + patch
messages: + msg71593
2008-08-20 23:13:10amaury.forgeotdarcsetmessages: + msg71592
2008-08-20 23:09:08pitrousetmessages: + msg71591
2008-08-20 22:59:49amaury.forgeotdarcsetmessages: + msg71589
2008-08-20 22:54:38benjamin.petersonsetnosy: + benjamin.peterson
messages: + msg71587
2008-08-20 22:25:23barrysetpriority: release blocker
2008-08-20 21:58:03hayposetmessages: + msg71579
2008-08-20 21:21:30hayposetmessages: + msg71575
2008-08-20 21:21:25amaury.forgeotdarcsetfiles: + lostcontext.py
messages: + msg71574
2008-08-20 20:03:59pitrousetmessages: + msg71570
2008-08-20 19:50:55amaury.forgeotdarcsetnosy: + amaury.forgeotdarc
messages: + msg71569
2008-08-20 17:10:03hayposetmessages: + msg71558
2008-08-20 16:49:36pitrousetmessages: + msg71557
2008-08-20 16:01:12hayposetmessages: + msg71553
2008-08-20 15:44:53pitrousetmessages: + msg71552
2008-08-20 15:24:24pitrousetmessages: + msg71551
2008-08-20 14:58:19hayposetmessages: + msg71548
2008-08-20 09:02:42pitrousetnosy: + pitrou
messages: + msg71522
2008-08-20 02:45:51hayposetmessages: + msg71506
2008-08-20 02:38:20hayposetmessages: + msg71505
2008-08-20 02:33:18haypocreate