[Cython] Help with cygdb bug

Volker Weißmann volker.weissmann at gmx.de
Wed Apr 22 14:44:16 EDT 2020


Hello,

cy exec print(localvar)

currently does not work. And I need your help to fix it.


If I'm not mistaken, the function "_fill_locals_dict" in libcython.py is
supposed to find and set all local variables.

The "for name, cyvar in iterator:" correctly iterates over all local
variables, but cyvar.type is not PythonObject but CObject.

The cython line "localvar= 49" gets translated to the C-line
"__pyx_v_localvar = 49;". Notice how the type of__pyx_v_localvar is long
and not a static PyObject*  . If an equivalent "static PyObject*" would
exist in the C-code, I would know how to make 'cy exec print(localvar)'
work (the reason why global variables work, is because they are of type
static PyObject*).


I see two ways to make `cy exec print(localvar)` work:

1. Let cygdb generate C-code to convert a long (or any other type) to an
equivalent static PyObject* (For long's it would be
__Pyx_PyInt_From_long). Then let cygdb execute this code by running
gdb.parse_and_eval(code). Then read the resulting variable with
something like

code = '''
                     (PyObject *) PyDict_SetItem(
                         (PyObject *) %d,
                         (PyObject *) %d,
                         (PyObject *) %s)
                 ''' % (local_dict_pointer, pystringp, cname)

gdb.parse_and_eval(code)


2. Compile the argument of cy exec (in this case "print(localvar)") to
C-code (while getting the local variables right) and run it using
gdb.parse_and_eval(code).


Ideally, cy exec var=123 should work like cy set var=123.



Example to reproduce it:

codefile.pyx:

def func():
     localvar = 49
     print(localvar)
func()


setup.py:

#!/usr/bin/env python
from setuptools import setup, Extension
from Cython.Build import cythonize
extensions = Extension('codefile', sources=['codefile.pyx'])
setup(
     author = 'Volker Weissmann',
     author_email = 'volker.weissmann at gmx.de',
     ext_modules = cythonize(
         extensions,
         gdb_debug=True,
     ),
)


.cygdbinit:

cy break codefile:3
cy run
cy print localvar


To reproduce it, run:
python setup.py build_ext --inplace
cygdb . -- -q --args python -c "import codefile"


With a debug version of Python.



More information about the cython-devel mailing list