일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- vi
- hostkeyalgorithms
- 노트북 배터리 교체
- 칼국수
- gdb tip
- ubuntu22.04
- linux
- 리눅스
- 인화여고
- whatis
- host key
- thread pid
- core file
- 괌
- 괌여행
- xshell4
- 출력
- Listen
- C
- 다수 클라이언트
- 껍질없는
- ubuntu
- kdumo
- 디버깅
- IPv6
- spacse
- 인천
- vcore
- 옛날 탕수육
- 노트북 정보
- Today
- Total
극히 개인적이고 극히 대단하지 않은
요긴한 gdb 명령들 본문
C로 프로그램을 작성하고 시험을 하다보면 수없이 많은 core 파일을 만나게 되는 경우가 있다. core 파일은 개발자 입장에서 별로 만나고 싶지 않은 파일이긴 하지만, 정상적으로 동작하지 않는 프로그램과 긴긴 시간을 씨름할 때에 있어서 core 파일은 때로는 사막에서 오아시스를 만나듯이 반가운 경우도 있다.
core파일을 얼마나 능수능란하게 다루고 요긴한 명령들을 조합해서 잘 쓰는가에 따라 core파일은 개발자에게 문제를 해결할 수 있는 명쾌하고 직관적인 정보를 주기도 하지만, 그렇지 않은 경우에는 문제점에 더불어 해결해야 할 숙제를 하나 더 떠안은 것 같은 부담으로 작용할 수도 있다.
core파이을 분석하기 위해 다양한 명령어를 쓰지만, 흔히 쓰지 않으면서도 알고 있으면 도움이 될만한 명령을 소개한다.
1. whatis
변수의 타입을 알려준다.
core파일을 디버깅하다보면 다양한 변수를 마주하게 되는데, 각 변수의 타입이 뭔지 명확하지 않으면 분석이 어려워질 수 있고, 소스를 옆에 열어놓고 변수의 선언부를 함께 확인해야 하는 번거로움이 있을 수 있는데, 이 명령은 그러한 번거로움을 깔끔하게 해결해준다.
해당 변수가 구조체인 경우 구조체의 정보를 알려준다.
(gdb) where
#0 0x0000000000000001 in ?? ()
#1 0x00007f02e9307471 in mariadb_reconnect () from /lib/x86_64-linux-gnu/libmariadb.so.3
#2 0x00007f02e9307bc1 in ?? () from /lib/x86_64-linux-gnu/libmariadb.so.3
#3 0x00007f02e9307e75 in mysql_ping () from /lib/x86_64-linux-gnu/libmariadb.so.3
#4 0x000055556e77becc in initR_CDR_DATA (mysql=0x0, endTime=0x7ffdfc288790 "2021-05-20 19:50:04") at appl/sip/TSM/db_util.c:1448
#5 0x000055556e6ed161 in bt_sighandler (sig=11, info=0x7ffdfc2889b0, secret=0x7ffdfc288880) at appl/sip/TSM/BSM_main.c:523
#6 <signal handler called>
#7 0x00007f02e9115028 in __GI__IO_fread (buf=0x5555716b7033, size=1, count=5, fp=0x555570f95da0) at iofread.c:37
#8 0x00007f02e940789e in file_read () from /usr/local/lib/libcrypto.so.1.1
#9 0x00007f02e9403c3e in bread_conv () from /usr/local/lib/libcrypto.so.1.1
#10 0x00007f02e9402806 in BIO_read () from /usr/local/lib/libcrypto.so.1.1
#11 0x00007f02e9663e69 in ssl3_read_n () from /usr/local/lib/libssl.so.1.1
#12 0x00007f02e966880e in ssl3_get_record () from /usr/local/lib/libssl.so.1.1
#13 0x00007f02e9665ef8 in ssl3_read_bytes () from /usr/local/lib/libssl.so.1.1
#14 0x00007f02e969ca01 in tls_get_message_header () from /usr/local/lib/libssl.so.1.1
#15 0x00007f02e969266d in state_machine.part () from /usr/local/lib/libssl.so.1.1
#16 0x00007f02e967d0c8 in SSL_do_handshake () from /usr/local/lib/libssl.so.1.1
#17 0x000055556ea8aa1b in RvTLSSessionServerHandshake (tlsSession=0x7f02dc235700, certCB=0x0, tcpSock=104, mtx=0x7f02db188420, logMgr=0x555570f95da0) at common/ccore/netdrivers/rvtls.c:1397
#18 0x000055556ea249d6 in TlsContinueHandshake (pConn=0x7f02db188318) at sip/transport/TransportTLS.c:1089
#19 0x000055556ea230b1 in TransportTLSHandleReadWriteEvents (pConn=0x7f02db188318, event=2) at sip/transport/TransportTLS.c:371
#20 0x000055556ea21337 in TransportTcpEventCallback (selectEngine=0x555570f9b098, fd=0x7f02db188320, selectEvent=2, error=0) at sip/transport/TransportTCP.c:1271
#21 0x000055556ea7c9d4 in RvSelectHandleSingleSelectFd (selectEngine=0x555570f9b098, selectEvent=2, hasError=0, fd=104) at common/ccore/netdrivers/rvselect.c:1909
#22 0x000055556ea7caca in RvSelectHandleEpollFds (selectEngine=0x555570f9b098, epFdSet=0x7f02dca03078, numFds=44016, numEvents=1) at common/ccore/netdrivers/rvselect.c:2234
#23 0x000055556ea7fc33 in RvSelectWaitAndBlock (selectEngine=0x555570f9b098, nsecTimeout=100000000000000000) at common/ccore/netdrivers/rvselect.c:5285
#24 0x000055556ea7f738 in RvSelectProcessEvents (selectEngine=0x555570f9b098) at common/ccore/netdrivers/rvselect.c:4715
#25 0x000055556e94cd32 in RvSipStackProcessEvents () at sip/stackMgr/RvSipStack.c:1893
#26 0x000055556e6f3641 in main (argc=2, argv=0x7ffdfc289ab8) at appl/sip/TSM/BSM_main.c:3574
(gdb)
예를 들어 위와 같은 core 파일이 있다고 가정할 때, 17번 frame에서 SSL_do_handshake() 를 호출했고 결국은 프로세스가 비정상 종료되었다면 다음과 같이 whatis 명령어로 필요한 frame에서 변수들의 type을 확인할 수 있다.
(gdb) frame 17
#17 0x000055556ea8aa1b in RvTLSSessionServerHandshake (tlsSession=0x7f02dc235700, certCB=0x0, tcpSock=104, mtx=0x7f02db188420, logMgr=0x555570f95da0) at common/ccore/netdrivers/rvtls.c:1397
1397 in common/ccore/netdrivers/rvtls.c
(gdb) whatis tlsSession
type = RvTLSSession *
2. ptype
변수의 타입과, 변수가 구조체로 선언되어 있는 경우 구조체를 구성하는 구성요소들을 확인할 수 있다.
(gdb) ptype tlsSession
type = struct {
SSL *sslSession;
BIO *bio;
RvSocket sock;
RvSelectEvents requiredForHandshake;
RvSelectEvents requiredForTLSRead;
RvSelectEvents requiredForTLSWrite;
RvSelectEvents requiredForTLSShutdown;
RvTLSEvents pendingTlsEvents;
RvTLSRenegState renegState;
RvBool bWaitingShutdownFinish;
RvUint32 counterWrites;
} *
3. set print pretty on
복잡한 구조체의 내용을 print 명령으로 출력하다보면 줄맞춤이 되지않아 보기 어려울 때 요긴하다. 특히 구조체 내에 다른 구조체를 포함한 경우에 가독성을 훨씬 높여준다.
(gdb) p *tlsSession
$2 = {sslSession = 0x5555716adba0, bio = 0x5555716af850, sock = 104, requiredForHandshake = 0, requiredForTLSRead = 0, requiredForTLSWrite = 0, requiredForTLSShutdown = 0, pendingTlsEvents = 0, renegState = RV_TLS_RENEG_NONE,
bWaitingShutdownFinish = 0, counterWrites = 0}
(gdb) set print pretty on
(gdb) p *tlsSession
$3 = {
sslSession = 0x5555716adba0,
bio = 0x5555716af850,
sock = 104,
requiredForHandshake = 0,
requiredForTLSRead = 0,
requiredForTLSWrite = 0,
requiredForTLSShutdown = 0,
pendingTlsEvents = 0,
renegState = RV_TLS_RENEG_NONE,
bWaitingShutdownFinish = 0,
counterWrites = 0
}
(gdb)
4. set print elements
디버깅을 하다보면 문자열이나 array의 길이가 다 출력되지 않고 잘려서 출력되는 경우가 있다. (...으로 잘림)
이런 경우에는 set print elements 뒤에 원하는 출력길이를 명시하면 그 길이까지 출력이 된다.
(gdb) p ph->data
$6 = 0x29157d0 "OPTIONS sip:jaOPwpQz@211.104.XXX.XXX SIP/2.0\r\nVia: SIP/2.0/UDP 192.241.207.17:45540;branch=zBrjvB.4690431032;rport;alias\r\nFrom: sip:MJagrVeB@192.241.207.17:45540;tag=41328117\r\nTo: sip:GPLWZfXH@211.104."...
(gdb) set print elements 1024
(gdb) p ph->data
$7 = 0x29157d0 "OPTIONS sip:jaOPwpQz@211.104.XXX.XXX SIP/2.0\r\nVia: SIP/2.0/UDP 192.241.207.17:45540;branch=zBrjvB.4690431032;rport;alias\r\nFrom: sip:MJagrVeB@192.241.207.17:45540;tag=41328117\r\nTo: sip:GPLWZfXH@211.104.XXX.XXX\r\nCall-ID: 4461338609@192.241.207.17\r\nCSeq: 1 OPTIONS\r\nContact: sip:mYaZFuNs@192.241.207.17:45540\r\nContent-Length: 0\r\nMax-Forwards: 20\r\nUser-Agent: rOHCvKym\r\nAccept: text/plain\r\n\r"
'20년차 개발자' 카테고리의 다른 글
다수 클라이언트 환경에서의 서버 소켓의 listen (0) | 2022.12.08 |
---|---|
리눅스에서 thread의 pid를 확인하는 코드 (0) | 2022.10.27 |
C 디버깅용 로그 출력할 때, 자동으로 함수이름과 라인번호 출력하기 (0) | 2020.09.11 |
vi 에디터로 hex모드로 에디팅 시 컬럼 수 늘이기 (0) | 2020.04.22 |
strace 로 프로세스 트레이스 할 때 출력문의 길이가 짧아서 곤란할 때. (0) | 2020.04.13 |