Mp4V2与ffmpeg静态库符号冲突问题解决
一、为什么静态符号会冲突
无论macho二进制类型,还是Windows上的PE格式,还是Linux上的ELF格式,里面都是按照特定格式存放的一个程序的代码和数据
比如Linux下的可执行文件格式,大致分为下面这些段
参考:https://www.ibm.com/developerworks/cn/linux/l-excutff/ 
不同操作系统支持的可执行文件格式不一样,但是不同平台上面可执行文件执行的流程是一样的。读取可执行文件,分别解析不同段,并解析之后,映射到进程中,
进程中的内存分布也是分段,这样方便数据组织和权限管理。
不同的静态库文件,映射到进程之后,还存在一个软连接的过程,想象一下,一个函数在其他B库中实现,A要使用的时候,是怎么调用的。
怎么知道B中方法的地址呢。
在B库映射到进程中后,A方法调用这个函数(符号)之前,操作系统已经找到这个符号在进程中的地址,建立符号->之际函数入口点的过程,就是符号表映射的过程,
这也是fishhook的原理,以上是我的理解。
二、分析工具介绍
有一个工具nm,能够用来分析二进制文件,可以扫描到可执行文件中的符号、以及相关信息。
NAME
nm - list symbols from object files SYNOPSIS
nm [-A|-o|--print-file-name] [-a|--debug-syms]
[-B|--format=bsd] [-C|--demangle[=style]]
[-D|--dynamic] [-fformat|--format=format]
[-g|--extern-only] [-h|--help]
[-l|--line-numbers] [-n|-v|--numeric-sort]
[-P|--portability] [-p|--no-sort]
[-r|--reverse-sort] [-S|--print-size]
[-s|--print-armap] [-t radix|--radix=radix]
[-u|--undefined-only] [-V|--version]
[-X 32_64] [--defined-only] [--no-demangle]
[--plugin name] [--size-sort] [--special-syms]
[--synthetic] [--target=bfdname]
[objfile...] DESCRIPTION
GNU nm lists the symbols from object files objfile.... If no object
files are listed as arguments, nm assumes the file a.out. For each symbol, nm shows:
# ... run man nm for detials.
不同符号的不同类型
| Value | Descripition | Note |
|---|---|---|
| A | The symbol's value is absolute, and will not be changed by further linking. | 符号绝对,链接过程不会改变 |
| B/b | The symbol is in the uninitialized data section (known as BSS). | 非初始化符号 |
| C | The symbol is common. | 公有符号,链接时会被同名符号覆盖 |
| D/d | The symbol is in the initialized data section. | 初始化符号 |
| G/g | The symbol is in an initialized data section for small objects. | 初始化符号,面向小数据访问优化 |
| I | The symbol is an indirect reference to another symbol. | 其它符号的间接引用 |
| N | The symbol is a debugging symbol. | 调试符号 |
| P | The symbols is in a stack unwind section. | 栈区符号(清空) |
| R/r | The symbol is in a read only data section. | 符号只读 |
| S/s | The symbol is in an uninitialized data section for small objects. | 非初始化符号,面向小数据访问优化 |
| T/t | The symbol is in the text (code) section. | 代码区符号 |
| U | The symbol is undefined. | 未定义或在外部定义的符号 |
| u | The symbol is a unique global symbol. | 全局唯一,GNU保留符 |
| V/v | The symbol is a weak object. | 弱定义符(详见C++强弱符号定义) |
| W/w | The symbol is a weak symbol that has not been specifically tagged as a weak object symbol. | emm...绕口令符号 |
| - | The symbol is a stabs symbol in an a.out object file. | stabs格式符号 |
| ? | The symbol type is unknown, or object file format specific. | NM也不认识的符号 |
rew@rew:/usr/lib64$ nm libpthread.a nptl-init.o:
U __default_pthread_attr
U __default_pthread_attr_lock
U _dl_cpuclock_offset
U _dl_get_tls_static_info
U _dl_init_static_tls
U _dl_pagesize
U _dl_wait_lookup_done
U __fork_generation
U __getrlimit
U __is_smp
U __libc_fatal
0000000000000008 C __libc_multiple_threads_ptr
U __libc_pthread_init
U __libc_setup_tls
U __libc_sigaction
U __libc_stack_end
U __lll_lock_wait_private
U __lll_unlock_wake_private
0000000000000000 b __nptl_initial_report_events
00000000000001b0 T __nptl_set_robust
U __nptl_setxid_error
0000000000000000 r nptl_version
00000000000004b0 T __pthread_get_minstack
00000000000001d0 T __pthread_initialize_minimal
00000000000001d0 T __pthread_initialize_minimal_internal
三、问题解决过程
最近发现,米家App中新引入了一个Mp4V2的.a静态库后,ffmpeg工作不正常了,Xcode调试过程中没有任何信息,只能看到crash

