My Python program crashes with "Fatal Python error: deallocating None". What does this error mean?

My Python program crashes with "Fatal Python error: deallocating None". What does this error mean?

我一直在尝试找出一些 Python 从 C++(使用 swig)编译的代码的问题。

以下信息是通过使用 python3-dbg(python 版本 3.8)执行 gdb 检索到的。

Python 因以下错误而崩溃:

Fatal Python error: deallocating None
Python runtime state: initialized

调用堆栈中 python 代码的违规行是:

value = self.get(name)

请注意,name 的值应该是一个有效的字符串。这里似乎没有什么可能会导致问题,但它通常在处理同一组数据时发生。这行代码执行了几百次才报错

堆栈跟踪中对 none_dealloc 的第一次调用在这里:

#26 0x000000000046ef6e in none_dealloc (ignore=<optimized out>) at ../Objects/object.c:1585
#27 0x00000000004706da in _Py_Dealloc (op=<optimized out>) at ../Objects/object.c:2215
#28 0x00000000004470e8 in _Py_DECREF (op=<optimized out>, lineno=430, filename=0x699244 "../Objects/frameobject.c") at ../Include/object.h:478
#29 frame_dealloc (f=0x25938d0) at ../Objects/frameobject.c:430
#30 0x00000000004706da in _Py_Dealloc (op=op@entry=0x25938d0) at ../Objects/object.c:2215
#31 0x00000000004e02e6 in _Py_DECREF (op=0x25938d0, lineno=4314, filename=0x6e3343 "../Python/ceval.c") at ../Include/object.h:478
#32 _PyEval_EvalCodeWithName (_co=0x7fdc678c0520, globals=<optimized out>, locals=locals@entry=0x0, args=<optimized out>, argcount=2, kwnames=0x0, kwargs=0x7fdc6468cf90, kwcount=<optimized out>, kwstep=1, defs=0x7fdc678bf6f8, defcount=1, kwdefs=0x0, closure=0x0, name=0x7fdc67d0c270, qualname=0x7fdc678c2280) at ../Python/ceval.c:4314

这让我感到困惑,因为在 Python 3.8 中 Python 代码在 frameobject.c 430 处启动 dealloc 是:

/* Kill all local variables */
valuestack = f->f_valuestack;
for (p = f->f_localsplus; p < valuestack; p++)
    Py_CLEAR(*p);

Py_CLEAR 的定义在尝试减少引用计数并可能释放指针之前检查 NULL。这怎么会导致任何类型的错误?当我查看调用堆栈中 op 或 _py_tmp 的值时,它显示为“已优化”。

#define Py_CLEAR(op)                            \
    do {                                        \
        PyObject *_py_tmp = _PyObject_CAST(op); \
        if (_py_tmp != NULL) {                  \
            (op) = NULL;                        \
            Py_DECREF(_py_tmp);                 \
        }                                       \
    } while (0)

这个错误是什么意思?我应该寻找什么?

None 是 Python 中的特殊全局对象。 “deallocating None”错误的意思是“None”上的引用计数已达到 0,并且 None 将被解除分配(也称为删除)。这是一件坏事!

这可能意味着用 C/C++ 编写的导入 Python 模块中的一个函数返回 Py_None 而没有先调用 Py_INCREF(Py_None ).当有人丢弃它对 None 的引用时,错误随后会在看似随机、无害的代码行中的其他地方显示出来,因为 None 上的引用计数现在 1 太少了。有关详细信息,请参阅此问题:Why should Py_INCREF(Py_None) be required before returning Py_None in C?