Python|在 C 中使用 Iterable 并诊断故障
本文旨在编写使用来自任何可迭代对象(例如列表、元组、文件或生成器)的项目的 C 扩展代码。
代码 #1:C 扩展函数,显示如何使用可迭代的项目。
static PyObject* py_consume_iterable(
PyObject* self, PyObject* args)
{
PyObject* obj;
PyObject* iter;
PyObject* item;
if (!PyArg_ParseTuple(args, "O", &obj)) {
return NULL;
}
if ((iter = PyObject_GetIter(obj)) == NULL) {
return NULL;
}
while ((item = PyIter_Next(iter)) != NULL) {
/* Use item */
... Py_DECREF(item);
}
Py_DECREF(iter);
return Py_BuildValue("");
}
上面的代码反映了Python中的类似代码。 PyObject_GetIter()
调用与调用iter()
获取迭代器相同。 PyIter_Next()
函数调用迭代器上的 next 方法,返回下一项,如果没有更多项,则返回 NULL。确保你小心内存管理—— Py_DECREF()
需要在生成的项目和迭代器对象本身上调用以避免内存泄漏。诊断分段错误 –
解释器因分段错误、总线错误、访问冲突或其他致命错误而剧烈崩溃。人们喜欢获取Python回溯,以显示程序在发生故障时运行的位置。
faulthandler 模块可用于帮助您解决此问题。在您的程序中包含以下代码。
代码#2:
import faulthandler
faulthandler.enable()
或者,使用 -Xfaulthandler 选项运行Python ,例如:
bash % python3 -Xfaulthandler program.py
最后但同样重要的是,可以相应地设置 PYTHONFAULTHANDLER 环境变量。启用故障处理程序后,C 扩展中的致命错误将导致在失败时打印Python回溯。例如:
Fatal Python error: Segmentation fault
Current thread 0x00007fff71106cc0:
File "example.py", line 6 in foo
File "example.py", line 10 in bar
File "example.py", line 14 in spam
File "example.py", line 19 in
Segmentation fault
虽然这不能说明 C 代码中哪里出了问题,但至少它可以说明它是如何从Python到达那里的。
故障处理程序将显示失败时执行的Python代码的堆栈回溯。至少,这将显示被调用的顶级扩展函数。借助pdb或其他Python调试器,可以调查导致错误的Python代码流。
在评论中写代码?请使用 ide.geeksforgeeks.org,生成链接并在此处分享链接。