freeswitch 新通话启动过程梳理

概述

freeswitch是一款开源的VOIP软交换平台,功能强大。

在使用fs进行呼叫业务的过程中,我们最常见到的日志就是呼叫通道的启动信息,日志如下

2022-03-03 14:14:30.028832 [NOTICE] switch_channel.c:1133 New Channel sofia/internal/1001@192.168.0.152 [d70acc45-294c-4787-8dce-ff46d2cd96a1]

这行日志表示一个新的通话channel初始化完成。

如果我们希望知道channel是如何初始化和启动的,该如何去梳理代码流程呢,有以下几种方式。

1, 查看源码。但是fs的源码比较复杂,调用层次多,第三方库也多。

2, 打印跟踪日志。常规操作,最常见也最简单的方式。

3, 堆栈打印。使用系统库函数打印堆栈来查看调用流程。

今天我们介绍第3种方式,通过堆栈来查看channel的初始化流程。

环境

centos:CentOS  release 7.0 (Final)或以上版本

freeswitch:v1.8.7

GCC:4.8.5

代码修改

修改src\switch_channel.c文件,代码如下,其中print_stack函数用来打印函数堆栈信息。对于backtrace的介绍在网上有很多,这里就不详细说明了。

#include <execinfo.h>

static void print_stack()

{

void *stacktrace[99];

char **symbols;

int size;

int i;

size = backtrace(stacktrace, 99);

symbols = backtrace_symbols(stacktrace, size);

if (!symbols) {

return;

}

for (i = 0; i < size; i++) {

switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "STACK: %s\n", symbols[i]);

}

free(symbols);

}

SWITCH_DECLARE(switch_status_t) switch_channel_set_name(switch_channel_t *channel, const char *name)

{

const char *old = NULL;

switch_assert(channel != NULL);

if (!zstr(channel->name)) {

old = channel->name;

}

channel->name = NULL;

if (name) {

char *uuid = switch_core_session_get_uuid(channel->session);

channel->name = switch_core_session_strdup(channel->session, name);

switch_channel_set_variable(channel, SWITCH_CHANNEL_NAME_VARIABLE, name);

if (old) {

switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_NOTICE, "Rename Channel %s->%s [%s]\n", old, name, uuid);

} else {

switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_NOTICE, "New Channel %s [%s]\n", name, uuid);

print_stack();

}

}

return SWITCH_STATUS_SUCCESS;

}

对freeswitch的代码重新编译安装,并启动fs进程。

呼叫测试

1001号码通过SIP注册到FS服务器,并发起INVITE呼叫,呼叫不需要通过,仅仅关注主叫方A路的通道初始化过程。

------------------------------------------------------------------------

INVITE sip:1002@192.168.0.152 SIP/2.0

Via: SIP/2.0/UDP 10.9.0.70:25969;branch=z9hG4bK-d87543-010e715d272bcd27-1--d87543-;rport

Max-Forwards: 70

Contact: <sip:1001@10.9.0.70:25969>

To: "1002"<sip:1002@192.168.0.152>

From: "1001"<sip:1001@192.168.0.152>;tag=9b6ae45a

Call-ID: NDJjYzY2NDMwZmQ1ZWE5YmY3ZjE3MWNiNGIwNmQ5YWQ.

CSeq: 1 INVITE

Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO

Content-Type: application/sdp

User-Agent: eyeBeam release 1004p stamp 31962

Content-Length: 478

v=0

o=- 2 2 IN IP4 10.9.0.70

s=CounterPath eyeBeam 1.5

c=IN IP4 10.9.0.70

t=0 0

m=audio 41980 RTP/AVP 0 98 18 101

a=alt:1 4 : 2cib73mX anCjScUO 10.9.0.70 41980

a=fmtp:18 annexb=no

a=fmtp:101 0-15

a=rtpmap:98 iLBC/8000

a=rtpmap:101 telephone-event/8000

a=sendrecv

a=x-rtp-session-id:F73CAA782C7D401EBE0ACC803E495B81

------------------------------------------------------------------------

switch_channel.c:1133 New Channel sofia/internal/1001@192.168.0.152 [d70acc45-294c-4787-8dce-ff46d2cd96a1]

switch_channel.c:1112 STACK: /usr/local/freeswitch/lib/libfreeswitch.so.1(+0x5f14d) [0x7fc46acb314d]

switch_channel.c:1112 STACK: /usr/local/freeswitch/lib/libfreeswitch.so.1(switch_channel_set_name+0x129) [0x7fc46acb9b59]

switch_channel.c:1112 STACK: /usr/local/freeswitch/mod/mod_sofia.so(+0x89a7c) [0x7fc4612bea7c]

switch_channel.c:1112 STACK: /usr/local/freeswitch/mod/mod_sofia.so(+0x8a25e) [0x7fc4612bf25e]

switch_channel.c:1112 STACK: /usr/local/freeswitch/mod/mod_sofia.so(+0x5c3b7) [0x7fc4612913b7]

switch_channel.c:1112 STACK: /usr/local/freeswitch/mod/mod_sofia.so(+0x11dfc1) [0x7fc461352fc1]

