当前位置: 首页 > Linux

linux平台下实现atosl

时间:2023-04-06 18:35:51 Linux

原文来自【听云科技博客】:http://blog.tingyun.com/web/a...前言如何实现一个类似mac平台下的atos工具linux平台(iOS符号分析)?为了分析问题,我在几年前在github上找到了一个开源实现。https://github.com/dechaoqiu/atosl编译的atosl工具,平时大概率工作正常,只有在特殊情况下才会出现解析错误,主要表现在以下几个方面:1.使用编写的appSwift,编译出来的atosl肯定会出现解析错误(形式是乱码)2.使用一些C++实现的函数,编译出来的atosl解析字符串也是乱码。3、解析iOS系统的framwork框架时,可能会出现解析错误(乱码形式)。4、用户的一些crash信息无法定位到具体的行号,编译的atosl服务只能解析偏移量。iOSdSYM文件结构分析在iOSApp开发过程中,我们会使用Xcode打包生成.xarchive包文件。Xcode的Organizer工具可用于管理和导出发布文件。iOS开发者熟悉这些流程,这里不再赘述。重复细说,主要想说的是打包后生成的dSYM文件。dSYM是一个目录。打开后,我们会发现一个二进制文件。如下图,可以看出iOS使用的是DWARF文件结构(DebugWithAttributedRecordFormats),这是一种调试文件结构标准,结构相当复杂。https://www.prevanders.net/dwarf.htmldSYM文件的一个重要作用就是当我们的程序崩溃时,我们会通过崩溃日志或者其他方法看到调用堆栈信息。通过日志信息,我们无法确切知道是文件的哪一部分出现了问题。这时候二进制文件提供的信息就非常有用了。通过它,我们可以通过工具去符号化它。在MacOSX平台下,Xcode自带了atos等工具,可以直接定位到文件的具体位置。使用方法如下:MacOS下有一个dwarfdump工具可以解析DWARF文件。显然,解析出来的信息并不能满足我们所有的需求。dwarfdump-aSwfitTest如果想了解其内部结构,请参考《iOS系统分析(二)Mach-O二进制文件解析》。ideagithub下载atosl源码,用C写的,添加Cxx和Swift错误示例使测试结果如下,很明显是Cxx和Swift符号化有问题,这就是我要解决的问题。回到macosx,使用xcode提供的xcrunatos处理,可以正确解析,(所以我要做的就是在linux平台上实现一个类似于macosx平台上的atos->输入输出相同)解决C++乱码的思考过程,我在研究和分析Mach-O文件时使用了一个MachOView工具,然后用该工具打开QuartzCoredSYM文件,发现字符串在SymTables中解析的也是乱码,但是神奇的事情发生了,当我的鼠标停留在某一行乱码上时,正确的解析字符串又回来了,这说明MachOView可以正确解析C++名称。果断去github上搜源码。从这里,我们知道编译器在编译过程中会对函数做一些技巧。让我们分析一下编译器的行为。mangledsymbolnames(重组符号名)C/Cxx在像C这样的语言中,任何给定的名字(symbol)只能对应一个唯一的函数或数据,不需要进行名字改编(namemangling)。尽管如此,如果你查看一个典型的纯C二进制文件的符号表,你会发现每个函数名都带有一个(下划线)前缀,如下所示:Thissimple"mangling"hasalonghistory,notreallyuseful,但对兼容性和一致性还是有一定影响的。按照惯例,在C中定义的名称将带有下划线,但在纯汇编中定义的全局符号不会(尽管许多汇编语言作者也会在定义前添加下划线以保持一致性)。    Objective-C其符号名称不会有异议或冲突;Objective-C的方法实现形式是:类选择器,Objective-c不允许同一个类使用不同的参数重复加载相同的选择器。cxx一个没有附加信息的简单名字可能会引起异议,所以必须做一些处理,如下:因为function对应两个参数不同的函数,在cxx中是合法的定义,所以我们不能简单的生成两个_函数符号,因为链接器不知道如何链接,也无法区分不同的函数实现。因此,cxx编译器使用一组严格的编码规则“破坏”符号。Swift首字符'-'是Swift符号必须的'-T'是Swift全局符号的标记解决方法按照这个规则自己恢复符号也是可行的,但是还是比较费时,而且可能有bug。幸运的是,Xcode附带了一个工具,可以让您检查这些错位名称的真面目,因此您无需自己重新实现它们。解决思路的过程既然apple提供了工具,那我就不用自己写了,直接调用即可。工具地址在xcode的目录下,如下:第一种方案:管道通信atosl直接调用swift-demangle。第二种解决方法:将swift-demangle.dylib链接到您的程序中。正确解析。接下来想办法把这个小程序移植到Linux平台上。我猜这是Swift提供的工具。Google发现Swift在源代码层面是开源的,而且它确实支持Linux。在linux上编译Swift配置环境并编译(Ubuntu14.04)。编译过程有坑(内存必须配置5GB以上,硬盘30GB以上)warning:如果遇到类似clang的错误:error:unabletoexecutecommand:Killed,Don'别想太多,只是内存满了,多试几次,说不定就能成功。一切正常的话,1个小时就能编译完成(我的硬件环境是MacBookAir1.4GHzCPU8GB内存SSD,用了将近1个小时)。第一种方案:swift编译完成后,在build/xxx/xxx/xxx/bin下有一个名为ELF的可执行文件。解决方法二:使用编译库文件在lib目录下找不到.so动态库,疑惑了半天(swift编译脚本用的是Cmake)darwin指的是mac系统的kernelcore(包括xnukernelandUnixShellenvironment),这里注释掉就可以编译(Linuxsharedlibrary).so,如果要编译静态库,需要修改cmake脚本,如下图:编译后,它将直接动态链接到atosl。Swift只能在Ubutun上编译。如果你的atosl要跑在其他Linux发行版上,最好静态链接所有依赖库。2make测试发现cxx和Swift测试样本的偏移量(定位到的行no无法解析),github上的代码好久没有维护了,最后果断重写。结束(如有问题请联系邮箱:liutianshxkernel@gmail.com)