Images useful for configuring the cython debugger
169
Getting the environment setup for the cython debugger is in itself challenging. The easiest way to do this is to use a Python installation configured with debugging symbols alongside a gdb that knows about this Python
Fortunately, this can all be abstracted with a pre-built docker image:
docker pull willayd/cython-debug
The image does not include Cython - this allows you to install whichever version you would like to use, but of course then requires you do this in your own Dockerfile or in the container while running
Something small to start works best. Let's assume you have this file test.pyx:
def foo():
message = "Hello world!"
print(message)
With these items set up on host, you can jump into the Docker container with a command such as:
docker run --rm -it -v <folder_with_text.pyx>:/data cython-debug
Make sure that you have cython installed. Afterwards you can jump over to your directory in the container that contains the cython file you would like to debug. Here we have put that at /data:
cd /data
cython -3 --gdb test.pyx # transpile into .c file
# Now we can build a shared library
gcc -g -fPIC -I/usr/local/include/python3.10d -shared test.c -o test.so
With all of that out of the way, you now have a shared library that python can load and operate with. Try running python3 -c "import test; test.foo()" and you'll see the Hello World message printed.
To debug this, execute the following command:
cygdb . -- --args python3 -c "import test; test.foo()"
This will enter the cygdb debugger interactively. Let's go ahead and set a breakpoint for the foo function we want to inspect:
(gdb) cy break foo
Function "__pyx_f_4test_foo" not defined.
Breakpoint 1 (__pyx_f_4test_foo) pending.
Now you can go ahead and run the program:
(gdb) cy run
1 def foo():
Here we've stopped the moment we've hit the Cython function. You can inspect the state of things:
(gdb) cy bt
#18 0x00007fb93f3cc5de in foo() at /cython/test.pyx:0
(gdb) cy step
2 message = "Hello World!"
(gdb) cy next
3 print(message)
(gdb) cy list
1 def foo():
2 message = "Hello World!"
> 3 print(message)
(gdb) cy locals
message = 'Hello World!'
Another way is to specify the module name and line number that you'd like to hit:
(gdb) cy break test:2
No source file named /cython/test.c.
Breakpoint 1 (/cython/test.c:1977) pending.
(gdb) cy run
2 message = "Hello World!"
Content type
Image
Digest
sha256:385782757…
Size
670.5 MB
Last updated
almost 4 years ago
docker pull willayd/cython-debug