switch_channel.c:1112 STACK: /usr/local/freeswitch/mod/mod_sofia.so(+0x151e52) [0x7fc461386e52]

switch_channel.c:1112 STACK: /usr/local/freeswitch/mod/mod_sofia.so(+0x1524a1) [0x7fc4613874a1]

switch_channel.c:1112 STACK: /usr/local/freeswitch/mod/mod_sofia.so(+0x61ea4) [0x7fc461296ea4]

switch_channel.c:1112 STACK: /usr/local/freeswitch/lib/libfreeswitch.so.1(+0x35bbd0) [0x7fc46afafbd0]

switch_channel.c:1112 STACK: /lib64/libpthread.so.0(+0x7ea5) [0x7fc468893ea5]

switch_channel.c:1112 STACK: /lib64/libc.so.6(clone+0x6d) [0x7fc467ee7b0d]

在上面的日志打印中,我们可以看到“STACK”的打印,就是函数调用堆栈的信息。

但是打印信息中,我们只能看到模块的名字和地址信息,看不到具体的函数名。

比如,在mod_sofia.so模块中,就有7次调用,无法看到函数名。

在尝试了对gcc编译参数增加“-ggdb”和“-rdynamic”之后,函数名的问题仍然无法解决。

后面通过“addr2line”工具,间接的查找到函数名。

函数名查看

通过“addr2line”工具,使用模块名和偏移地址,查找函数名。

addr2line 0x5f14d -e /usr/local/freeswitch/lib/libfreeswitch.so.1  -f

print_stack

/root/zr/freeswitch-1.8.7/src/switch_channel.c:1107

switch_channel.c:1112 STACK: /usr/local/freeswitch/lib/libfreeswitch.so.1(switch_channel_set_name+0x129) [0x7fc46acb9b59]

addr2line 0x89a7c -e /usr/local/freeswitch/mod/mod_sofia.so  -f

sofia_glue_set_name

/root/zr/freeswitch-1.8.7/src/mod/endpoints/mod_sofia/sofia_glue.c:70

addr2line 0x8a25e -e /usr/local/freeswitch/mod/mod_sofia.so  -f

sofia_glue_attach_private

/root/zr/freeswitch-1.8.7/src/mod/endpoints/mod_sofia/sofia_glue.c:208

addr2line 0x5c3b7 -e /usr/local/freeswitch/mod/mod_sofia.so  -f

sofia_event_callback

/root/zr/freeswitch-1.8.7/src/mod/endpoints/mod_sofia/sofia.c:2578

addr2line 0x11dfc1 -e /usr/local/freeswitch/mod/mod_sofia.so  -f

su_msg_is_non_null

/root/zr/freeswitch-1.8.7/libs/sofia-sip/libsofia-sip-ua/nua/../../libsofia-sip-ua/su/sofia-sip/su_wait.h:565 (discriminator 5)

addr2line 0x151e52 -e /usr/local/freeswitch/mod/mod_sofia.so  -f

su_base_port_execute_msgs

/root/zr/freeswitch-1.8.7/libs/sofia-sip/libsofia-sip-ua/su/su_base_port.c:283

addr2line 0x1524a1 -e /usr/local/freeswitch/mod/mod_sofia.so  -f

su_base_port_step

/root/zr/freeswitch-1.8.7/libs/sofia-sip/libsofia-sip-ua/su/su_base_port.c:473

addr2line 0x61ea4 -e /usr/local/freeswitch/mod/mod_sofia.so  -f

sofia_profile_thread_run

/root/zr/freeswitch-1.8.7/src/mod/endpoints/mod_sofia/sofia.c:3392

addr2line 0x35bbd0 -e /usr/local/freeswitch/lib/libfreeswitch.so.1  -f

dummy_worker

/root/zr/freeswitch-1.8.7/libs/apr/threadproc/unix/thread.c:152

addr2line 0x7ea5 -e /lib64/libpthread.so.0  -f

start_thread

pthread_create.c:?

channel初始化流程

从上面可以看出一通新的呼叫channel的初始化过程如下。

sofia_profile_thread_run->su_base_port_step->su_base_port_execute_msgs->su_msg_is_non_null->sofia_event_callback->sofia_glue_attach_private->sofia_glue_set_name->switch_channel_set_name

sofia_profile_thread_run,mod_sofia模块,启动profile端口监听。

su_base_port_step,sofia_sip库,端口收到消息。

su_base_port_execute_msgs,sofia_sip库,分发消息。

sofia_event_callback,mod_sofia模块,sip消息回调函数。

sofia_glue_attach_private,mod_sofia模块,初始化session和channel的参数设置。

sofia_glue_set_name,mod_sofia模块,设置channel名称。

switch_channel_set_name,freeswitch核心,设置channel名称。

到底为止,我们就回到了文章最开始的地方,日志打印“New Channel”的地方。

总结

我们使用了系统库函数backtrace和工具addr2line,得到了函数调用的流程。

在fs这种复杂的代码架构中,单纯使用backtrace无法解决全部问题。

查看代码流程多了一种不同的方式,对于工作中解决问题有帮助。


空空如常

求真得真

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容