[issue46451] Possibly bad interaction with tracing and cython?

2022-01-20 Thread Sebastian Berg


Sebastian Berg  added the comment:

Ahh, a further data-point.  The name from the module scope that is overwritten 
IS a parameter name used in the function locals.  Strangly, if I modify the 
tracing to print more:

stop = 0
def trace(frame, event, arg):
global stop
if stop > 10:
return None

if np.core.numeric.dtype is not np.dtype:
#print("Something happened here, `np.core.numeric.dtype IS np.dtype`")
print(np.core.numeric.dtype)
print(frame, event, arg)
stop += 1
else:
print(frame, event, arg)

return trace

Then what I get is:

None
 call None
None
 line None
None
 line None
None
 line None
None
 line None
bool


So, upon entering the function, the value is (already) cleared/set to None 
(which is correct of course for `dtype=None`) and then while the function runs 
storing into the function locals _mutates_ the module global?

For the fact that it keeps changing during the function run, points very 
strongly at CPython?

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue46451] Possibly bad interaction with tracing and cython?

2022-01-20 Thread Sebastian Berg


New submission from Sebastian Berg :

Starting here, but there could be Cython interaction or something else in 
theory.  But, when running the following:

* Python 3.10.1 (not 3.9.9, debug version or not)
* Setting a tracing function  (not setting a trace-function will fix the issue)
* Running Cython (maybe also C code) calling back into Python (the best I can 
tell)

It can happen that module globals in the called funtions scope seem to be 
modified.  Oddly enough to a value used in the locals of that function?!

The pandas issue:

https://github.com/pandas-dev/pandas/issues/41935

has a reproducer (sorry that it takes NumPy and pandas for now).  I will paste 
it at the end here also.

I can find that the value is modified by the time the `trace` function is 
called.  No other "trace" triggers are processed before in this example (Cython 
calls other functions in NumPy, but all of those are C implemented, so I guess 
that is why).
The function in question (unlike all?) should further be called with 
`__Pyx_PyFunction_FastCall`, so that is probably an important data point: 
Fastcall protocol seems involved.

(Reproducible using NumPy 1.21.5 and Pandas 1.3.5, but except maybe pandas due 
to the Cython version, I don't expect version dependency.)

The output of the script is very brief:

Something happened here, `np.core.numeric.dtype IS np.dtype`
 call None


The full reproducer script is:


import sys
import numpy as np
import pandas as pd

from numpy.core import numeric

stop = False
def trace(frame, event, arg):
global stop
if stop:
return None

if np.core.numeric.dtype is not np.dtype:
print("Something happened here, `np.core.numeric.dtype IS np.dtype`")
print(frame, event, arg)
stop = True
else:
print(frame, event, arg)

return trace

sys.settrace(trace)

pd._libs.lib.maybe_convert_objects(np.array([None], dtype=object))


For completeness, the Cython code calling the NumPy function in question, is 
(likley, there is more, this is Cython, I just cut it out a bit :)):

  #if CYTHON_FAST_PYCALL
  if (PyFunction_Check(__pyx_t_5)) {
PyObject *__pyx_temp[3] = {__pyx_t_2, __pyx_t_6, Py_False};
__pyx_t_15 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_8, 
2+__pyx_t_8); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 2441, __pyx_L1_error)
__Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
__Pyx_GOTREF(__pyx_t_15);
__Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  } else
  #endif

--
components: Interpreter Core
messages: 411082
nosy: seberg
priority: normal
severity: normal
status: open
title: Possibly bad interaction with tracing and cython?
type: crash
versions: Python 3.10

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com