2011-12-18 10 views
1

저는 LD_PRELOAD를 사용하여 PyDict_New 함수를 가로 채려고합니다. 나는 this recipe이 파이썬 인터프리터에서 getpid로 작업했음을 확인했으며, 대신 adapted it to use PyDict_New을 가졌지 만 예상대로 작동하지 않는다. 사전을 명확하게 할당하고 있지만이 함수를 사용해야 할 경우에도 재정의가 호출되지 않습니다.는 LD_PRELOAD로 PyDict_New를 가로 챌 수 없습니다.

내가 뭘 잘못하고 있니?


배경 : 매우 큰 시스템에서 문제를 디버깅하려고합니다. 나는 나쁜 참조 카운트를 가진 dict가 있다는 것을 발견했다. dict이 처음으로 할당 된 곳과 문제가 어디에서 발생했는지는 알지만, 중간 시간에는 카운트가 나빠질 것이고 간단한 코드 추적은하지 않을 것입니다. dict는 캐시되고 다시 사용되기 때문입니다. (PyDict_New를 통해) gc 시스템에 의해.

답변

3

LD_PRELOAD는 동적으로로드되는 함수 만 오버로드 할 수 있습니다. Python 바이너리를 사용하는 경우 PyDict_New는 동적으로로드되지 않으므로 동적 로더가 해당 심볼의 해상도를 가로 챌 수 없습니다. 대신 자신의 바이너리를 컴파일하고 libpython.so와 링크하여 자신 만의 "파이썬"을 만들면 작동 할 것입니다. 다음은 프로그램 (/tmp/foo.c)에 넣어해야 할 것입니다 무엇 :

#include "Python.h" 

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

그리고 당신은 단순히 그것을 구축 할 수 있습니다 : 의 gcc -o foo는 -I는/usr/포함/python2.7 foo.c를 -lpython2.7

는이 작업을 수행 한 후, ./foo에 LD_PRELOAD 작동합니다.

+0

"스스로 동적으로로드"한다는 것은 무엇을 의미합니까? LD_PRELOAD가 -Bsymbolic로 컴파일되지 않은 공유 라이브러리의 전역 함수를 재정의 할 수 있습니까? –

+1

나는 실행 파일의 심볼이 ld.so에 의해 동적으로로드되지 않는다는 사실을 언급했다. ld.so에 의해로드되지 않기 때문에 LD_PRELOAD는 단순히 사용되지 않습니다. 이 경우, OP가 재정의하고자하는 함수는 python 실행 파일로 컴파일되었고 공유 라이브러리에서 ld.so에 의해로드되지 않았습니다. 제공된 솔루션에서 모든 파이썬은 libpython2.7.so에서 동적으로로드되므로 LD_PRELOAD가 작동합니다. -Bsymbolic에 관해서는, 저의 이해는 라이브러리가 실행 파일의 첫 번째를 보는 대신 자체 심볼을 먼저 선호하도록하는 것입니다. –

+0

나는 이것을 시험해 볼 필요가있다. – bukzor

1

나는 그냥 (귀하와 관련 버전에 대한) 파이썬의 소스 버전을 다운로드 디버그 모드에서 구축하고 그것으로 응용 프로그램을 실행하는 데 귀하의 경우 훨씬 쉬울 것 같아요.

이 방법을 사용하면 문제를 디버깅 할 때 훨씬 더 융통성있게 해결할 수 있습니다. 예를 들어 PyDict_New에 조건부 중단 점을 설정하거나 사용자 고유의 버전으로 바꿀 수 있습니다.

+0

이 질문에 답변하지는 않지만 투표를하겠습니다. 나는 그걸 생각하지 않았다. 나는 그런 낮은 수준에서 일하는 것에 익숙하지 않은 것 같다. – bukzor

+0

@bukzor : 귀하의 질문은 실제로 직접적으로 다루기에 충분한 세부 정보를 제공하지 않습니다 (코드, 컴파일/링크/실행 경로, 예상 출력, 표시 출력 등). 그렇지 않으면 현재 너무 추상적입니다.). 그럼에도 불구하고 내가 제안한 접근 방식은 문제를 더 빨리 디버깅하도록해야합니다. IMHO –

+0

내 게시물의 링크를 클릭하면 해당 정보를 모두 찾을 수 있습니다. 어쩌면 나는 그것들을 더욱 두드러지게/명료하게 만들어야한다. 내일 할거야. – bukzor