cProfile with generator throwing
Hi. It seems that cProfile does not support throwing exceptions into generators properly, when an external timer routine is used. The problem is that _lsprof.c: ptrace_enter_call assumes that there are no exceptions set when it is called, which is not true when the generator frame is being gen_send_ex'd to send an exception into it (Maybe you could say that only CallExternalTimer assumes this, but I am not sure). This assumption causes its eventual call to CallExternalTimer to discover that an error is set and assume that it was caused by its own work (which it wasn't). I am not sure what the right way to fix this is, so I cannot send a patch. Here is a minimalist example to reproduce the bug:
import cProfile import time p=cProfile.Profile(time.clock) def f(): ... yield 1 ... p.run("f().throw(Exception())") Exception exceptions.Exception: Exception() in
ignored Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python2.5/cProfile.py", line 135, in run return self.runctx(cmd, dict, dict) File "/usr/lib/python2.5/cProfile.py", line 140, in runctx exec cmd in globals, locals File "<string>", line 1, in <module> File "<stdin>", line 1, in f SystemError: error return without exception set
Eyal Lotem schrieb:
Hi. It seems that cProfile does not support throwing exceptions into generators properly, when an external timer routine is used.
The problem is that _lsprof.c: ptrace_enter_call assumes that there are no exceptions set when it is called, which is not true when the generator frame is being gen_send_ex'd to send an exception into it (Maybe you could say that only CallExternalTimer assumes this, but I am not sure). This assumption causes its eventual call to CallExternalTimer to discover that an error is set and assume that it was caused by its own work (which it wasn't).
I am not sure what the right way to fix this is, so I cannot send a patch. Here is a minimalist example to reproduce the bug:
import cProfile import time p=cProfile.Profile(time.clock) def f(): ... yield 1 ... p.run("f().throw(Exception())") Exception exceptions.Exception: Exception() in
ignored Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python2.5/cProfile.py", line 135, in run return self.runctx(cmd, dict, dict) File "/usr/lib/python2.5/cProfile.py", line 140, in runctx exec cmd in globals, locals File "<string>", line 1, in <module> File "<stdin>", line 1, in f SystemError: error return without exception set
There might be a similar problem with trace functions, see bug #1733757 which is quite obscure too. Georg -- Thus spake the Lord: Thou shalt indent with four spaces. No more, no less. Four shall be the number of spaces thou shalt indent, and the number of thy indenting shall be four. Eight shalt thou not indent, nor either indent thou two, excepting that thou then proceed to four. Tabs are right out.
participants (2)
-
Eyal Lotem
-
Georg Brandl