nginx_mod_h264_streaming-2.2.7 bug 导致nginx进程crash,When new version release to fix the problem about truncated mp4 make nginx crash? errorlog like *** glibc detected *** nginx: worker process: double free or corruption (!prev): 0x000000000b8dfe00 ***
2.3.2版本虽然解决这个问题,但会产生新问题:当文件不存在的时候返回415(不支持的文件类型,应该返回404)。另外一个没有经过验证的解决方案见下文。
一、错误产生过程
在t前台播放时,播放器显示video not found,用MP4Box查看该mp4文件信息是不完整的:
# MP4Box -info /data/video/b9463.mp4
Error opening file /data/video/b9463.mp4: IsoMedia File is truncated
二、nginx 错误日志示例:
2010/12/30 17:42:08 [alert] 31354#0: worker process 31357 exited on signal 6
*** glibc detected *** nginx: worker process: double free or corruption (!prev): 0x0000000001fc64e0 ***
======= Backtrace: =========
/lib/libc.so.6(+0x71ad6)[0x7f2344918ad6]
/lib/libc.so.6(cfree+0x6c)[0x7f234491d84c]
/lib/libc.so.6(fclose+0x14d)[0x7f2344909a1d]
nginx: worker process[0x46305a]
nginx: worker process[0x463b13]
nginx: worker process[0x460500]
nginx: worker process[0x404e43]
/lib/libc.so.6(__libc_start_main+0xfd)[0x7f23448c5c4d]
nginx: worker process[0x403579]
======= Memory map: ========
00400000-00485000 r-xp 00000000 08:07 96680 /usr/sbin/nginx
00685000-00692000 rw-p 00085000 08:07 96680 /usr/sbin/nginx
00692000-006a0000 rw-p 00692000 00:00 0
01faf000-0213d000 rw-p 01faf000 00:00 0 [heap]
7f233c000000-7f233c021000 rw-p 7f233c000000 00:00 0
7f233c021000-7f2340000000 ---p 7f233c021000 00:00 0
7f2343255000-7f234326b000 r-xp 00000000 08:09 16099 /lib/libgcc_s.so.1
三、原因
nginx_mod_h264_streaming-2.2.7 MP4拖拽模块遇到错误或者不完整的mp4文件时会导致进程crash,错误日志如:
*** glibc detected *** nginx: worker process: double free or corruption (!prev): 0x000000000b8dfe00 ***
影响该 work process 负责的所有链接。
四、解决
2.2.7的mp4模块问题出现在mp4_io.c: read_box(), 出错时会 fclose(infile)
509 if(fread(box_data, (off_t)atom->size_, 1, infile) != 1)
510 {
511 MP4_ERROR("Error reading %c%c%c%c atom/n",
512 atom->type_ >> 24, atom->type_ >> 16,
513 atom->type_ >> 8, atom->type_);
514 free(box_data);
515 fclose(infile);
而mp4_context_exit 尝试再次关闭它,产生了double free or corruption
543 static void mp4_context_exit(struct mp4_context_t* mp4_context)
544 {
545 free(mp4_context->filename_);
546
547 if(mp4_context->infile)
548 {
549 fclose(mp4_context->infile);
550 }
可以通过在 read_box fclose(infile)之后把infile置为空避免double free的问题
+ mp4_context->infile = NULL;
当然,作者未公布的版本2.3.2也fix了这个问题,但是有个新问题,同样需要patch(文件不存在会返回415...),估计还在bug fix阶段,未release
五、官方参考
http://h264.code-shop.com/trac/discussion/1/156?discussion_action=quote;
http://favortel.blog.sohu.com/158346223.html