searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

自研切片录制服务器系统livecached 问题分析及解决过程

2023-05-31 09:49:37
11
0

1.    问题描述

       在南京中心CICD测试服务器环境下,新动漫频道在播放过程中,会出现core,导致livecached进程产生段错误,从而发生系统崩溃问题。

       Core文件内容:

       

       Core时nginx日志信息:

       

2.    Core原因及分析过程

2.1.        分析过程

       从core文件的段错误位置,判断在执行ngx_h264_parse.c中: start_code_prefix(bitsctx) 时,访问bitsctx时发生段错误。

       从相应代码段处可以看到,start_code_prefix(bitsctx)中所引用的bitsctx来源于

                     h264ctx->bitsctx

       代码段如下:

     

       因此,分析core文件中h264ctx堆栈信息:使用指令 p *h264ctx

       记录堆栈信息如下:

       可以看到h264ctx->bitsctx和h264ctx->log的地址信息被写为0x10101010100和0x101000001010101的0、1组合

       

       此时,为了获取bitsctx(环形缓冲区索引结构指针)的真正地址,在代码中H264解析方法前后增加日志打印,最终打印结果如下:

       

       可见,真实的bitsctx的指针地址应为0x00007FB106B94010,说明h264ctx->bitsctx应该被误修改过。

       由于h264ctx结构体的生命周期和频道一致,相关成员变量的赋值均在ngx_mpegts_parse_H264()方法内完成,因此合理推测,是由于上一次H264解包时,由于某些字段的错误解析,导致赋值越界,并且,赋值越界只可能存在于带有指针属性的相关赋值中(因为确定类型的非指针属性的变量,其边界是确定的,不会发生赋值越界;对于有指针属性的,比如数组、指针变量,使用循环体或者memcpy等方式进行赋值时,编译器不会检查是否赋值越界)。

       从core文件中h264ctx结构体的堆栈信息中,可见

              nal_unit_type = 6

       这代表着,上一次h264解析的是SEI类型的数据包体

     

       相关解析方法为h264_nal_parse_sei()

       从h264ctx结构体相关定义中,发现与SEI类型解析相关的结构体如下:

     

       其中具有指针属性的成员变量为图中红框内容,包括:

       int32_t                             initial_cpb_removal_delay[32];

       int32_t                             nitial_cpb_removal_delay_offset[32];

       uint8_t                             clock_timestamp_flag[3];

与initial_cpb_removal_delay、nitial_cpb_removal_delay_offset相关的代码如下所示:

从h264ctx堆栈信息中,可以看到for循环赋值所依赖的cpb_cnt_minus1 = 0,因此,这两个数组均没有发生越界赋值问题(越界需要cpb_cnt_minus1>=32,32为initial_cpb_removal_delay的数组长度)。

接下来分析clock_timestamp_flag[3]的赋值:

从相关代码段中可以分析到,如果clock_timestamp_flag[3]赋值越界,需要NumClockTS>=3。而NumClockTS依赖于sei_num_clock_ts_table[pt->pic_struct]。

从h264ctx堆栈信息中,得到pic_struct = 12

查找sei_num_clock_ts_table数组定义:如下

重点来了:sei_num_clock_ts_table数组长度只有9,且最大成员值为3,而在本次解析中:

       NumClockTS = sei_num_clock_ts_table[pt->pic_struct]

NumClockTS获取的值,是sei_num_clock_ts_table尾后位置的值,此数值未必在0~8之间,如果超过9,那么NumClockTS的值将不可预知,在for循环赋值之中,就会循环向后赋值,导致clock_timestamp_flag成员之后的h264ctx结构体中相关成员被错误赋值(覆盖)。

在相关代码段增加打印信息,打印NumClockTS

可以看见,NumClockTS的值为110,远超过最大值3。

正是这个错误,导致了本次core问题。

2.2.        Core原因

       由于在H264解析中,解析SEI类型时,由于解析clock_timestamp_flag [3]所依赖的pic_struct字段的值大于sei_num_clock_ts_table[9]的边界,从而NumClockTS取值错误,发生赋值越界,导致 h264ctx->bitsctx被错误赋值。当下一次进入H264解析时,访问错误地址段,导致段错误。详细分析过程见上。

3.    解决办法

       查阅H264相关手册,pic_struct相关内容如下,其有效值为0~8,与代码实现时一致。但是9~15为保留值,应予以相关处理,保证代码在pic_struct出现非0~8时,不会出现意外取值。

     

       代码修改如下:

当pic_struct取值9~15之间(最大值15,因为其有效长度为4bit)时,NumClockTS = 0,不进行相关内容解析,避免越界赋值。

0条评论
0 / 1000
潘****羽
3文章数
0粉丝数
潘****羽
3 文章 | 0 粉丝
原创

