在linux平臺實現atosl

来源:http://www.cnblogs.com/TingyunAPM/archive/2016/11/17/6075219.html
-Advertisement-
Play Games

➠更多技術乾貨請戳:聽雲博客 序言 怎麼在linux 平臺下實現一個類似於mac 平臺下的 atos 工具( iOS 符號化解析)? 分析問題 在github上找到了幾年前的開源實現,[https://github.com/dechaoqiu/atosl](https://github.com/de ...


更多技術乾貨請戳:聽雲博客

序言

怎麼在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:[email protected]

 原文鏈接:http://blog.tingyun.com/web/article/detail/1342


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ? alias for 'help' base print or set address offset bdinfo print Board Info structure boot boot default, i.e., run 'bootcmd' bootd boot default, i.e., ...
  • 參考docker從入門到實戰 使用 Supervisor 來管理進程 Docker 容器在啟動的時候開啟單個進程,比如,一個 ssh 或者 apache 的 daemon 服務。但我們經常需要在一個機器上開啟多個服務,這可以有很多方法,最簡單的就是把多個啟動命令放到一個啟動腳本裡面,啟動的時候直接啟 ...
  • docker使用小技巧 殺死所有正在運行的容器 刪除所有的已經停止的容器 刪除所有鏡像 可以為這些命令創建別名 實時查看容器日誌 ...
  • 本文鏈接:http://www.cnblogs.com/MartinChentf/p/6076075.html (轉載請註明出處) 在Linux系統中,mkdir命令用來創建一個目錄或一個級聯目錄。 1. 命令格式 mkdir [選項] 目錄名 2. 命令選項 -m=mode 為目錄指定訪問許可權,與 ...
  • 第一步:安裝numlockx,輸入命令 第二步:用 vim 打開 rc.local 文件,輸入命令 第三步:修改文件內容,在exit 0前增加以下內容並保存 vim怎麼插入內容呢? 1.快捷鍵 i:切換到插入模式 2.方向鍵調整游標到插入位置 3.複製粘貼代碼 4:Esc鍵退出插入模式,回到預設的命 ...
  • linux下文件的複製、移動與刪除命令為:cp,mv,rm一、文件複製命令cp 命令格式:cp [-adfilprsu] 源文件(source) 目標文件(destination) cp [option] source1 source2 source3 ... directory 參數說明: -a: ...
  • ftp
    vsftp 1.安裝軟體 yum install vsftpd-y systemctl start vsftpd systemctl stop firewalld |enable firewalld -cmd --list-all firewalld -cmd --add-service=ftp - ...
  • 先決條件:操作前請確認執行了$ sudo apt-get -y install vim的VIM安裝,linux預設只有VI。 vi(vim)是上Linux非常常用的編輯器,很多Linux發行版都預設安裝了vi(vim)。vi(vim)命令繁多但是如果使用靈活之後將會大大提高效率。vi是“visual ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...