In C python, access to the bytecode evaluation stack

Given a Python C frame pointer, how can I look at a random stack score record? (Some specific stack entries can be found through locals(); I'm talking about other stack entries.)

I asked a wider question like this recently:

getting exec p python argument string or accessing evaluation stack

but here I want to focus on being able to read CPython stack entries at runtime.

I will take a solution that works on CPython 2.7 or on any Python later than Python 3.3. However, if you have things that work outside of this, share it and, if there is no better solution, I agree with that.

I would prefer not to modify the Python C code. In Ruby, I really did this to get what I want. From experience, I can say that this is probably not the way we want to work. But then again, if there is no better solution, I will take it. (My understanding regarding SO points is that I lose him in generosity anyway. Therefore, I am happy to go look at the person who showed the best spirit and willingness to look at it, assuming it works.)

update: User Comment2357112 TL; DR; In principle, this is difficult to do. (However, if you think you have a desire to try, be sure to do it.)

So let me narrow down the scope of this simpler problem, which, in my opinion, is doable:

python, inspect.currentframe(), . C f_valuestack. Python, / Python .

2, , ( ) . , , , . ", , ", " " , - , , , 190 . . ...

- , , .

.

+4
3

, , :

2357112 :

  • Python, ,
  • ,
  • , ( ).

...

- C f_valuestack, ( ) . , C. , , , , , . .

C PyFrameObject, f_valuestack. PyFrameObject Python Python ( , , , python ), - .

, , , last_i.

, , Ned Batchhelder byterun. - Python Python. , , CPython VM. (, ). byterun , Python, .

, - ( , ), . xdis.

, , , , , , EXEC, .

0

, ctypes C-, .

-, API, C Python, . C. CPython 3.6; , , .

PyFrameObject f_valuestack, . f_stacktop, . Python , stack_pointer _PyEval_EvalFrameDefault:

stack_pointer = f->f_stacktop;
assert(stack_pointer != NULL);
f->f_stacktop = NULL;       /* remains NULL unless yield suspends frame */

, f_stacktop , yield... await, yield from -. yield await Python stack_pointer f_stacktop, , , , C .

f_stacktop NULL, , f_valuestack f_stacktop ctypes. ctypes gc.get_referents(frame_object), , .

f_stacktop NULL, . , f_valuestack, , .

  • co_stacksize, , .
  • , , , Python , .
  • gc.get_referents , f_stacktop NULL. , ( , f_stacktop null , ).
  • , f_lasti, -, , , , - Python -, - . , , , .
  • Frame , , , . ( .)
  • stackpointer GDB - , .
+3

Edit:

Thonny IDE [sub] stepping. . SO. Python .

:

Ruby , , Python?

, , f_lineno, , f_locals , f_back , f_code , , , - .. - . .

w.r.t. . , : :

3.3.1

CPython C, C ( http://github.com/python) object, frameobject.c, , f_trace f_lineno. f_trace , , , , Pycallgraph4, 3.2. ...

3.8.1

Bdb PSL ( Python). , , , . Bdb . , , . , . , .

, bdb , settrace() PSL sys. f_trace , bdb ...

Pdb, PSL, bdb . cmd PSL, , pdb , , , , . , step, next continue, . Python , , 3.9.5.

. Python , .

I have not worked with Python for many years, so I apologize if something is wrong. Also, as you can see from the links, this was Python 3.2.

+1
source

Source: https://habr.com/ru/post/1678468/


All Articles