پروفایل‌گیری و ردگیری

مفسر پایتون پشتیبانی سطح پایینی برای متصل کردن امکانات پروفایل‌گیری و ردگیری اجرا فراهم می‌کند. از این امکانات در ابزارهای پروفایل‌گیری، اشکال‌زدایی و تحلیل پوشش استفاده می‌شود.

این رابط C به کد پروفایل‌گیری یا ردگیری اجازه می‌دهد از سربار فراخوانی از طریق اشیاء فراخوانی‌پذیر در سطح پایتون اجتناب کند و در عوض فراخوانی مستقیم تابع C انجام دهد. ویژگی‌های اساسی این امکان تغییری نکرده‌اند؛ این رابط اجازه می‌دهد توابع ردگیری به ازای هر نخ نصب شوند، و رویدادهای پایه‌ای که به تابع ردگیری گزارش می‌شوند، همان رویدادهایی هستند که در نسخه‌های قبلی به توابع ردگیری در سطح پایتون گزارش می‌شدند.

typedef int (*Py_tracefunc)(PyObject *obj, PyFrameObject *frame, int what, PyObject *arg)

نوع تابع ردگیری‌ای که با استفاده از PyEval_SetProfile() و PyEval_SetTrace() ثبت می‌شود. پارامتر نخست، شیءی است که به‌عنوان obj به تابع ثبت‌کننده پاس داده‌شده است؛ frame شیء فریمی است که رویداد به آن مربوط است؛ what یکی از ثابت‌های PyTrace_CALL، PyTrace_EXCEPTION، PyTrace_LINE، PyTrace_RETURN، PyTrace_C_CALL، PyTrace_C_EXCEPTION، PyTrace_C_RETURN یا PyTrace_OPCODE است و arg به مقدار what بستگی دارد:

مقدار what

معنای arg

PyTrace_CALL

همیشه Py_None.

PyTrace_EXCEPTION

اطلاعات استثنا به شکلی که توسط sys.exc_info() بازگردانده می‌شود.

PyTrace_LINE

همیشه Py_None.

PyTrace_RETURN

مقداری که به فراخوان‌کننده بازگردانده می‌شود، یا NULL در صورتی که ناشی از استثنا باشد.

PyTrace_C_CALL

شیء تابعی که فراخوانی می‌شود.

PyTrace_C_EXCEPTION

شیء تابعی که فراخوانی می‌شود.

PyTrace_C_RETURN

شیء تابعی که فراخوانی می‌شود.

PyTrace_OPCODE

همیشه Py_None.

int PyTrace_CALL

مقدار پارامتر what در تابع Py_tracefunc هنگامی که فراخوانی جدیدی از یک تابع یا متد، یا ورود جدیدی به یک تولیدگر گزارش می‌شود. توجه داشته باشید که ایجاد پیمایش‌گر برای یک تابع تولیدگر گزارش نمی‌شود، زیرا هیچ انتقال کنترلی به بایت‌کد پایتون در فریم مربوطه وجود ندارد.

int PyTrace_EXCEPTION

مقدار پارامتر what برای تابع Py_tracefunc زمانی که استثنایی پرتاب شده باشد. تابع کال‌بک با این مقدار برای what زمانی فراخوانی می‌شود که پس از پردازش هر بایت‌کدی، استثنا در فریمی که در حال اجراست تنظیم شود. اثر این امر آن است که همان‌طور که گسترش استثنا موجب بازگشایی پشته‌ی پایتون می‌شود، کال‌بک هنگام بازگشت به هر فریم، همزمان با گسترش استثنا فراخوانی می‌شود. فقط توابع ردگیری این رویدادها را دریافت می‌کنند؛ پروفایل‌گیر به آن‌ها نیازی ندارد.

int PyTrace_LINE

