標籤:sip kamailio gdb
要對kamailio/opensips進行單步調試,就需要先瞭解其代碼的結構及運行方式,kamailio/opensips使用Reactor和Proactor結合的IO網路模型,使用主進程負責監聽網路,當有串連產生或首包到達時,就通過pipe將檔案描述符發送給worker進程,worker進程就會負責此串連的資料取讀、業務處理、資料發送等事情,然後再次等待此socket事件。當我們想要調試一段代碼時,就先確認這段代碼是運行在什麼類型的進程中,通常用於處理SIP邏輯的代碼都是在worker進程中執行的,下面是一個kamailio進程啟動的執行個體:
[[email protected] sipserver]# kamctl ps
Process:: ID=0 PID=6651 Type=attendant
Process:: ID=1 PID=6653 Type=udp receiver child=0 sock=172.16.0.16:53
Process:: ID=2 PID=6654 Type=udp receiver child=1 sock=172.16.0.16:53
Process:: ID=3 PID=6656 Type=udp receiver child=2 sock=172.16.0.16:53
Process:: ID=4 PID=6658 Type=udp receiver child=3 sock=172.16.0.16:53
Process:: ID=5 PID=6661 Type=slow timer
Process:: ID=6 PID=6662 Type=timer
Process:: ID=7 PID=6665 Type=MI FIFO
Process:: ID=8 PID=6668 Type=ctl handler
Process:: ID=9 PID=6669 Type=SNMP AgentX
Process:: ID=10 PID=6672 Type=tcp receiver (generic) child=0
Process:: ID=11 PID=6674 Type=tcp receiver (generic) child=1
Process:: ID=12 PID=6676 Type=tcp receiver (generic) child=2
Process:: ID=13 PID=6677 Type=tcp receiver (generic) child=3
Process:: ID=14 PID=6679 Type=tcp main process上例中Type=tcp receiver和udp receiver這兩種類型的進程都是處理SIP訊息的,包括kamailio.cfg配置中route段都是在此進程中執行,通常我們為對SIP協議進行處理而開發的模組也都在此進程中執行。kamailio和opensips在代碼核心架構上是一致的,下面以kamailio為例說明如何使用gdb進行調試。偵錯工具有兩種方法:方法1直接用GDB運行kamailio:將kamailio.cfg配置為fork=no, 這樣kamailio會以單進程方式運行,所以的邏輯都將在一個進程裡執行,但單進程模式不支援TCP listen,所以要調試TCP邏輯,不能使用此方式。直接使用gdb調試kamailio主程式就行:
[[email protected] ~]# gdb /usr/sbin/kamailio
GNU gdb (GDB) Red Hat Enterprise Linux (7.0.1-45.el5)
Copyright (C) 2009 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/sbin/kamailio...done.
(gdb) b main.c:10
Breakpoint 1 at 0x45725c: file main.c, line 10.
(gdb) run
方法2 將kamailio運行起來後,再用gdb attach調試:第一種方法的缺點非常明顯,不能調試TCP進程,也不能將kamailio多進程的優勢發揮出來。將kamailio.cfg配置為fork=yes將以多進程方式啟動,與此相關的參數還有兩個:children=1 ;配置處理udp連接埠資料的進程數量tcp_children=1 ;配置處理tcp連接埠資料的進程資料,如果此參數未配置,預設使用children參數。如果使用以上參數啟動程式,如果listen參數有對應的連接埠,將會啟動1個UDP處理進程和1個TCP處理進程,執行個體如下:
[[email protected] sipserver]# kamctl ps
Process:: ID=0 PID=6651 Type=attendant
Process:: ID=1 PID=6653 Type=udp receiver child=0 sock=172.16.0.16:53
Process:: ID=5 PID=6661 Type=slow timer
Process:: ID=6 PID=6662 Type=timer
Process:: ID=7 PID=6665 Type=MI FIFO
Process:: ID=8 PID=6668 Type=ctl handler
Process:: ID=9 PID=6669 Type=SNMP AgentX
Process:: ID=10 PID=6672 Type=tcp receiver (generic) child=0
Process:: ID=14 PID=6679 Type=tcp main process當kamailio收到TCP資料時,會由6672進程進行處理,我們可以使用gdb attach到指定進程進行調試,執行個體如下:
[[email protected] ~]# gdb
GNU gdb (GDB) Red Hat Enterprise Linux (7.0.1-45.el5)
Copyright (C) 2009 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/>.
(gdb) attach 6672
Attaching to process 6672
......
(gdb) b redis_base.c:100
Breakpoint 1 at 0x2b6c45e70082: file redis_base.c, line 100.
(gdb) c
Continuing.
然後再設定斷點,執行run即可,當伺服器收到SIP訊息並運行到指定代碼即可單步調試,在調試過程中再結合日誌輸出,對定位問題非常有協助。關於如何使用gdb請參考文檔:http://wenku.baidu.com/link?url=UNUB8A6f2OGt_KJxU4p7-df-j9QFw2z2CFN6nCj4smzijx_UiMIkUTFh7JlOE-byIylp2yGfaTbtKPpOGR3lhTd09p3NTQtZDPrWp9N5pmu
新浪微博:@安靜的發狂者郵箱:dennis.yu(@)live.cnQQ:229675152專註於移動互連網音視頻通訊領域,歡迎交流;本文為原創,轉載請保留著作權並聯絡作者
kamailio/opensips 技術交流QQ群:118791050
opensips/kamailio gdb代碼調試方法詳解