2014-09-10 1 views
2

파이썬이 ctypes를 사용하여 C 함수를 호출하는 코드를 디버깅하려고합니다. 관심이있는 Python 코드의 행은 다음과 같습니다.Ctypes - ctypes를 사용하는 파이썬 코드에서 C 백 트레이스 가져 오기

returnValue = cfunction() 

여기서 cfunction은 C 함수입니다. cfunction 코드에서 cfunction이 어디에서 반환되었는지 알고 싶습니다. 어떻게해야합니까?

파이썬에서 gdb를 사용할 수있는 것처럼 보이지만 위의 줄에 중단 점을 설정하고 C 코드에서 C 함수가 반환 된 위치를 표시 할 수 있도록 gdb를 사용하는 것이 올바른지 잘 모르겠습니다. 물론 -g로 컴파일 된 C 코드가 있습니다.

Linux에서 맥주 나 스피치와 같이 무료로 사용할 수있는 한 gdb를 사용해야하는 것은 아닙니다.

(I 7.7을 gdb를, 파이썬 2.7.6 실행 해요, 그리고 C 코드는 GCC 4.8.2로 컴파일됩니다.)

답변

1

당신이 (GDB 포함) 합리적인 디버거에서 python를 실행하면 여부를 시작하여 그것은 그런 식으로 또는 그것에 붙임으로써 확장 모듈로로드 된 Python의 일부가 ctypes 또는 다른 방법으로로드되었는지 여부와 상관없이 C 코드에서 중단 점을 만들 수 있습니다. 그리고, 그 일을 마치면, 당신은 원하는대로 다른 것을 한 줄씩 또는 한 줄씩 백 트래스를 인쇄 할 수 있습니다. 그것은 단지 일반적인 디버거 세션입니다. 물론 파이썬에는 디버깅 심볼이 없을 수도 있지만, .so를 위해 디버깅 심볼을 가지고있는 한 그것은 모두 당신이 신경 쓰는 것입니다.)

예를 들어 (lldb을 사용합니다. 완전히 gdb과 호환되는 명령의 하위 집합에 붙어 있습니다.) :

$ lldb python3 
Current executable set to 'python3' (x86_64). 
(lldb) run 
Process 6828 launched: '/Library/Frameworks/Python.framework/Versions/3.4/bin/python3' (x86_64) 
Process 6828 stopped 
* thread #1: tid = 0x8cf0d1, 0x00007fff5fc01028 dyld`_dyld_start, stop reason = exec 
    frame #0: 0x00007fff5fc01028 dyld`_dyld_start 
dyld`_dyld_start: 
-> 0x7fff5fc01028: popq %rdi 
    0x7fff5fc01029: pushq $0x0 
    0x7fff5fc0102b: movq %rsp, %rbp 
    0x7fff5fc0102e: andq $-0x10, %rsp 
(lldb) c 
Process 6828 resuming 
Python 3.4.1 (v3.4.1:c0e311e010fc, May 18 2014, 00:54:21) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import ctypes 
>>> libc = ctypes.CDLL('/usr/lib/libc.dylib') 
Process 6828 stopped 
* thread #1: tid = 0x8cf0d1, 0x00007fff8a7149aa libsystem_kernel.dylib`__select + 10, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP 
    frame #0: 0x00007fff8a7149aa libsystem_kernel.dylib`__select + 10 
libsystem_kernel.dylib`__select + 10: 
-> 0x7fff8a7149aa: jae 0x7fff8a7149b4   ; __select + 20 
    0x7fff8a7149ac: movq %rax, %rdi 
    0x7fff8a7149af: jmpq 0x7fff8a71119a   ; cerror 
    0x7fff8a7149b4: ret 
(lldb) b printf 
Breakpoint 1: where = libsystem_c.dylib`printf, address = 0x00007fff875cf8a8 
(lldb) c 
Process 6828 resuming 
>>> libc.printf('spam') 
Process 6828 stopped 
* thread #1: tid = 0x8cf0d1, 0x00007fff875cf8a8 libsystem_c.dylib`printf, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1 
    frame #0: 0x00007fff875cf8a8 libsystem_c.dylib`printf 
libsystem_c.dylib`printf: 
-> 0x7fff875cf8a8: pushq %rbp 
    0x7fff875cf8a9: movq %rsp, %rbp 
    0x7fff875cf8ac: pushq %r15 
    0x7fff875cf8ae: pushq %r14 
(lldb) bt 
* thread #1: tid = 0x8cf0d1, 0x00007fff875cf8a8 libsystem_c.dylib`printf, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1 
    * frame #0: 0x00007fff875cf8a8 libsystem_c.dylib`printf 
    frame #1: 0x0000000101a545e7 _ctypes.so`ffi_call_unix64 + 79 
    frame #2: 0x0000000101a5549f _ctypes.so`ffi_call + 575 
    frame #3: 0x0000000101a4f81f _ctypes.so`_ctypes_callproc + 879 
    frame #4: 0x0000000101a4772a _ctypes.so`PyCFuncPtr_call + 314 
    frame #5: 0x000000010000da08 Python`PyObject_Call + 104 
    frame #6: 0x00000001000e1c3f Python`PyEval_EvalFrameEx + 16975 
    frame #7: 0x00000001000e665d Python`PyEval_EvalCodeEx + 2349 
    frame #8: 0x00000001000e671f Python`PyEval_EvalCode + 63 
    frame #9: 0x000000010010f5ba Python`PyRun_InteractiveOneObject + 474 
    frame #10: 0x000000010010f93e Python`PyRun_InteractiveLoopFlags + 110 
    frame #11: 0x00000001001113e1 Python`PyRun_AnyFileExFlags + 161 
    frame #12: 0x000000010012867f Python`Py_Main + 3535 
    frame #13: 0x0000000100000e32 Python 
    frame #14: 0x0000000100000c84 Python 
(lldb) 
+0

죄송합니다. 내가하는 일을 요지로 생각하지만, 파이썬 스크립트에 어떻게 중단 점을 넣을 수 있는지 아직 확실하지 않습니다. 나는 내가 합법적으로이 문제에 대해 의문을 가질 수 있기 전에 디버거를 사용하는 방법에 대해 거의 알지 못한다고 생각한다. – raoulcousins

+0

@raoulcousins ​​: 파이썬 코드 나 C 코드에서 중단 점을 원합니까? 전자의 경우, C 레벨 디버거가 아닌'pdb'를 사용하기를 원합니다. 후자의 경우,'gdb' 또는 원하는 다른 디버거에 대한 자습서를 읽거나 코드 줄 옆에있는 코드 줄을 클릭하여 코드 줄을 추가 할 수있는 멋진 GUI IDE를 찾아야합니다. breakpoint ...하지만 기본적인 생각은'printf'입니다. 내 프로그램에'printf'라는 명확한 C 함수가 있다면, 그 명령은 그 함수의 시작 부분에 중단 점을 설정합니다. – abarnert

+0

@raoulcousins ​​: 상황이 조금 복잡해 질 수 있지만, 간단한 경우 ... 음,'mylib.cfunction()'을 쓰면'ctypes'에서 함수를 호출 할 수 있습니다. 보통 'gdb'에서 함수를 중단시킬 수 있습니다 'b 함수 '라고 쓰면됩니다. – abarnert

관련 문제