kamailio代码调试指南

kamailio源码对于初学者,阅读起来是有一定难度的,特别是kamailio里面最核心的路由脚本kamailio.cfg的理解。
静态方式阅读源码,往往无法深刻理解代码的运行逻辑,于是使用gdb工具来辅助理解源码将变得事半功倍。
那么在使用gdb调试之前,需要对kamailio的软件设计架构有个初步了解。kamailio是多进程架构,使用Reactor和Proactor结合的IO网络模型,使用主进程负责监听网络,当有连接产生或者首包到达时,就通过pipe(进程间管道通信)将文件描述符发给worker进程,worker进程就会负责此连接的数据读取、业务处理、数据发送等处理,然后再次等待socket事件。

下面是一个kamailio进程启动的实例:

[root@localhost sbin]# ./kamctl ps
{
  "jsonrpc":  "2.0",
  "result": [
    {
      "IDX":  0,
      "PID":  4919,
      "DSC":  "main process - attendant"
    }, {
      "IDX":  1,
      "PID":  4920,
      "DSC":  "udp receiver child=0 sock=172.20.74.81:5060"
    }, {
      "IDX":  2,
      "PID":  4921,
      "DSC":  "udp receiver child=1 sock=172.20.74.81:5060"
    }, {
      "IDX":  3,
      "PID":  4922,
      "DSC":  "udp receiver child=2 sock=172.20.74.81:5060"
    }, {
      "IDX":  4,
      "PID":  4923,
      "DSC":  "udp receiver child=3 sock=172.20.74.81:5060"
    }, {
      "IDX":  9,
      "PID":  4928,
      "DSC":  "slow timer"
    }, {
      "IDX":  10,
      "PID":  4929,
      "DSC":  "timer"
    }, {
      "IDX":  11,
      "PID":  4930,
      "DSC":  "secondary timer"
    }, {
      "IDX":  12,
      "PID":  4931,
      "DSC":  "JSONRPCS FIFO"
    }, {
      "IDX":  13,
      "PID":  4932,
      "DSC":  "JSONRPCS DATAGRAM"
    }, {
      "IDX":  14,
      "PID":  4933,
      "DSC":  "USRLOC Timer"
    }, {
      "IDX":  15,
      "PID":  4934,
      "DSC":  "ctl handler"
    }, {
      "IDX":  16,
      "PID":  4935,
      "DSC":  "TIMER NH"
    }, {
      "IDX":  17,
      "PID":  4936,
      "DSC":  "tcp receiver (generic) child=0"
    }, {
      "IDX":  18,
      "PID":  4937,
      "DSC":  "tcp receiver (generic) child=1"
    }, {
      "IDX":  19,
      "PID":  4938,
      "DSC":  "tcp receiver (generic) child=2"
    }, {
      "IDX":  20,
      "PID":  4939,
      "DSC":  "tcp receiver (generic) child=3"
    }, {
      "IDX":  21,
      "PID":  4940,
      "DSC":  "tcp receiver (generic) child=4"
    }, {
      "IDX":  25,
      "PID":  4944,
      "DSC":  "tcp main process"
    }
  ],
  "id": 4947
}

udp receiver和tcp receiver都是处理SIP消息的进程,包括kamailio.cfg配置中route段的代码都是在此进程中运行。为了方便调试,需要将kamailio配置为单进程运行模式,将kamailio.cfg中children=1

log_facility=LOG_LOCAL0
log_prefix="{$mt $hdr(CSeq) $ci} "

/* number of SIP routing processes for each UDP socket
 * - value inherited by tcp_children and sctp_children when not set explicitely */
children=1    //默认为8

/* uncomment the next line to disable TCP (default on) */
# disable_tcp=yes

/* number of SIP routing processes for all TCP/TLS sockets */
# tcp_children=8

设置单进程模式后,运行如下

[root@localhost sbin]# ./kamctl ps
{
  "jsonrpc":  "2.0",
  "result": [
    {
      "IDX":  0,
      "PID":  5036,
      "DSC":  "main process - attendant"
    }, {
      "IDX":  1,
      "PID":  5037,
      "DSC":  "udp receiver child=0 sock=172.20.74.81:5060"
    }, {
      "IDX":  2,
      "PID":  5038,
      "DSC":  "slow timer"
    }, {
      "IDX":  3,
      "PID":  5039,
      "DSC":  "timer"
    }, {
      "IDX":  4,
      "PID":  5040,
      "DSC":  "secondary timer"
    }, {
      "IDX":  5,
      "PID":  5041,
      "DSC":  "JSONRPCS FIFO"
    }, {
      "IDX":  6,
      "PID":  5042,
      "DSC":  "JSONRPCS DATAGRAM"
    }, {
      "IDX":  7,
      "PID":  5043,
      "DSC":  "USRLOC Timer"
    }, {
      "IDX":  8,
      "PID":  5044,
      "DSC":  "ctl handler"
    }, {
      "IDX":  9,
      "PID":  5045,
      "DSC":  "TIMER NH"
    }, {
      "IDX":  10,
      "PID":  5046,
      "DSC":  "tcp receiver (generic) child=0"
    }, {
      "IDX":  11,
      "PID":  5047,
      "DSC":  "tcp main process"
    }
  ],
  "id": 5050
}
(gdb) b auth_mod.c:854
Breakpoint 1 at 0x7fcba244f838: file auth_mod.c, line 854.

(gdb) c
Continuing.
Breakpoint 1, w_pv_auth_check (msg=0x7fcba9af8838, realm=0x7fcba9aabc18 "\250\006\253\251\313\177", passwd=0x7fcba9aabd78 "",
    flags=0x7fcba9aabed8 "\320\313\177", checks=0x7fcba9aabf78 "0窩\313\177") at auth_mod.c:854
