gdb로python 디버깅
개시하다
gdb로 ptyhon 프로세스를 연결하고 ptyhon 영역을 디버깅하는 방법입니다.
gdb에서 C/C++ 디버깅을 할 수 있지만,python 영역은 쉽게 볼 수 없기 때문에,pythn-debuginfo를 사용하여 디버깅 방법을 기록하십시오.
정보의 출처는 참고 문헌[1]을 참조한다.
언제 쓸 수 있을까요?
개발 환경
CentOS Linux release 7.7.1908 (Core)
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-115.el7
설정
(python 2.7의 경우)
# debuginfo-install python
(python 3의 경우)# debuginfo-install python3 libgcc
저도 다음과 같은 방법을 써서 시험용 창고를 효과적으로 설치했지만 debuginfo-install이 더 똑똑해 보여서 수정하고 있습니다.yum --disablerepo='*' --enablerepo='*-debug*' install python-debuginfo
pytohon3에서libgcc의 debuginfo를 설치해야 한다는 욕을 먹고 기록을 추가했다.다른 포장이 필요할지도 몰라요.만약 부족하다면, 다음에 기술한 gdb가 시작될 때, 설치해야 할 물건에 대해 메시지를 출력해야 합니까?사용법
$ gdb python <PID>
(python 2.7의 경우)
(gdb) source /usr/lib/debug/usr/lib64/libpython2.7.so.1.0.debug-gdb.py
(python 3의 경우)(gdb) source /usr/lib/debug/usr/lib64/libpython3.6dm.so.1.0-3.6.8-18.el7.x86_64.debug-gdb.py
이번에는 3.6.8을 사용했습니다./usr/lib/debug/usr/lib64/아래를 참조하여 해당 버전의 파일을 적절하게 적용하십시오.py-list
이 범위의 Pythhon 코드 출력py-bt
Pythhon 코드의 뒤로 추적 py-up
파이썬 스택py-down
파이썬 스택 아래py-print
Python 스택의 변수 표시py-locals
Python 스택 변수 목록 표시나는 사용 방법 등의 도움을 찾았지만 찾지 못했다.
정보, 명령 파일*이 있을 수 있습니다.debug-gdb.py의 소스를 보고, 어떤 지령을 사용할 수 있는지/어떻게 사용하는 것이 비교적 빠를 수 있는지 봅시다.
데모
무엇이든지 좋습니다. 다음은 이 보도를 위해 제작을 시도하는 절차입니다.
pythondebugggb.py
import threading
import time
class MultiThreadDeadLock(object):
'''
MultiThreadDeadLock
デッドロックを意図的におこすテスト用の実装
'''
def __init__(self):
'''
constructor
'''
self._counter = 0
self.main()
def increment(self, lock):
'''
カウンタをインクリメントします。
:param lock: (object) threading.Lock()で取得した排他用オブジェクト
:return: None
'''
while True:
time.sleep(0.1) # スレッド間の割り込み用に少し待たせる
lock.acquire()
self._counter += 1
lock.release()
def print_counter(self, lock):
'''
現在のカウンタを表示します。
デッドロックを再現するため3より大きい場合に意図的にロックを解放せずにExceptionをraiseします。
:param lock: (object) threading.Lock()で取得した排他用オブジェクト
:return: None
'''
while True:
time.sleep(0.1) # スレッド間の割り込み用に少し待たせる
lock.acquire()
print("counter = {}".format(self._counter))
if self._counter > 3:
# 意図的にExceptionをraiseして、デッドロックさせる。
# 実際には、予期しないところでExceptionがraiseされることだろう...
raise RuntimeError()
lock.release()
def main(self):
'''
メイン処理
:return: None
'''
lock = threading.Lock()
inc_thread = threading.Thread(target=self.increment, args=(lock,))
print_thread = threading.Thread(target=self.print_counter, args=(lock,))
inc_thread.start()
print_thread.start()
inc_thread.join()
print_thread.join()
if __name__ == '__main__':
MultiThreadDeadLock()
프로세스 ID 확인
ps 명령어나 pgrep로 찾아보세요.
gdb로 연결, 명령 파일 *.debug-gdb.실행py,실행py-bt
$ gdb python3 7066
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-115.el7
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /usr/bin/python3.6...Reading symbols from /usr/lib/debug/usr/bin/python3.6.debug...done.
done.
(中略)
done.
Loaded symbols for /lib64/libgcc_s.so.1
0x00007f5a083e8afb in futex_abstimed_wait (cancel=true, private=<optimized out>,
abstime=0x0, expected=0, futex=0x7f59fc000c10)
at ../nptl/sysdeps/unix/sysv/linux/sem_waitcommon.c:43
43 err = lll_futex_wait (futex, expected, private);
(gdb) source /usr/lib/debug/usr/lib64/libpython3.6dm.so.1.0-3.6.8-18.el7.x86_64.debug-gdb.py
(gdb) py-bt
Traceback (most recent call first):
<built-in method acquire of _thread.lock object at remote 0x7f5a011328c8>
File "/usr/lib64/python3.6/threading.py", line 1072, in _wait_for_tstate_lock
elif lock.acquire(block, timeout):
File "/usr/lib64/python3.6/threading.py", line 1056, in join
self._wait_for_tstate_lock()
File "pythondebuggdb.py", line 68, in main
inc_thread.join()
File "pythondebuggdb.py", line 26, in __init__
self.main()
File "pythondebuggdb.py", line 72, in <module>
MultiThreadDeadLock()
스레드 전환(gdb) info threads
Id Target Id Frame
2 Thread 0x7f5a01094700 (LWP 7067) "python3" 0x00007f5a083e8afb in futex_abstimed_wait (cancel=true, private=<optimized out>, abstime=0x0, expected=0, futex=0x2471020)
at ../nptl/sysdeps/unix/sysv/linux/sem_waitcommon.c:43
* 1 Thread 0x7f5a08d20740 (LWP 7066) "python3" 0x00007f5a083e8afb in futex_abstimed_wait (cancel=true, private=<optimized out>, abstime=0x0, expected=0, futex=0x7f59fc000c10)
at ../nptl/sysdeps/unix/sysv/linux/sem_waitcommon.c:43
(gdb) thread 2
[Switching to thread 2 (Thread 0x7f5a01094700 (LWP 7067))]
#0 0x00007f5a083e8afb in futex_abstimed_wait (cancel=true, private=<optimized out>,
abstime=0x0, expected=0, futex=0x2471020)
at ../nptl/sysdeps/unix/sysv/linux/sem_waitcommon.c:43
43 err = lll_futex_wait (futex, expected, private);
참고 문헌
다음은 각주 참조
각주
Debugging an inactive python process ↩︎
파이톤으로 gdb를 조작합니다. ↩︎
Reference
이 문제에 관하여(gdb로python 디버깅), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/ngw/articles/python-debug-gdb텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)