经过一番思索,猜测可能是这个库和ffmpeg本来的库存在符号冲突,使用nm工具导出所有符号
在静态库libmp4v2.a同级目录下面执行 命令
nm -U libmp4v2.a | grep -v ' t ' | grep -v ' s ' | grep -v ' d ' | grep -v ' b ' | awk '{print $3}' | tr -s '\n' > symbol.txt
看下symbol.txt的结果
cat symbol.txt

生成的符号结果很多,其中因为.a是fat结构,很多符号是冲突的。
一些符号明显带有mp4v2的标记,不可能跟ffmpeg冲突,所以,要对结果过滤下
编写一段脚本代码,过滤这个文本
过滤掉Mp4相关,并且去重
#!/usr/bin/env python3
# _*_ coding:utf-8 _*_
#
# @Version : 1.0
# @Time : 2019/6/29 3:13
# @Author : ddyt
# @File : LessSymbol.py
#
# 符号表处理 import cxxfilt if __name__ == '__main__':
s = set()
file = open("symbol.txt")
fileLines = file.readlines()
for line in fileLines:
if "mp4" not in line and line.rstrip() not in s and "MP4" not in line:
print(cxxfilt.demangle(line.rstrip()))
s.add(line.rstrip())
过滤结果

部分符号看起来很复杂,这个是C++类的方法经过编译器mangle之后生成的
将所有内容进行demangle,打开 https://demangler.com/,输入脚本生成的结果,demangle
可以看到一些复杂的符号,是C++ string的符号产生的,忽略掉这些符号

可以看到一些特殊的方法
_av_free
_av_freep
_av_log2
_av_log2_16bit
_av_malloc
_av_mallocz
_av_realloc
_av_realloc_array
_av_realloc_f
_av_reallocp
_av_reallocp_array
_avio_w8
_avio_wb16
_avio_wb32
_avio_write
_ff_avc_find_startcode
_ff_avc_parse_nal_units
_ff_avc_parse_nal_units_buf
_ff_golomb_vlc_len
_ff_interleaved_dirac_golomb_vlc_code
_ff_interleaved_golomb_vlc_len
_ff_interleaved_se_golomb_vlc_code
_ff_interleaved_ue_golomb_vlc_code
_ff_isom_write_hvcc
_ff_se_golomb_vlc_code
_ff_ue_golomb_len
_ff_ue_golomb_vlc_code
_mov_assm_hvcc_data
_mov_hvcc_add_nal_unit
_mov_write_hev1_tag
_mov_write_hvcc_tag
这些带有ff前缀和av前缀的,就是来自ffmpeg,这些符号就是冲突的根源
再看下crash时候的堆栈,最后一个方法avio_write在上面的符号中

现在冲突的原因找到了,处理思路分为两种
1、修改冲突的函数的名字
2、使用宏定义来修改函数的名字
这里采用第一种,使用Visual Code打开代码目录

然后,针对可能冲突的符号,逐一全局查找替换

