`

在linux平台实现atosl

阅读更多

原文出自【听云技术博客】:http://blog.tingyun.com/web/article/detail/1342

序言

怎么在linux 平台下实现一个类似于mac 平台下的 atos 工具( iOS 符号化解析)?

分析问题

在github上找到了几年前的开源实现,[https://github.com/dechaoqiu/atosl](https://github.com/dechaoqiu/atosl)

编译出来的atosl工具平常很大几率是工作正常的,只有在特殊情况下会出现解析错误,主要表现为以下方式:

1、使用Swift 编写的app ,编译出来的 atosl 一定会解析错误(乱码形式) 

2、使用C+ + 实现的一些函数,编译出来的 atosl 解析出来的字符串也是乱码

3、在解析 iOS 系统framwork 框架的时候 有几率会出现解析错误(乱码形式) 

4、用户的某些崩溃信息不能定位到具体的 line no,编译出来的 atosl服务只能解析出来offset。

iOS dSYM 文件结构剖析

在 iOS App 开发过程中,我们会利用Xcode打包,生成.xarchive的包文件,通过Xcode 的Organizer 工具可以管理并导出发布文件,iOS 开发者对这些过程都是轻车熟路,这里不再重复阐述,主要想讲的是,打包之后生成的dSYM 文件。

01.png

dSYM 是一个目录,打开之后,我们会找到一个二进制文件如下图

02.png

可以看出iOS 使用的是DWARF文件结构 (Debug With Attributed RecordFormats) 是一种调试文件结构标准,结构相当复杂。

[https://www.prevanders.net/dwarf.html](https://www.prevanders.net/dwarf.html)

dSYM 文件的一个重要作用就在于,当我们的程序发生崩溃,通过crash log 或其他方式 ,会看到调用栈信息。 通过log信息,我们并不知道具体是在哪一个文件的哪一个位置出了问题, 这个时候这个二进制文件提供的信息就非常有用了,通过它我们可以通过工具 去符号化, Mac OS X 平台下 Xcode 自带了 atos 这样的工具,这样可以直接定位到某个文件的具体位置。 用法如下:

11.png

03.png

在 Mac OS 下有 dwarfdump 工具来解析DWARF文件,很显然解析出来的信息并不能满足我们的所有需求。

dwarfdump -a  SwfitTest

04.png

如果要了解其内部结构,请参考《iOS系统分析(二)Mach-O二进制文件解析》

思路

github 下载 atosl 源代码,C写的 

1.png

添加Cxx 与 Swift的错误样例

2.png

make test 结果如下,很明显 Cxx 与 Swift 符号化有问题,这就是我要解决的问题。

3.png

返回到mac os x中利用xcode 提供的 xcrun atos 处理,能够正确解析,(所以我要做的事情就是在linux平台下实现一个 类似于mac os x 平台下的  atos -\>输入输出相同)

4.png

解决C+ + 乱码的思考过程,在前面学习分析 Mach-O 文件的时候 使用过一个 MachOView 工具,然后我用工具打开QuartzCore 这个dSYM 文件,发现在 SymTables 里面解析出来的 字符串也是乱码,但是神奇的事情发生了,当我鼠标停留在某一行乱码的时候 复出了正确的解析字符串,这说明 MachOView 是能够正确解析C + + 名字的。果断 github 搜源代码. 从这里知道了 编译器在编译过程中会对函数做一些手脚,下面分析编译器的行为。

13.png

mangled symbol names (重整符号名称)

C/Cxx

在C这样的语言中,任何给定的名字(符号)只能对应唯一的一个函数或数据,不需要名字重整(name mangling)。即便如此,如果你看一个典型的纯C二进制的符号表,你会发现每个函数名有一个 (下划线)的前缀,如下:

5.png

这种简单的“mangling”(重整)已有很长的历史,实际上没有多少用处,但仍为兼容性和一致性起到一些效果。按照惯例,C中定义的名字会有下划线,而纯汇编定义的全局符号则没有(尽管许多汇编语言的作者为了一致性,也会预先考虑下划线的定义)。      

Objective-C  

它的符号名字不会有异议或者说冲突;Objective-C的方法实现的形式是: -[class selector](#),并且objective - c不允许相同的类使用不同的参数来重载相同的selectors。

Cxx 

一个没有额外信息的简单的名字可能会产生异议,所以必须做一些处理, 如下:

6.png

因为function对应两个包含不同参数的函数,这在cxx中是合法的定义,所以我们不能简单地生成两个\_ function符号,因为链接器会不知道如何链接,无法区分不同的函数实现。因此,cxx编译器使用一组严格的编码规则“mangles”(重整)了符号。

Swift

7.png

1. 最开始的字符’-‘对Swift符号是必须的

2. ‘-T’是Swift全局符号的标记

解决方法 

按照这个规则自己去还原符号也是可行的,不过还是比较费时,还可能有bug。

幸好Xcode 自带了个工具, 可以查看这些 mangled name 的本来面目,就不需要自己重新去实现.

解决思路过程

既然apple 提供了工具,那么我就不需要去自己写了,直接调用即可,在xcode的目录中找到了工具地址如下:

8.png

9.png

第一种解决方法 :管道通信 atosl 直接调用 swift-demangle 。

第二种解决方法 : 将swift-demangle.dylib 链接到程序中。

10-1.png

11-1.png

12.png

正确解析。接下来要想办法将这个小程序移植到Linux 平台下。

我猜这是Swift提供的工具,Google 发现Swift是源代码级别开源,果然支持Linux。

在linux上编译 Swift

配置环境编译之(Ubuntu 14.04),编译过程中有坑(内存必须配置5GB以上,硬盘30GB 以上)

warning:如果你遇到类似 clang: error: unable to execute command: Killed 的报错,不要多想,就是内存爆了,多试几次也许就成功了。

如果一切正常1小时就能编译完毕(我的硬件环境 MacBookAir  1.4GHz CPU   8GB 内存  固态硬盘,用了将近1个小时)。

第一种解决方案:swift编译完成后 在build/xxx/xxx/xxx/bin 下果然有ELF这个可执行文件

14.png

第二种解决方案: 使用编译出来的库文件

在lib目录下 没有找到 .so动态库,纳闷很久(swift的 编译脚本使用的是Cmake) Darwin 这个术语是指 mac  系统内核核心 (包括 xnu kernel 与 Unix Shell 环境),注释掉这里就可以将(Linux 共享库) .so 编译出来,如果要编译静态库 则需要修改cmake脚本,如下图:

15.png

16.png

17.png

18.png

19.png

共享库编译出来了,则直接动态链接到 atosl中,swift 只能在Ubutun上编译,如果最终你的atosl 要在 Linux的其他发行版上运行,最好将所有的依赖库用静态链接。

21.png

2

20.png

22.png

make test 

23.png

测试发现 cxx 与Swift的测试样例 的 offset(定位到的 line no 解析不出来),github上的代码已经很久没有人维护了,最后还是果断重写之。

24.png

end

(有任何问题请联系 email:liutianshxkernel@gmail.com)

0
0
分享到:
评论

相关推荐

    《网络编程与分层协议设计基于Linux平台实现》.(刘飚).[PDF]

    《网络编程与分层协议设计基于Linux平台实现》.(刘飚).[PDF]

    网络编程与分层协议设计基于linux平台实现

    以下是对“网络编程与分层协议设计基于Linux平台实现”这一主题的详细解析。 首先,网络编程涉及的主要知识点包括套接字编程、TCP/IP协议族以及并发处理。套接字是网络编程的基本接口,通过创建、绑定、监听和接受...

    在Linux平台上用多线程方法实现浮点向量的点积计算

    在Linux平台上用多线程方法实现浮点向量的点积计算: 点积规则可以自己定,程序中采用的是ai=bi=-1/1/0(按3取余运算),另外,计算程序运行时间. 输入格式为: vec_mul thread_num N 参数: thread_num:线程数,从1到...

    基于Linux平台实现不同权限的VNC用户登录方法.pdf

    在Linux平台上实现不同权限的VNC用户登录方法需要进行以下步骤: 1. 安装VNC Server 首先需要在Linux平台上安装VNC Server。可以使用rpm命令来安装VNC Server,例如:`rpm -q vnc`。 2. 配置VNC Server 安装完成...

    在嵌入式Linux中实现TFTP Server.pdf

    "在嵌入式Linux中实现TFTP Server" 本文档主要讨论了在嵌入式Linux中实现TFTP Server的方法和过程。TFTP(Trivial File Transfer Protocol)是一种简单的文件传输协议,常用于网络产品的软件或配置在线更新。在...

    linux 平台, modbus tcp 协议的简单实现

    在Linux平台上实现Modbus TCP协议是一项常见的任务,特别是在工业自动化和物联网(IoT)领域。Modbus是一种广泛应用的通信协议,允许设备之间进行数据交换,而TCP(Transmission Control Protocol)是网络层的一种传输...

    一个IPSec在Linux平台上的实现框架.pdf

    IPSec 在 Linux 平台上的实现框架 本文提出了一种在 Linux 平台上实现 IPSec 的框架,详细介绍了安全策略数据库 (SPD) 和安全关联数据库 (SAD) 的记录结构,分析了 Linux 的网络 IP 层代码,並給出了 IPSec 的原型...

    Linux操作系统在Windows平台上运行的仿真系统研究的实现方法.pdf

    "Linux 操作系统在 Windows 平台上运行的仿真系统研究的实现方法" 本文主要解决在 Windows 平台上实现 Linux 操作系统仿真运行的方法。该系统具有交互操作的功能,即使在没有 Linux 操作系统环境的情况下也能实现 ...

    LINUX平台下实现DCS画面的显示.pdf

    在Linux平台上实现DCS(分布式控制系统)画面的显示是一项技术挑战,主要涉及到操作系统、系统开发以及与DCS系统的集成。本文将深入探讨如何在Linux环境下,利用特定的技术和工具来展示DCS的画面。 首先,DCS是一种...

    操作系统实验 实验题目:多线程编程 在Linux平台上用多线程方法实现浮点向量的点积计算

    本科操作系统实验代码,使用多线程编程实现浮点向量的点积计算。

    MiniGUI图形库在嵌入式Linux平台上的移植与实现.pdf

    MiniGUI图形库在嵌入式Linux平台上的移植与实现 MiniGUI图形库是嵌入式Linux平台上的一种常用的图形库,具有良好的软件架构和可移植性。它能够提供对图形的支持,保证应用程序的顺利编译和实现。 1. MiniGUI的...

    16030110032_张瑞_网络应用程序设计实验.zip

    实验内容:在linux平台上实现1个TCP并发服务器,至少可以为10个客户端同时提供服务。 2. 进程间的协调通信(4学时) 掌握进程的概念、进程间通信的基本原理、集成间通信的主要类型和各自的特点。实验内容:在linux平台...

    JavaWeb应用在ARMLinux平台上的实现.pdf

    "JavaWeb应用在ARMLinux平台上的实现" 本文主要讨论了在ARMLinux平台上实现JavaWeb应用的详细过程。首先,作者们完成了Java虚拟机JAMVM、Java Web容器Winstone和嵌入式数据库Sqhte的移植配置,并成功地在ARMLinux...

    linux平台下C语言实现一个简单的httpsever

    在Linux平台上,使用C语言实现一个简单的HTTP服务器是一项基础但重要的技能,这涉及到网络编程、多线程处理以及文件操作等多个领域。以下是一些相关的知识点: 1. **TCP/IP协议与HTTP协议**: - TCP(传输控制协议...

    Linux平台下DNS服务器的实现与应用.pdf

    本文主要介绍了在Linux操作系统平台上实现DNS服务器的配置和应用。文章首先介绍了DNS服务器的背景和发展历程,然后详细介绍了DNS服务器的实现过程,包括 Bind 软件的安装和配置、DNS服务器的建立和应用。 DNS服务器...

    Linux平台下IPMI驱动程序实现.pdf

    在Linux平台下实现IPMI驱动程序需要解决以下几个问题: (1)如何设计和实现可扩展性强、使用方便并且支持多用户的IPMI驱动程序? (2)如何在Linux平台下实现IPMI驱动程序架构? (3)如何实现IPMI字符设备文件...

    基于Linux平台的通信软件的设计与实现.pdf

    在实现过程中,服务器端需处理并发连接,确保同时连接的多个客户端能够稳定运行。这通常通过多线程或异步IO模型来实现,如Linux的epoll机制。客户端则主要负责用户界面的交互,提供友好且高效的图形用户界面(GUI)...

    Linux下一个简单的文件系统实现

    开发者在实现XORFS时,需要将这些接口映射到XORFS的具体实现上,例如,如何在XORFS的数据结构中查找文件,如何分配和释放磁盘空间,以及如何处理文件的读写请求。 在`xorfs.c`中,开发者可能需要定义自己的超级块...

    基于Linux平台的通信软件的设计与实现_雷文礼.pdf

    在实现过程中,利用ADB(Android Debug Bridge)进行了在线调试,确保了发送和接收框的通信功能流畅运行。 该系统的成功开发为后续基于Linux平台的通信软件设计提供了实践基础和经验参考。在未来,随着Linux平台的...

Global site tag (gtag.js) - Google Analytics