在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 文件。

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

可以看出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 这样的工具,这样可以直接定位到某个文件的具体位置。 用法如下:

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

dwarfdump -a  SwfitTest

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

思路

github 下载 atosl 源代码,C写的 

添加Cxx 与 Swift的错误样例

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

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

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

mangled symbol names (重整符号名称)

C/Cxx

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

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

Objective-C  

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

Cxx 

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

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

Swift

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

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

解决方法 

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

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

解决思路过程

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

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

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

正确解析。接下来要想办法将这个小程序移植到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这个可执行文件

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

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

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

2

make test 

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

end

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

时间: 2024-10-26 09:36:58

在linux平台实现atosl的相关文章

Oracle DG Linux平台逻辑Standby的创建实例

oracle,平台,linux,数据库,archive,sql 操作系统:linux redhat 4.7 Oracle: 10.2.0.1 主库:orcl_pd 备库:LGDG 一.逻辑Standby创建过程 1.创建物理Standby 具体的参考: Oracle Data Guard Linux 平台 Physical Standby 搭建实例 简单的做如下几点提示: (1)初始化参数配置 初始化参数的修改并不仅仅只是在待创建的Standby数据库端创建,当前的Primary数据库甚至同一个

Oracle DG Linux平台物理Standby搭建实例

Oracle Data Guard Linux 平台 Physical Standby 搭建实例 Data Guard 环境: 操作系统: redhat 4.7 Primary数据库: IP地址:10.85.10.1. 数据库SID:orcl DB_UNIQUE_NAME:orcl_pd Standby数据库: IP地址:10.85.10.2 数据库SID:orcl. DB_UNIQUE_NAME:orcl_st 一.rimary 端的配置 1.  主库设置为force logging 模式 S

Windows及Linux平台下的计时函数总结

本文对Windows及Linux平台下常用的计时函数进行总结,包括精度为秒.毫秒.微秒三种精度的各种函数. 比如Window平台下特有的Windows API函数GetTickCount().timeGetTime().及QueryPerformanceCounter(), Linux平台下特有的gettimeofday()函数,以及标准的C/C++函数time()和clock().下面分别对此进行简单介绍并附上示例代码. 通用的C/C++计时函数time()和clock() time_t ti

Linux平台下如何把幻灯片转换为Web页

经常接触演示文稿的朋友们都希望能够在Web页中浏览多页演示文稿.下面我就以RedOffice办公套件为例,介绍在Linux平台如何把专业幻灯片转换为Web页,同时进行Web页浏览. 具体实现的方法如下:打开演示文稿文档,执行"工具-Web页浏览"命令,通过"选择设置模板"."输入首页有关信息"."选择网页中按钮风格"."设置网页的颜色图案"四个步骤,就可实现多页演示文稿的Web页浏览. 选择设计模板 在弹出

在Linux平台及IPv4环境中构建IPv6测试环境

随着互联网技术的不断发展,传统的 IPv4 地址已不能满足用户的需要.新一代的 IPv6 协议也日益被广泛的接受和使用,越来越多的软件系统都要求支持 IPv6 网络协议.然而现有网络环境对 IPv6 的支持仍然非常有限,这给软件的开发和测试都带来了一定的困难.本文将介绍如何使用 Apache 在现有的 IPv4 网络中构建模拟的 IPv6 环境. 在 Linux 平台及 IPv4 环境中构建 IPv6 测试环境 1 IPv6简介 IPv6(Internet Protocol Version 6)

程序员最爱的Linux平台开发工具有哪些?

  Linux程序员经常抱怨,自从他们使用了免费开源的系统平台后,作为一名程序员,却并没有在代码编辑器上得到足够的重视.他们往往会认为Linux平台上的代码编辑器太少了,以至于影响他们的编程工作.但是事实并非如此,在Linux平台上有太多的代码编辑器供你使用了,下面我们分享了5个最受Linux程序员欢迎的代码编辑器,继续在编程的路上前行吧! 1.Eclipse Eclipse是一款很酷的开源代码编辑器,同时它也是最受程序员亲睐的代码编辑器之一,它拥有代码高亮和智能提示等强大的功能.在Eclips

Linux平台网络电话skype Alpha功能介绍

  Linux平台网络电话skype Alpha功能介绍 微软在今天面向Linux用户发布了一个全新的Skype版本--Linux Skype Alpha,这也是Linux版Skype在2014年来的首次新版更新. 这次更新后,Linux版Skype将会获得现在的Skype应有的功能,包括图片/视频聊天.文件共享以及全新的符号.在用户界面方面也进行了重做,使整个操作过程更流畅. 不过值得注意的事,旧版的Linux Skype仍然存在,毕竟现在这个只是个Alpha版.但是Linux Skype A

Mirai物联网僵尸攻击竟然可以在Linux平台和Windows平台之间交叉传播

本文讲的是Mirai物联网僵尸攻击竟然可以在Linux平台和Windows平台之间交叉传播, 近日,卡巴斯基实验室通过监测,发现一个全新的物联网木马正在通过Windows设备传播.最早卡巴斯基实验室的安全研究人员观察到这个推送Mirai下载器的扩展器变体是在2017年1月,但其实这个Windows木马以前就有了,只不过通过Windows进行传播的途径也非常有限.不过,如果Mirai木马强制性的远程实施Telnet命令连接,就会从Windows主机传播到Linux主机,尽管这个传播方法目前还没有经

iLinux:Linux平台最大的自定义图标收藏铺

Linux Icons可能是Linux平台上最大的图标收藏铺,它的创作灵感来源于Linux,Windows和Mac OS系统. 在Linux平台可用的高品质图标甚少,即使有几百种不同的软件包. iLinux Icons 的开发者从三个不同的平台:Ubuntu,Windows和Mac OS上设法收集和整理了那些类似的图标(在一些情况下甚至更好的). 安装非常简单,可以用一个简单的PPA帮助.只需在终端中输入以下命令: sudo add-apt-repository ppa:noobslab/ico