自研切片录制服务器系统livecached 问题分析及解决过程

2023-05-31 09:49:37
11
0

1.    问题描述

       在南京中心CICD测试服务器环境下,新动漫频道在播放过程中,会出现core,导致livecached进程产生段错误,从而发生系统崩溃问题。

       Core文件内容:

       

       Core时nginx日志信息:

       

2.    Core原因及分析过程

2.1.        分析过程

       从core文件的段错误位置,判断在执行ngx_h264_parse.c中: start_code_prefix(bitsctx) 时,访问bitsctx时发生段错误。

       从相应代码段处可以看到,start_code_prefix(bitsctx)中所引用的bitsctx来源于

                     h264ctx->bitsctx

       代码段如下:

     

       因此,分析core文件中h264ctx堆栈信息:使用指令 p *h264ctx

       记录堆栈信息如下:

       可以看到h264ctx->bitsctx和h264ctx->log的地址信息被写为0x10101010100和0x101000001010101的0、1组合

       

       此时,为了获取bitsctx(环形缓冲区索引结构指针)的真正地址,在代码中H264解析方法前后增加日志打印,最终打印结果如下:

       

       可见,真实的bitsctx的指针地址应为0x00007FB106B94010,说明h264ctx->bitsctx应该被误修改过。

       由于h264ctx结构体的生命周期和频道一致,相关成员变量的赋值均在ngx_mpegts_parse_H264()方法内完成,因此合理推测,是由于上一次H264解包时,由于某些字段的错误解析,导致赋值越界,并且,赋值越界只可能存在于带有指针属性的相关赋值中(因为确定类型的非指针属性的变量,其边界是确定的,不会发生赋值越界;对于有指针属性的,比如数组、指针变量,使用循环体或者memcpy等方式进行赋值时,编译器不会检查是否赋值越界)。

       从core文件中h264ctx结构体的堆栈信息中,可见

              nal_unit_type = 6

       这代表着,上一次h264解析的是SEI类型的数据包体

     

       相关解析方法为h264_nal_parse_sei()

       从h264ctx结构体相关定义中,发现与SEI类型解析相关的结构体如下:

     

       其中具有指针属性的成员变量为图中红框内容,包括:

       int32_t                             initial_cpb_removal_delay[32];

       int32_t                             nitial_cpb_removal_delay_offset[32];

       uint8_t                             clock_timestamp_flag[3];

与initial_cpb_removal_delay、nitial_cpb_removal_delay_offset相关的代码如下所示:

从h264ctx堆栈信息中,可以看到for循环赋值所依赖的cpb_cnt_minus1 = 0,因此,这两个数组均没有发生越界赋值问题(越界需要cpb_cnt_minus1>=32,32为initial_cpb_removal_delay的数组长度)。

接下来分析clock_timestamp_flag[3]的赋值:

从相关代码段中可以分析到,如果clock_timestamp_flag[3]赋值越界,需要NumClockTS>=3。而NumClockTS依赖于sei_num_clock_ts_table[pt->pic_struct]。

从h264ctx堆栈信息中,得到pic_struct = 12

查找sei_num_clock_ts_table数组定义:如下

重点来了:sei_num_clock_ts_table数组长度只有9,且最大成员值为3,而在本次解析中:

       NumClockTS = sei_num_clock_ts_table[pt->pic_struct]

NumClockTS获取的值,是sei_num_clock_ts_table尾后位置的值,此数值未必在0~8之间,如果超过9,那么NumClockTS的值将不可预知,在for循环赋值之中,就会循环向后赋值,导致clock_timestamp_flag成员之后的h264ctx结构体中相关成员被错误赋值(覆盖)。

在相关代码段增加打印信息,打印NumClockTS

可以看见,NumClockTS的值为110,远超过最大值3。

正是这个错误,导致了本次core问题。

2.2.        Core原因

       由于在H264解析中,解析SEI类型时,由于解析clock_timestamp_flag [3]所依赖的pic_struct字段的值大于sei_num_clock_ts_table[9]的边界,从而NumClockTS取值错误,发生赋值越界,导致 h264ctx->bitsctx被错误赋值。当下一次进入H264解析时,访问错误地址段,导致段错误。详细分析过程见上。

3.    解决办法

       查阅H264相关手册,pic_struct相关内容如下,其有效值为0~8,与代码实现时一致。但是9~15为保留值,应予以相关处理,保证代码在pic_struct出现非0~8时,不会出现意外取值。

     

       代码修改如下:

当pic_struct取值9~15之间(最大值15,因为其有效长度为4bit)时,NumClockTS = 0,不进行相关内容解析,避免越界赋值。

文章来自个人专栏
CDN自研切片录制 livecached
3 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0