서버를 만들고, 여러 테스트하는 것 중에 영구 접속이 끊어지는 상황을 재현하는 것은 쉽지 않을 수 있다. 디버거를 이용하여 간단히 종료시켜 보는 법을 알아 본다.

python으로 돌고 있는 데몬(pid 11688)이 있다고 하고, 데몬의 DB 접속은 영구 접속에 해당하는데, 이 접속을 강제로 종료시키는 것을 가정한다.

$ lsof -n -p 11688

COMMAND   PID   USER   FD   TYPE   DEVICE  SIZE/OFF      NODE NAME
python  11688 pynoos  cwd    DIR    202,3        80   1636949 /misc/django_projects/app/broadcast
python  11688 pynoos  rtd    DIR    202,3      4096       128 /
python  11688 pynoos  txt    REG    202,3      7216     53035 /usr/bin/python
python  11688 pynoos  mem    REG    202,3     12408 134524267 /usr/lib64/python/lib-dynload/grpmodule.so
python  11688 pynoos  mem    REG    202,3     13520 134538649 /usr/lib64/python/lib-dynload/_bisectmodule.so
python  11688 pynoos  mem    REG    202,3     48240 134524376 /usr/lib64/python/lib-dynload/arraymodule.so
python  11688 pynoos  mem    REG    202,3    694224 134524317 /usr/lib64/python/lib-dynload/unicodedata.so
python  11688 pynoos  mem    REG    202,3     24176 134524160 /usr/lib64/python/lib-dynload/zlibmodule.so
python  11688 pynoos  mem    REG    202,3     14496  69180222 /usr/lib64/libutil-2.17.so
...
... (생략)
...
python  11688 pynoos  mem    REG    202,3     19288  69048848 /usr/lib64/libdl-2.17.so
python  11688 pynoos  mem    REG    202,3    142232  69048881 /usr/lib64/libpthread-2.17.so
python  11688 pynoos  mem    REG    202,3   1847496  67226793 /usr/lib64/libpython.so.1.0
python  11688 pynoos  mem    REG    202,3    163400  69048840 /usr/lib64/ld-2.17.so
python  11688 pynoos    0r   CHR      1,3       0t0      1028 /dev/null
python  11688 pynoos    1u   CHR    136,4       0t0         7 /dev/pts/4
python  11688 pynoos    2u   CHR    136,4       0t0         7 /dev/pts/4
python  11688 pynoos    3w   REG    202,3   3009102 136203946 /misc/log/projects/app.log
python  11688 pynoos    4r   CHR      1,9       0t0      1033 /dev/urandom
python  11688 pynoos    5w   REG    202,3 266251952 135014754 /misc/log/projects/app.sql
python  11688 pynoos    6u  IPv4 26138940       0t0       UDP *:9413
python  11688 pynoos    7u  IPv4 26137372       0t0       TCP 10.1.1.1:33148->10.1.1.2:mysql (ESTABLISHED)

먼저 열려 있는 파일들의 리스트(list of open files; lsof)를 확인한다. 위의 예에서는 7u로 되어 있는 값이 mysql 커넥션 디스크립터다. 이 디스크립터를 종료하면 mysql과의 접속이 종료되는 것이다.

$ gdb /usr/bin/python  11688
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/python...Reading symbols from /usr/bin/python...(no debugging symbols found)...done.
(no debugging symbols found)...done.
Attaching to program: /usr/bin/python, process  11688
Reading symbols from /lib64/libpython.so.1.0...Reading symbols from /lib64/libpython.so.1.0...(no debugging symbols found)...done.
(no debugging symbols found)...done.
Loaded symbols for /lib64/libpython.so.1.0
Reading symbols from /lib64/libpthread.so.0...(no debugging symbols found)...done.
[New LWP 12995]
[New LWP 12994]
[New LWP 12992]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Loaded symbols for /lib64/libpthread.so.0
Reading symbols from /lib64/libdl.so.2...(no debugging symbols found)...done.
Loaded symbols for /lib64/libdl.so.2
...
... (생략)
...
Loaded symbols for /usr/lib64/python/lib-dynload/arraymodule.so
Reading symbols from /usr/lib64/python/lib-dynload/_bisectmodule.so...Reading symbols from /usr/lib64/python/lib-dynload/_bisectmodule.so...(no debugging symbols found)...done.
(no debugging symbols found)...done.
Loaded symbols for /usr/lib64/python/lib-dynload/_bisectmodule.so
Reading symbols from /usr/lib64/python/lib-dynload/grpmodule.so...Reading symbols from /usr/lib64/python/lib-dynload/grpmodule.so...(no debugging symbols found)...done.
(no debugging symbols found)...done.
Loaded symbols for /usr/lib64/python/lib-dynload/grpmodule.so
0x00007f0de576b953 in select () from /lib64/libc.so.6
(gdb) call close(7)
$1 = 0

gdb는 디버깅 중인 프로세스의 입장으로 간단한 시스템 콜을 호출 할 수 있는데, 마지막 명령처럼 "call close(7)" 을 호출하면, 디스크립터를 종료하게 된다. 그리고, ^D를 눌러 gdb를 종료하면 프로세스는 실행을 재개하며, 영문도 모르는 채 DB 접속이 끊어지는 상황을 만나게 된다.

Happy Debugging.

+ Recent posts