如何以最简单的方式调试Python C扩展中的引用计数?

2 投票
1 回答
633 浏览
提问于 2025-04-17 09:07

我做了一些Python的C扩展,虽然它们的行为都经过验证,但我想通过一些引用计数的调试来进一步确认。

我该如何确认我正确地插入了引用计数的增加和减少呢?我想从一个黑箱的角度来验证,也就是说,如果所有的引用计数都做得正确,一个函数的输入、输出和内存应该是什么样子的?

我第一步的想法是使用sys.getrefcount(obj)来检查所有输入和输出对象的引用计数,看看它们是否正常。其次,我还可以检查一下内存使用情况,确保没有内存泄漏。

不过我之前从来没有做过这些,所以最简单、最正确的方法是什么呢?

请注意:我不想使用任何Cython风格的库,我更愿意自己动手做C的细节,以便学习基础知识。

解决方案:根据建议,我构建了一个启用了调试的Python解释器。我以为这会很复杂,但其实并没有。根据这个方法,我在Objects/object.c中添加了那些确切的代码行。之后,我在下载的Python源代码目录中只需执行:

./configure --with-pydebug --prefix=/usr/local/python/
make
make install

关于如何将C扩展构建到这个新解释器中,我只需要在setup.py中的Extension部分将include_dirs标签指向'/usr/local/python/include/python2.7',然后用新解释器运行构建和安装命令。完成后,我可以在C代码中添加_Py_CountReferences(stderr);这一行,引用计数就会输出到stderr(控制台)。这样可以很好地看到引用计数的变化,以及代码执行过程中它是如何增加和减少的。

1 个回答

1

有一个建议:在调试模式下编译Python解释器(使用--with-pydebug选项)。用这个解释器来编译和测试你的扩展。这个解释器会显示对象的总数,而这个总数在你重复运行测试时不应该增加。确保测试你代码的所有可能退出路径——我曾经忘记在发生异常时减少对象的引用计数。

撰写回答