一、背景
首先說需求,這個需求非常常見,就是android上需要的一個功能,linux已經有開源代碼而且非常穩定,希望能直接porting過去使用,這個程序是pure c 的代碼,也就是說,跟android framework, java 沒關系,也跟jni沒有關系,我們希望的就是能編譯成一個可執行工具,push到android后能直接跑起來使用。
既然是native 代碼,主要影響到的就是bionic libc, 因為android的這個基礎庫跟 linux 上常見的 gnu libc 有區別,主要是被精簡了,至於更具體理解什么叫被精簡,建議找個linux 開源工具代碼在 android ndk 環境里編一下就知道了,其實,這里邊還隱藏另外兩層區別,一個是 android api level, 就是所謂的android 版本,比如 android 4.4.4 對應 android API 19, android 5 對應 android API 21 , 不同版本的 bionic libc 本身也是有區別的。 另一個是 abi , 就是體系架構的區別,比如 x86, x86_64, armeabi -v7a 等等,不同 abi 設置下 bionic libc 用到的接口也不一樣。上面這兩個影響會導致,你的代碼可能在 API 21 編譯通過了,但是在 API 19 失敗,或者,在 armeabi-v7a 成功了,但是在 arm64-v8a 失敗了。這兩點的處理放在另外的文章說明,這篇文章不考慮。可以認為,我們暫時不考慮編譯出來的工具的通用性,只在特定的目標,如 abi = armeabi-v7a, api = 21 的android devices 上運行。
好了,我們已經編成功了這個工具,push 到目標設備后(或模擬器)發現運行出現段錯誤,這是非常常見的,因為在移植過程中,我們把某些 glibc 的調用替換成了 bionic 的調用,接下去應該怎么調試呢?首先說這里的調試,當然是源碼級別的單步調試,就是我們在 linux 上開發並調試程序一樣。這個要求看似簡單,但我搜索了一天的時間,嘗試了多種方式,最后才找到一種簡單可用且匹配需求的方式。
二、方法
首先,嘗試搜索 gdb-for-arm 的工具,就是看有沒有一個 gdb 可執行程序,是可以直接在 android arm devices 上運行的,如果有的話,就跟直接在 linux 環境里調試一樣了,可惜,這么簡單的需求,都搜索不到
下面都是嘗試用遠程調試的方式
第一種,客戶端在win7. 使用 ida pro 6.6 , 它提供了一個 android_server 可以用來push到 android 系統里運行,然后在 ida 的界面里 run remote 可執行程序,這種方式可以跑起來,可以單步執行、可以下斷點,但是無法加載正確的符號表。
第二種,客戶端在win7,找了一個 http://gnutoolchains.com/android/ 為android 編譯好的 gnu tool chains 網站,下載 gdbserver 和 gdb.exe , gdbserver push到目標機器跑起來,本地用 gdb.exe 啟動,使用gdb 遠程調試那套步驟進行設置,發現也是能夠跑起來,還是無法正確加載符號表。
第三種,客戶在在win7,使用 Cygwin 的方式跑gdb客戶端,啟動之后 cygwin 報了一個長度太長的問題,沒有深入去解決
從這里開始,突然對在win7 下啟動 gdb 客戶端有些失望,隨即改為在 ubuntu14.04 里啟動 gdb 客戶端, android 模擬器也在 ubuntu 里啟動。這里的 ubuntu 跑在 win7 上的 vmware 里。具體如果在 ubutnu 里下載並配置 android sdk 開發環境,並創建 avd , 啟動 avd, 可以從網上搜索,最終就是在 ubuntu 里正常啟動一個 android emulator.
然后,就使用下面的方式,就是可以源代碼單步調試了: