NDK官方開發指南翻譯之 NDK_GDB,ndkndk_gdb
這幾天看JNI,沒有基礎,那真是難受……把看到的相關資料記錄一下,也分享給初學者。
‘ndk-gdb’ Overview
重要:如果你要調試線程相關的程式,請閱讀下面的‘Thread Support’部分。
1.用法:
-------------
Android r4引入了一個叫著‘ndk-gdb’的指令碼,能夠非常簡單的為NDK產生的機器碼啟動一個debugsession。
這個指令碼位於NDK的頂層目錄下,它必須從你應用程式的目錄或者子目錄下,用命令列的方式來調用。例如:
cd $PROJECT
$NDK/ndk-gdb
$NDK指向你NDK的安裝路徑。你可以建立一個別名或者把$NDK加入到你的環境變數PATH中,這樣可以避免每次都要輸入完整的路徑名。
重要:本地調試只有在以下所有條件都滿足時才能工作:
1.你的應用程式必須用‘ndk-build’指令碼編譯。
用之前的方式‘make APP=<name>’編譯,NDK是不支援的。
2.你的應用程式必須是可調試的:
換句話說,AndroidManifest.xml的<application>必須設定android:debuggable為true。
3. 你的應用程式必須運行在Android 2.2或者更高的版本中:
ndk-gdb運行在Android 2.2版本之前是不行的。這並不意味著,你的應用程式的目標API必須是2.2+,只是debugging session只能運行在2.2+的裝置或者模擬器上。
非常非常非常重要!!
如果你使用Eclipse ADT外掛程式編譯應用程式,必須確保使用0.9.7或之後的版本。
如果你使用‘ant’編譯工具,必須確保使用的是SDK平台組件的最新版本。下面是最低版本的要求:
Android 1.5 r4
Android1.6 r3
Android2.1 r2
Android2.2 r1
這些都可以通過SDK的更新來獲得。
如果這些條件不滿足,產生的apk將不會包含必要的支援檔案,本地調試將不能工作。
如果發現了問題,‘ndk-gdb’會處理許多錯誤情況和儲存錯誤資訊。例如:
-檢查adb是否在你的path中。
-檢查你的應用程式在manifest中是否聲明了debuggable。
-檢查裝置上已經安裝的具有相同包名的應用程式是否是可調試的。
預設情況下,ndk-gdb會搜尋已經正在啟動並執行應用程式進程,如果沒有找到的話會報錯。但是你可以在啟動debugging session之前,使用--start或--launch=<name>選項來自動啟動activity。
當gdb成功attach到你應用程式的進程中,在session建立後,ndk-gdb會有一個GDB提示:在產生的本地庫中尋找源檔案和symbol/debug versions。
你可以用‘b <location>’設定斷點,用‘c’(continue)繼續執行。更多的命令請查看GDB手冊。
重要:當退出GBD提示,應用程式的調試進程就會停止!這是gdb的一個限制。
重要:當gdb找不到系統庫(如libc.so, libstdc++.so, liblog.so, libcutils.so等)的時候,GDB停止退出前,會列出一長串的錯誤資訊。
這是正常的,因為在你的開發機器上,沒有這些庫的symbol/debug versions來對應你的目標裝置。你可以安全的忽略這些資訊。
2. 選項:
------------
你可以用‘ndk-gdb --help’命令列出這些選項:
--verbose:
列印native debuggingsession啟動時的詳細資料。當你不能串連、ndk-gdb列印的錯誤資訊不夠的時候,才需要它來調試問題。
--force:
預設情況下,如果發現另外一個nativedebugging session運行在同一台裝置上,ndk-gdb會崩潰。使用--force會kill掉那個session,然後啟動一個新的session替換它。注意調試的程式不會被kill,將會再一次stopped。
--start:
預設情況下,ndk-gdb會試圖attach到一個正在啟動並執行應用程式的執行個體上。你可以在debugging sessiong之前,使用--start來顯示的啟動你的應用程式。
注意:這個選項會啟動manifest中第一個launchable的activity,使用--launch=<name>可以啟動其他的activity。--launch-list可以列出所有這樣的activity。
--launch=<name>:
除了可以啟動指定的activity外,其他的和start類似。如果你的manifest定義了很多launchable的activity,這個選項是比較有用的。
--launch-list:
列出manifest中所有launchable的activity。使用--start時,第一個launchable的activity被啟動。
--project=<path>:
指定應用程式的工程所在目錄。如果你不想cd到你工程的目錄中,這個選項是比較有用的。
--port=<port>
預設情況下,ndk-gdb使用本地TCP連接埠5039串連到debugged的應用程式。通過使用不同的連接埠,在同一台開發機器中,可以在不同的裝置/模擬器上運行偵錯工具。
--adb=<file>:
如果不在你的path中,可以指定adb工具的路徑。
-d,-e,-s <serial>
這些標誌和ADB類似,可以處理多台裝置/模擬器串連到你機器上的情況。
-d:串連到一個單獨的物理裝置
-e:串連到一個單獨的類比
-s:串連到<serial>指定的真機或者模擬器,<serial>是用‘adb devices’命令列出的裝置 的名稱。
你也可以定義ADB_SERIAL環境變數來指定你的裝置,不需要使用這個選項。
--exec=<file>:
-x<file>:
串連到調試進程後,會運行在<file>檔案中找到的GDB初始化命令。當你要做一些重複的事情,這是非常有用的。例如建立一序列的斷點,然後自動回復執行。
3.必要條件
---------------------
目前‘ndk-gdb’需要運行在Unix shell上。這意味著在Windows系統中必須運行在Cygwin上。我們希望在以後的NDK版本中能夠擺脫這個限制。
NDK的其他要求:例如 GNU Make3.81或更高版本。
4. 線程支援:
------------------
如果你的應用程式運行在Android 2.3之前,ndk-gdb不能正確的調試本地線程,debug的時候只能把斷點打在主線程中,完全會忽略其他線程的執行。
造成這個問題的最初原因是很複雜的,本質上是在這個平台上不幸有一個bug,而這個是最近才發現的。
運行時,NDK內建的gdbserver二進位檔案有特殊的代碼來檢測這個條件,並且會自動調整它的行為(換句話說,當編譯代碼的時候,你不需要任何的特殊操作)。
這意味著在實踐中:
- 如果你運行在Android 2.3,或者2.3之前的平台但是已經修複了這個bug,你可以自動的調試本地線程。
- 如果不是,你只能在主線程中調試(像前面所說的)。當啟動ndk-gdb(在gdb prompt之前),你會看到下面的資訊:
Thread debugging is unsupported on this Android platform!
如果你在非主線程中執行的函數打了斷點,程式會退出,同時GDB會輸出以下資訊:
Program terminated with signal SIGTRAP, Trace/breakpoint trap.
The program no longer exists.
android怎使用ndk
程式中一些邏輯是用C寫的,使用jni調用C代碼,使用基本的打log的方式很難查看大型數組,瞭解到android ndk sdk中有個工具叫ndk-gdb可以很方便地對c代碼進行調試,使用過程並不順利,遇到兩個錯誤,耗時一周終於解決。如果是在windows下,需要安裝cygwin。首先,在cygwin命令列下進入到你工程的根目錄下如果你要調試的程式已經在運行了,直接運行ndk-gdb如果你要調試的程式沒有運行,可以使用ndk-gdb --start鍵入ndk-gdb命令,會出現一系列庫檔案載入的資訊,這些庫可能會載入失敗,不過沒有關係出現<gdb>提示符,輸入help命令可以查看一系列命令使用l命令列出c檔案的內容,但是遇到 No symbol table is loaded. Use the "file" command.使用以下命令載入需要調試的so檔案:file obj/local/armeabi/libsearch-algorithm.so使用list或者l可以查看載入的c檔案。使用b 100,在c檔案的第100行設定斷點。使用c或者continue命令繼續運行程式。出現錯誤:Continuing.Warning:Cannot insert breakpoint 1.Error accessing memory address 0x11a0: Input/output error.錯誤原因:使用ndk-gdb --start 啟動程式第一個activity,但是此時so檔案並沒有被載入。解決方案:首先開啟程式並使用,在保證so檔案已經被使用的情況下,調用ndk-gdb命令偵錯工具進程。正確流程:1.建立一個模擬器或者使用真機運行想要調試的程式,確保so檔案已經被載入。2.在此程式的根目錄下調用ndk-gdb,出現gdb提示符。3.使用l命令,應該可以列印出c檔案。4.使用b 10,可以在c檔案的第十行列印斷點。5.使用c命令恢複程式運行。
android怎使用ndk
程式中一些邏輯是用C寫的,使用jni調用C代碼,使用基本的打log的方式很難查看大型數組,瞭解到android ndk sdk中有個工具叫ndk-gdb可以很方便地對c代碼進行調試,使用過程並不順利,遇到兩個錯誤,耗時一周終於解決。如果是在windows下,需要安裝cygwin。首先,在cygwin命令列下進入到你工程的根目錄下如果你要調試的程式已經在運行了,直接運行ndk-gdb
如果你要調試的程式沒有運行,可以使用ndk-gdb --start
鍵入ndk-gdb命令,會出現一系列庫檔案載入的資訊,這些庫可能會載入失敗,不過沒有關係
出現<gdb>提示符,輸入help命令可以查看一系列命令使用l命令列出c檔案的內容,但是遇到 No symbol table is loaded. Use the "file" command.使用以下命令載入需要調試的so檔案:
file obj/local/armeabi/libsearch-algorithm.so使用list或者l可以查看載入的c檔案。使用b 100,在c檔案的第100行設定斷點。
使用c或者continue命令繼續運行程式。
出現錯誤:Continuing.
Warning:Cannot insert breakpoint 1.
Error accessing memory address 0x11a0: Input/output error.錯誤原因:使用ndk-gdb --start 啟動程式第一個activity,但是此時so檔案並沒有被載入。
解決方案:首先開啟程式並使用,在保證so檔案已經被使用的情況下,調用ndk-gdb命令偵錯工具進程。
正確流程:
1.建立一個模擬器或者使用真機運行想要調試的程式,確保so檔案已經被載入。
2.在此程式的根目錄下調用ndk-gdb,出現gdb提示符。
3.使用l命令,應該可以列印出c檔案。
4.使用b 10,可以在c檔案的第十行列印斷點。
5.使用c命令恢複程式運行。