I use GDB to understanding how CPython executes the test.py
source file and I want to stop the CPython when it starts the execution of opcode I am interested.
OS: Ubuntu 18.04.2 LTS
Debugger: GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git
The first problem - many CPython's .py
own files are executed before my test.py
gets its turn, so I can't just break at the _PyEval_EvalFrameDefault
- there are many of them, so I should distinguish my file from others.
The second problem - I can't set the condition like "when the filename is equal to the test.py", because the filename is not a simple C
string, it is the CPython's Unicode object, so the standard GDB string functions can't be used for comparing.
At this moment I do the next trick for breaking the execution at the needed line of test.py
source:
For example, I have the source file:
x = ['a', 'b', 'c']
# I want to set the breakpoint at this line.
for e in x:
print(e)
I add the binary left shift operator to the code:
x = ['a', 'b', 'c']
# Added for breakpoint
a = 12
b = 2 << a
for e in x:
print(e)
And then, track the BINARY_LSHIFT
opcode execution in the Python/ceval.c
file by this GDB command:
break ceval.c:1327
I have chosen the BINARY_LSHIFT
opcode, because of its seldom usage in the code. Thus, I can reach the needed part of .py
file quickly - it happens once in the all other .py
modules executed before my test.py
.
I look the more straightforward way of doing the same, so the questions:
- Can I catch the moment the
test.py
starts executing? I should mention, what thetest.py
filename is appearing on different stages: parsing, compilation, execution. So, it also will be good to can break the CPython execution at the any stage. - Can I specify the line of the
test.py
, where I want to break? It is easy for.c
files, but is not for.py
files.