Mp4V2与ffmpeg静态库符号冲突问题解决

2024-03-24 10:30

本文主要是介绍Mp4V2与ffmpeg静态库符号冲突问题解决,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、为什么静态符号会冲突

  无论macho二进制类型,还是Windows上的PE格式,还是Linux上的ELF格式,里面都是按照特定格式存放的一个程序的代码和数据

  比如Linux下的可执行文件格式,大致分为下面这些段

  参考:https://www.ibm.com/developerworks/cn/linux/l-excutff/    

  不同操作系统支持的可执行文件格式不一样,但是不同平台上面可执行文件执行的流程是一样的。读取可执行文件,分别解析不同段,并解析之后,映射到进程中,

  进程中的内存分布也是分段,这样方便数据组织和权限管理。

  不同的静态库文件,映射到进程之后,还存在一个软连接的过程,想象一下,一个函数在其他B库中实现,A要使用的时候,是怎么调用的。

  怎么知道B中方法的地址呢。

  在B库映射到进程中后,A方法调用这个函数(符号)之前,操作系统已经找到这个符号在进程中的地址,建立符号->之际函数入口点的过程,就是符号表映射的过程,

  这也是fishhook的原理,以上是我的理解。

二、分析工具介绍

  有一个工具nm,能够用来分析二进制文件,可以扫描到可执行文件中的符号、以及相关信息。

NAMEnm - list symbols from object filesSYNOPSISnm [-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...]DESCRIPTIONGNU nm lists the symbols from object files objfile....  If no objectfiles are listed as arguments, nm assumes the file a.out.For each symbol, nm shows:# ... run man nm for detials.

  不同符号的不同类型

ValueDescripitionNote
AThe symbol's value is absolute, and will not be changed by further linking.符号绝对,链接过程不会改变
B/bThe symbol is in the uninitialized data section (known as BSS).非初始化符号
CThe symbol is common.公有符号,链接时会被同名符号覆盖
D/dThe symbol is in the initialized data section.初始化符号
G/gThe symbol is in an initialized data section for small objects.初始化符号,面向小数据访问优化
IThe symbol is an indirect reference to another symbol.其它符号的间接引用
NThe symbol is a debugging symbol.调试符号
PThe symbols is in a stack unwind section.栈区符号(清空)
R/rThe symbol is in a read only data section.符号只读
S/sThe symbol is in an uninitialized data section for small objects.非初始化符号,面向小数据访问优化
T/tThe symbol is in the text (code) section.代码区符号
UThe symbol is undefined.未定义或在外部定义的符号
uThe symbol is a unique global symbol.全局唯一,GNU保留符
V/vThe symbol is a weak object.弱定义符(详见C++强弱符号定义)
W/wThe 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也不认识的符号

  比如:(参考 https://www.jianshu.com/p/a86bd1b8e4a5)
rew@rew:/usr/lib64$ nm libpthread.anptl-init.o:U __default_pthread_attrU __default_pthread_attr_lockU _dl_cpuclock_offsetU _dl_get_tls_static_infoU _dl_init_static_tlsU _dl_pagesizeU _dl_wait_lookup_doneU __fork_generationU __getrlimitU __is_smpU __libc_fatal
0000000000000008 C __libc_multiple_threads_ptrU __libc_pthread_initU __libc_setup_tlsU __libc_sigactionU __libc_stack_endU __lll_lock_wait_privateU __lll_unlock_wake_private
0000000000000000 b __nptl_initial_report_events
00000000000001b0 T __nptl_set_robustU __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 cxxfiltif __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静态库符号冲突问题解决的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/841314

相关文章

如何解决idea的Module:‘:app‘platform‘android-32‘not found.问题

《如何解决idea的Module:‘:app‘platform‘android-32‘notfound.问题》:本文主要介绍如何解决idea的Module:‘:app‘platform‘andr... 目录idea的Module:‘:app‘pwww.chinasem.cnlatform‘android-32

kali linux 无法登录root的问题及解决方法

《kalilinux无法登录root的问题及解决方法》:本文主要介绍kalilinux无法登录root的问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,... 目录kali linux 无法登录root1、问题描述1.1、本地登录root1.2、ssh远程登录root2、

SpringBoot应用中出现的Full GC问题的场景与解决

《SpringBoot应用中出现的FullGC问题的场景与解决》这篇文章主要为大家详细介绍了SpringBoot应用中出现的FullGC问题的场景与解决方法,文中的示例代码讲解详细,感兴趣的小伙伴可... 目录Full GC的原理与触发条件原理触发条件对Spring Boot应用的影响示例代码优化建议结论F

MySQL 中查询 VARCHAR 类型 JSON 数据的问题记录

《MySQL中查询VARCHAR类型JSON数据的问题记录》在数据库设计中,有时我们会将JSON数据存储在VARCHAR或TEXT类型字段中,本文将详细介绍如何在MySQL中有效查询存储为V... 目录一、问题背景二、mysql jsON 函数2.1 常用 JSON 函数三、查询示例3.1 基本查询3.2

Pyserial设置缓冲区大小失败的问题解决

《Pyserial设置缓冲区大小失败的问题解决》本文主要介绍了Pyserial设置缓冲区大小失败的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录问题描述原因分析解决方案问题描述使用set_buffer_size()设置缓冲区大小后,buf

PyInstaller打包selenium-wire过程中常见问题和解决指南

《PyInstaller打包selenium-wire过程中常见问题和解决指南》常用的打包工具PyInstaller能将Python项目打包成单个可执行文件,但也会因为兼容性问题和路径管理而出现各种运... 目录前言1. 背景2. 可能遇到的问题概述3. PyInstaller 打包步骤及参数配置4. 依赖

resultMap如何处理复杂映射问题

《resultMap如何处理复杂映射问题》:本文主要介绍resultMap如何处理复杂映射问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录resultMap复杂映射问题Ⅰ 多对一查询:学生——老师Ⅱ 一对多查询:老师——学生总结resultMap复杂映射问题

解决SpringBoot启动报错:Failed to load property source from location 'classpath:/application.yml'

《解决SpringBoot启动报错:Failedtoloadpropertysourcefromlocationclasspath:/application.yml问题》这篇文章主要介绍... 目录在启动SpringBoot项目时报如下错误原因可能是1.yml中语法错误2.yml文件格式是GBK总结在启动S

java实现延迟/超时/定时问题

《java实现延迟/超时/定时问题》:本文主要介绍java实现延迟/超时/定时问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java实现延迟/超时/定时java 每间隔5秒执行一次,一共执行5次然后结束scheduleAtFixedRate 和 schedu

idea maven编译报错Java heap space的解决方法

《ideamaven编译报错Javaheapspace的解决方法》这篇文章主要为大家详细介绍了ideamaven编译报错Javaheapspace的相关解决方法,文中的示例代码讲解详细,感兴趣的... 目录1.增加 Maven 编译的堆内存2. 增加 IntelliJ IDEA 的堆内存3. 优化 Mave