到此,工作基本完成
修改完毕之后,合并测试
Mp4V2与ffmpeg静态库符号冲突问题解决的更多相关文章
- 解决QZ-SDK静态库libRPToolLib.a中avfoundation.o文件和kxMovie依赖的ffmpeg静态库libavdevice.a函数重复定义的问题
解决QZ-SDK静态库libRPToolLib.a中avfoundation.o文件和kxMovie依赖的ffmpeg静态库libavdevice.a函数重复定义的问题 在原来项目中导入全志v3相机的 ...
- 基于ffmpeg静态库的应用开发
最近几天在试着做基本ffmpeg静态库的开发,只有main中包含了avdevice_register_all 或avfilter_register_all,编译就通不过,undefined refre ...
- Windows 系统 vs2012 MinGW 编译ffmpeg 静态库
Windows系统下 vs2012编译ffmpeg 动态库 前面已经有文章讲述,本文将讲述如果编译生成ffmpeg静态库以方便 在vs2012下调用. 准备工作:安装MinGW环境,修改ffmpeg配 ...
- 为iOS编译FFmpeg静态库
为iOS编译FFmpeg静态库 环境:OS X Yosemite (版本10.10.5) Xcode (Version 7.1.1 (7B1005)) 一.资料准备: (1)ffmpeg源 ...
- iOS解决两个静态库的冲突 duplicate symbol
http://blog.163.com/023_dns/blog/static/118727366201391544630380/ 场景: 解决TencentOpenAPI.framework与Zba ...
- ffmpeg静态库Windows版本
GitHub上面有一个项目 提供了编译环境 以及编译好的静态库 https://github.com/ShiftMediaProject/FFmpeg
- 【FFMPEG】【ARM-Linux开发】 ffmpeg 静态库使用,undefined reference错误
原文:http://blog.csdn.net/chinazjn/article/details/7954984 ffmpeg移植到dm365上,遇到undefined reference错误: GA ...
- Msys2+mingw-w64 编译VS2013使用的ffmpeg静态库注意事项
1.环境准备 第一步:从http://sourceforge.net/projects/msys2/下载msys2的安装程序安装msys2; 第二步:通过msys2的包管理工具pacman安装ming ...
- xcode5下一个ffmpeg静态库配置
1.若要安装xcode命令行工具 1).xcode5安装命令行工具方法: 在终端运行命令Using xcode-select --install 2).xcode5之前安装命令行工具方法: 2.xco ...
- 【VS开发】Caffelib中出现的问题:强制链接静态库所有符号(包括未被使用的)
C++程序在链接一个静态库时,如果该静态库里的某些方法没有任何地方调用到,最终这些没有被调用到的方法或变量将会被丢弃掉,不会被链接到目标程序中.这样做大大减小生成二进制文件的体积.但是,某些时候,即使 ...
随机推荐
- 当 mysql-connector-java-5 遇上 MySQL8,终究还是错付了 → 门当户对真的很重要!
开心一刻 今天,老婆给我发消息 老婆:老公,儿子从隔壁邻居家回来了 老婆:是先打还是先洗? 我:先洗吧,万一打错人了呢 老婆:先洗脸吧,没错就边打边洗 起因 在我们的固有认知中, mysql-conn ...
- 嘉楠k210 多线程 点亮流水灯
from Maix import GPIO from fpioa_manager import fm import _thread import time fm.register(24, fm.fpi ...
- NOI 2024省选OIFC模拟21 蒲巴巴 超繁做法
题目描述 一年一度的 PuBaBa 杯开始了! 今年的 PuBaBa 杯总共有 \(n\) 个选手来参加,编号分别为 \(1,2,\cdots,n\),他们的水平按编号依次递增,所以他们过的题目数量单 ...
- Thinkphp5.x全漏洞复现分析
基础知识 命名空间和子命名空间 我们可以把namespace理解为一个单独的空间,事实上它也就是一个空间而已,子命名空间那就是空间里再划分几个小空间,举个例子: <?php namespace ...
- nginx请求头相关漏洞修复(http host&X-XSS-Protection)
nginx请求头相关漏洞修复(http host&X-XSS-Protection) 参考链接:Nginx常见漏洞处理 - 码农教程 (manongjc.com) Web应用漏洞-NGINX各 ...
- 阿里云安全运营中心:DDoS攻击趁虚而入,通过代理攻击已成常态
应用层DDoS攻击与传统的DDoS攻击有着很大不同.传统的DDoS攻击通过向攻击目标发起大流量并发式访问造成服务不可用,系统瘫痪,这种方式比较容易被识破,且市场上已经有成熟的应对方案.而近年来兴起的应 ...
- Apsara Stack 同行者专刊 | 怀同行之心,筑信任之基,践数智之行
简介: 政企云平台处在怎样的历史阶段?数智创新的同行者们面临着怎样的挑战与机遇?在时代巨幕下,政企期待云厂商扮演怎样的角色?阿里云智能研究员.混合云平台总经理刘国华认为,云厂商不仅需要有定力与实力,也 ...
- [FAQ] swagger-php 支持 Authorization Bearer token 校验的用法
@OA\SecurityScheme 可以是 Controller 层面也可以是 Action 层面. 类型 type="apiKey". in="header" ...
- [FAQ] Truffle Deployer 合约传参问题: Invalid number of parameters for "undefined". Got 0 expected 1!
在使用 `truffle migrate` 时,如果合约的构造函数需要传参,而部署脚本里没有传的时候,就会报这个错. 未传参时: const Migrations = artifacts.requir ...
- WPF 已知问题 清空 CollectionView 的 SortDescriptions 可能抛出空异常
本文记录一个 WPF 的已知问题,在通过 CollectionViewSource 获取到 CollectionView 之后,如果 CollectionViewSource 对象已被 GC 回收,将 ...