- Notifications
You must be signed in to change notification settings - Fork0
Andy-Messer/Py-modules-in-C
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Сallback that the Python interpreter will invoke for every function call and line of Python executed.
ЗАПОМНИТЕ ЭТО!!! Функция trace срабатывает на каждой строке, на каждом вызове, каждом исключении.
- простейший пример trace функции.
importsysdefmy_py_trace_fn(frame,event,arg):# .. do something useful ..returnmy_py_trace_fnsys.settrace(my_py_trace_fn)
- frame - текущий исполняемый frame.
- event - строка с информацией о типе event-а.
- arg - аналог returnable value, когда мы хотим вернуть код возврата или ошибки.
Важно! Надо понимать, что каждый раз мы возвращаем саму функцию. Это важно для понимания вопроса:"Что такое цепочка трассировки?"
На дне Python, средства трассировки реализованны с помощью C. Каждый поток исполнения имеет два глобальных указателя:
- c_tracefunc - указывает на сигнатуру вызванной функции.
intmy_trace(PyObject*obj,PyFrameObject*frame,intevent,PyObject*arg);
- c_traceobj - указывает на произвольный объект Python, который будет передан в качестве первого аргумента функции.
- Остальные аргументы аналогичны аргументам функции Python, за исключением того, что здесь событие — это целое число, а не строка.
Для регистрации trace_func, используемPyEval_SetTrace().
P.s. К сожалению, в CНЕТ такого же простого механизма цепочек, как упоминалось ранее.
Достаточно естественный факт, что sys.settrace() в Python реализована с помощью PyEval_SetTrace().
Простейший пример обертки над PyEval_SetTrace():
PyObject*sys_settrace(PyObject*py_fn){if (py_fn==Py_None) {PyEval_SetTrace(NULL,NULL); }else {PyEval_SetTrace(trace_trampoline,py_fn); }returnPy_None;}
Рассмотрим код выше, если мы передадим в sys_settrace() NULL, то функция трассировки будет затёрта, иначе же мы можем записать функцию trace_trampoline.
Пример trace_trampoline:
inttrace_trampoline( PyObject *obj, PyFrameObject *frame,int event, PyObject *arg){ PyObject *callback;if (event == PyTrace_CALL) {/* Remember obj is really my_py_trace_fn*/ callback = obj; }else { callback = frame->f_trace; }if (callback ==NULL) {return0; } result =/* Call callback(frame, event as str, arg)*/;if (/* error occurred in callback*/) {PyEval_SetTrace(NULL,NULL); frame->f_trace =NULL;return -1; }if (result != Py_None) { frame->f_trace = result; }return0;}
В коде выше происходит интересная ситуация, мы проэмулировали цепочку трассировки, через frame->f_trace.
- Кроме метода sys.Settrace(), есть ещё sys.gettrace(). Прикол:
# import syssys.settrace(sys.gettrace())
На Python данный код отработает корректно, однако на C, будет тяжело вылечить свою прогу после такого))))
Здесь представлена далеко не вся информация из статьи, если кто-то хочет ещё изучать то вот:
About
Documentation for the python module in C.
Topics
Resources
Uh oh!
There was an error while loading.Please reload this page.