مقداری که هنگام گزارش‌شدن یک رویداد شماره سطر، به‌عنوان پارامتر what به یک تابع Py_tracefunc (اما نه به یک تابع پروفایل‌گیری) ارسال می‌شود. این رویداد می‌تواند برای یک فریم، با تنظیم f_trace_lines روی 0 در همان فریم، غیرفعال شود.

int PyTrace_RETURN

مقدار پارامتر what در توابع Py_tracefunc زمانی که یک فراخوانی در شرف بازگشت است.

int PyTrace_C_CALL

مقدار پارامتر what برای توابع Py_tracefunc هنگامی که یک تابع C در شرف فراخوانی شدن است.

int PyTrace_C_EXCEPTION

مقدار پارامتر what برای توابع Py_tracefunc هنگامی که یک تابع C استثنا ایجاد کرده باشد.

int PyTrace_C_RETURN

مقدار پارامتر what برای توابع Py_tracefunc هنگامی که یک تابع C بازگشته است.

int PyTrace_OPCODE

مقدار پارامتر what برای توابع Py_tracefunc (اما نه توابع پروفایل‌گیری) زمانی که یک آپ‌کد جدید در شرف اجراست. این رویداد به‌طور پیش‌فرض منتشر نمی‌شود: باید به‌طور صریح با تنظیم f_trace_opcodes به 1 روی فریم درخواست شود.

void PyEval_SetProfile(Py_tracefunc func, PyObject *obj)

تابع پروفایل‌گیر را روی func تنظیم می‌کند. پارامتر obj به عنوان نخستین پارامتر به تابع پاس داده می‌شود و می‌تواند هر شیء پایتون یا NULL باشد. اگر تابع پروفایل نیاز به نگهداری وضعیت داشته باشد، استفاده از مقدار متفاوتی برای obj در هر نخ، مکانی مناسب و نخ‌ایمن برای ذخیره‌سازی آن فراهم می‌کند. تابع پروفایل برای همه رویدادهای پایش‌شده به جز PyTrace_LINE، PyTrace_OPCODE و PyTrace_EXCEPTION فراخوانی می‌شود.

همچنین تابع sys.setprofile() را ببینید.

فراخوانی‌کننده باید یک attached thread state داشته باشد.

void PyEval_SetProfileAllThreads(Py_tracefunc func, PyObject *obj)

مانند PyEval_SetProfile() است، اما به‌جای تنظیم تابع پروفایل تنها روی نخ فعلی، آن را در تمام نخ‌های در حال اجرای متعلق به مفسر فعلی تنظیم می‌کند.

فراخوانی‌کننده باید یک attached thread state داشته باشد.

مانند PyEval_SetProfile()، این تابع هر استثنایی را که هنگام تنظیم توابع پروفایل در همه‌ی نخ‌ها ایجاد می‌شود، نادیده می‌گیرد.

اضافه شده در نسخه‌ی 3.12.

void PyEval_SetTrace(Py_tracefunc func, PyObject *obj)

تابع ردگیری را روی func تنظیم می‌کند. این تابع مشابه PyEval_SetProfile() است، با این تفاوت که تابع ردگیری رویدادهای شماره سطر و رویدادهای به ازای هر آپ‌کد را دریافت می‌کند، اما هیچ رویدادی مربوط به فراخوانی اشیاء تابع C را دریافت نمی‌کند. هر تابع ردگیری که با استفاده از PyEval_SetTrace() ثبت‌شده باشد، PyTrace_C_CALL، PyTrace_C_EXCEPTION یا PyTrace_C_RETURN را به عنوان مقدار پارامتر what دریافت نخواهد کرد.

همچنین تابع sys.settrace() را ببینید.

فراخوانی‌کننده باید یک attached thread state داشته باشد.

void PyEval_SetTraceAllThreads(Py_tracefunc func, PyObject *obj)

مانند PyEval_SetTrace() است، اما به‌جای تنظیم تابع ردگیری فقط روی نخ فعلی، آن را در تمام نخ‌های در حال اجرا که به مفسر فعلی تعلق دارند تنظیم می‌کند.

