1

我正在尝试使用 LD_PRELOAD 来拦截 PyDict_New 函数。我已经验证了这个配方在 python 解释器中与 getpid 一起工作,并且我已经对其进行了调整以使用 PyDict_New,但它根本不像我预期的那样工作。虽然我清楚地分配了字典,并且必须使用这个函数,但我的覆盖没有被调用。

我究竟做错了什么?


背景:我正在尝试在一个非常大的系统中调试问题。我发现有一个引用计数错误的字典。我知道第一次分配 dict 的位置,以及问题出现的位置,但我很确定在某个中间时间计数会变坏,并且简单的代码跟踪不会做,因为 dict 被缓存并重用(通过 PyDict_New)由 gc 系统。

4

2 回答 2

3

LD_PRELOAD 只能重载本身动态加载的函数。如果您使用的是 python 二进制文件,则 PyDict_New 不会动态加载,因此动态加载器无法拦截该符号的解析。如果您通过编译自己的二进制文件并与 libpython.so 链接来创建自己的“python”,它应该可以工作。以下是您需要放入程序 (/tmp/foo.c) 的内容:

#include "Python.h"

int
main(int argc, char **argv)
{
    return Py_Main(argc, argv);
}

你可以简单地构建它: gcc -o foo -I/usr/include/python2.7 foo.c -lpython2.7

完成此操作后, ./foo 上的 LD_PRELOAD 应该可以工作。

于 2011-12-20T20:45:17.763 回答
1

我认为在您的情况下,只需下载 Python 的源代码分发(与您相关的版本),在调试模式下构建它并使用它运行您的应用程序会容易得多。

此方法将在调试问题时为您提供更大的灵活性。例如,您可以在其中设置条件断点PyDict_New或将其替换为您自己的版本。

于 2011-12-18T04:15:46.397 回答