не может перехватить PyDict_New с LD_PRELOAD - PullRequest
1 голос
/ 18 декабря 2011

Я пытаюсь использовать LD_PRELOAD для перехвата функции PyDict_New.Я убедился, что этот рецепт работает с getpid в интерпретаторе python, и я адаптировал его для использования PyDict_New , но он просто не работает, как я ожидаю.Хотя я четко выделяю словари, и эту функцию нужно использовать, мое переопределение не вызывается.

Что я делаю не так?


Справочная информация: я пытаюсьотладить проблему в очень большой системе.Я обнаружил, что есть диктат с плохим количеством ссылок.Я знаю, где впервые указывается dict, и где проявляется проблема, но я почти уверен, что через какое-то промежуточное время счетчик выйдет из строя, и простая трассировка кода не сработает, поскольку dict кэшируется и используется повторно.(через PyDict_New) системой gc.

Ответы [ 2 ]

3 голосов
/ 21 декабря 2011

LD_PRELOAD может только перегружать функции, которые сами загружаются динамически. Если вы используете двоичный файл python, PyDict_New не загружается динамически, и поэтому у динамического загрузчика нет возможности перехватить разрешение этого символа. Если вместо этого вы создадите свой собственный «python», скомпилировав свой двоичный файл и соединив его с libpython.so, он должен работать. Вот что вам нужно добавить в вашу программу (/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

После того, как вы это сделаете, LD_PRELOAD on ./foo должен работать.

1 голос
/ 18 декабря 2011

Я думаю, в вашем случае было бы намного проще просто загрузить исходный дистрибутив Python (для соответствующей вам версии), собрать его в режиме отладки и запустить ваше приложение вместе с ним.

Этот метод предоставит вам гораздо больше гибкости в устранении проблемы. Например, вы можете установить условные контрольные точки в PyDict_New или просто заменить их собственной версией.

...