854             return pv_auth_check(msg, &srealm, &spasswd, vflags, vchecks);
(gdb) bt
#0  w_pv_auth_check (msg=0x7fcba9af8838, realm=0x7fcba9aabc18 "\250\006\253\251\313\177", passwd=0x7fcba9aabd78 "",
    flags=0x7fcba9aabed8 "\320\313\177", checks=0x7fcba9aabf78 "0窩\313\177") at auth_mod.c:854
#1  0x00000000005eccf5 in do_action (h=0x7ffea97a06b0, a=0x7fcba9aae2b0, msg=0x7fcba9af8838) at core/action.c:1104
#2  0x00000000005f9e52 in run_actions (h=0x7ffea97a06b0, a=0x7fcba9aae2b0, msg=0x7fcba9af8838) at core/action.c:1584
#3  0x00000000005fa4ce in run_actions_safe (h=0x7ffea97a2de0, a=0x7fcba9aae2b0, msg=0x7fcba9af8838) at core/action.c:1648
#4  0x000000000044b5bc in rval_get_int (h=0x7ffea97a2de0, msg=0x7fcba9af8838, i=0x7ffea97a0c24, rv=0x7fcba9aae980, cache=0x0) at core/rvalue.c:949
#5  0x00000000004500ed in rval_expr_eval_int (h=0x7ffea97a2de0, msg=0x7fcba9af8838, res=0x7ffea97a0c24, rve=0x7fcba9aae978) at core/rvalue.c:1947
#6  0x0000000000450519 in rval_expr_eval_int (h=0x7ffea97a2de0, msg=0x7fcba9af8838, res=0x7ffea97a119c, rve=0x7fcba9aaf0a8) at core/rvalue.c:1955
#7  0x00000000005ec580 in do_action (h=0x7ffea97a2de0, a=0x7fcba9ab0de0, msg=0x7fcba9af8838) at core/action.c:1055
#8  0x00000000005f9e52 in run_actions (h=0x7ffea97a2de0, a=0x7fcba9aaac40, msg=0x7fcba9af8838) at core/action.c:1584
#9  0x00000000005eca0e in do_action (h=0x7ffea97a2de0, a=0x7fcba9aafaf8, msg=0x7fcba9af8838) at core/action.c:1070
#10 0x00000000005f9e52 in run_actions (h=0x7ffea97a2de0, a=0x7fcba9aa8050, msg=0x7fcba9af8838) at core/action.c:1584
#11 0x00000000005eca0e in do_action (h=0x7ffea97a2de0, a=0x7fcba9ab1ed8, msg=0x7fcba9af8838) at core/action.c:1070
#12 0x00000000005f9e52 in run_actions (h=0x7ffea97a2de0, a=0x7fcba9aa61a0, msg=0x7fcba9af8838) at core/action.c:1584
#13 0x00000000005e91ef in do_action (h=0x7ffea97a2de0, a=0x7fcba9a730e8, msg=0x7fcba9af8838) at core/action.c:703
#14 0x00000000005f9e52 in run_actions (h=0x7ffea97a2de0, a=0x7fcba9a6ec38, msg=0x7fcba9af8838) at core/action.c:1584
#15 0x00000000005fa596 in run_top_route (a=0x7fcba9a6ec38, msg=0x7fcba9af8838, c=0x0) at core/action.c:1669
#16 0x0000000000602cfa in receive_msg (
    buf=0xfc3160 "REGISTER sip:172.20.74.81;transport=tcp SIP/2.0\r\nVia: SIP/2.0/TCP 172.20.74.55:5060;branch=z9hG4bK481F610A005680374a14ac\r\nFrom: \"DESKTOP-C9B9OA2\" <sip:00008001@172.20.74.81>;tag=417D83E1-AC5A0620\r\nTo:"..., len=920, rcv_info=0x7fcb9e07dba0) at core/receive.c:515
#17 0x0000000000686e29 in receive_tcp_msg (
    tcpbuf=0x7fcb9e07df28 "REGISTER sip:172.20.74.81;transport=tcp SIP/2.0\r\nVia: SIP/2.0/TCP 172.20.74.55:5060;branch=z9hG4bK481F610A005680374a14ac\r\nFrom: \"DESKTOP-C9B9OA2\" <sip:00008001@172.20.74.81>;tag=417D83E1-AC5A0620\r\nTo:"..., len=920, rcv_info=0x7fcb9e07dba0, con=0x7fcb9e07db88)
    at core/tcp_read.c:1413
#18 0x0000000000688f3a in tcp_read_req (con=0x7fcb9e07db88, bytes_read=0x7ffea97a3614, read_flags=0x7ffea97a360c) at core/tcp_read.c:1604
#19 0x000000000068d2f6 in handle_io (fm=0x7fcba9b02e10, events=1, idx=-1) at core/tcp_read.c:1855
#20 0x000000000067a394 in io_wait_loop_epoll (h=0xb6a960 <io_w>, t=2, repeat=0) at core/io_wait.h:1070
#21 0x000000000068ec91 in tcp_receive_loop (unix_sock=23) at core/tcp_read.c:1976
#22 0x0000000000537b1d in tcp_init_children (woneinit=0x7ffea97a3a9c) at core/tcp_main.c:5229
#23 0x000000000042df80 in main_loop () at main.c:1849
#24 0x00000000004377f9 in main (argc=5, argv=0x7ffea97a4188) at main.c:3078
(gdb)

设置断后,再使用SIP终端进程注册,当服务器收到SIP消息,并运行到指定代码时,即可单步调试,同时查看调用堆栈,对位定位问题以及跟踪源码非常有帮助。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值