فراخوانی‌کننده باید یک attached thread state داشته باشد.

مانند PyEval_SetTrace()، این تابع هر استثنایی را که هنگام تنظیم توابع ردگیری در تمامی نخ‌ها ایجاد شود نادیده می‌گیرد.

اضافه شده در نسخه‌ی 3.12.

ردگیری ارجاع

اضافه شده در نسخه‌ی 3.13.

typedef int (*PyRefTracer)(PyObject*, int event, void *data)

نوع تابع ردگیری‌ای که با استفاده از PyRefTracer_SetTracer() ثبت‌شده است. پارامتر اول یک شیء پایتون است که به‌تازگی ایجاد‌شده است (زمانی که event روی PyRefTracer_CREATE تنظیم‌شده باشد) یا در شرف نابودی است (زمانی که event روی PyRefTracer_DESTROY تنظیم‌شده باشد). آرگومان data همان اشاره‌گر مات است که هنگام فراخوانی PyRefTracer_SetTracer() ارائه‌شده است.

اگر یک تابع ردگیری جدید به‌جای تابع فعلی ثبت شود، فراخوانی تابع ردگیری با شیء تنظیم‌شده بر NULL و event تنظیم‌شده بر PyRefTracer_TRACKER_REMOVED انجام خواهد شد. این اتفاق درست پیش از ثبت تابع جدید رخ خواهد داد.

اضافه شده در نسخه‌ی 3.13.

int PyRefTracer_CREATE

مقدار پارامتر event در توابع PyRefTracer هنگامی که یک شیء پایتون ایجاد شده است.

int PyRefTracer_DESTROY

مقدار پارامتر event در توابع PyRefTracer هنگامی که یک شیء پایتون نابود شده است.

int PyRefTracer_TRACKER_REMOVED

مقدار پارامتر event برای توابع PyRefTracer هنگامی که ردیاب فعلی در شرف جایگزین‌شدن با ردیاب جدیدی است.

اضافه شده در نسخه‌ی 3.14.

int PyRefTracer_SetTracer(PyRefTracer tracer, void *data)

یک تابع ردیاب ارجاع ثبت کنید. این تابع هنگامی فراخوانی می‌شود که یک شیء جدید پایتون ایجاد شده باشد یا هنگامی که یک شیء در شرف نابود شدن است. اگر data ارائه شود، باید یک اشاره‌گر مات باشد که هنگام فراخوانی تابع ردیاب ارائه خواهد شد. در صورت موفقیت 0 را برگردانید. در صورت خطا یک استثنا تنظیم کنید و -1 را برگردانید.

توجه داشته باشید که توابع ردیاب نباید درون خود اشیاء پایتونی ایجاد کنند، در غیر این صورت فراخوانی بازورودپذیر خواهد بود. ردیاب همچنین نباید هیچ استثنای موجودی را پاک کند یا استثنایی تنظیم کند. هر بار که تابع ردیاب فراخوانی می‌شود، یک وضعیت نخ فعال خواهد بود.

هنگام فراخوانی این تابع، باید یک attached thread state وجود داشته باشد.

اگر تابع ردیاب دیگری از قبل ثبت شده باشد، تابع قدیمی درست پیش از ثبت تابع جدید، با event برابر با PyRefTracer_TRACKER_REMOVED فراخوانی می‌شود.

اضافه شده در نسخه‌ی 3.13.

PyRefTracer PyRefTracer_GetTracer(void **data)

تابع ردیاب ارجاع ثبت‌شده و مقدار اشاره‌گر داده‌ی مات را که هنگام فراخوانی PyRefTracer_SetTracer() ثبت شده بود، برمی‌گرداند. اگر هیچ ردیابی ثبت نشده باشد، این تابع NULL را برمی‌گرداند و اشاره‌گر data را برابر NULL قرار می‌دهد.

هنگام فراخوانی این تابع، باید یک attached thread state وجود داشته باشد.

اضافه شده در نسخه‌ی 3.13.